Skip to content

Commit a2eb808

Browse files
committed
net: print some debug packet information
1 parent aa22ad2 commit a2eb808

File tree

5 files changed

+224
-24
lines changed

5 files changed

+224
-24
lines changed

include/net/hdr.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#pragma once
2+
3+
#include <netinet/in.h>
4+
#include <sys/cdefs.h>
5+
#include <sys/types.h>
6+
7+
BEGIN_DECLS
8+
9+
struct __PACKED eth_hdr {
10+
struct eth_addr dest;
11+
struct eth_addr src;
12+
uint16_t type;
13+
};
14+
15+
#define ETH_TYPE_ARP 0x0806
16+
#define ETH_TYPE_IP 0x0800
17+
18+
struct __PACKED arp_hdr {
19+
uint16_t hw_type;
20+
uint16_t proto_type;
21+
uint8_t hw_addr_len;
22+
uint8_t proto_addr_len;
23+
uint16_t opcode;
24+
struct eth_addr src_hw_addr;
25+
struct in_addr src_proto_addr;
26+
struct eth_addr dest_hw_addr;
27+
struct in_addr dest_proto_addr;
28+
};
29+
30+
#define ARP_REQUEST 1
31+
#define ARP_REPLY 2
32+
33+
struct __PACKED ip4_hdr {
34+
uint8_t ihl : 4;
35+
uint8_t version : 4;
36+
uint8_t tos;
37+
uint16_t len;
38+
uint16_t id;
39+
uint16_t flags : 3;
40+
uint16_t frag_offset : 13;
41+
uint8_t ttl;
42+
uint8_t protocol;
43+
uint16_t checksum;
44+
struct in_addr src;
45+
struct in_addr dest;
46+
};
47+
48+
#define IP4_PROTOCOL_ICMP 1
49+
#define IP4_PROTOCOL_TCP 6
50+
#define IP4_PROTOCOL_UDP 17
51+
52+
struct __PACKED udp_hdr {
53+
uint16_t src_port;
54+
uint16_t dest_port;
55+
uint16_t length;
56+
uint16_t checksum;
57+
};
58+
59+
struct __PACKED tcp_hdr {
60+
uint16_t src_port;
61+
uint16_t dest_port;
62+
uint32_t seq;
63+
uint32_t ack;
64+
uint8_t data_offset : 4;
65+
uint8_t reserved : 4;
66+
uint8_t flags;
67+
uint16_t window;
68+
uint16_t checksum;
69+
uint16_t urgent;
70+
};
71+
72+
END_DECLS

include/netinet/in.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ BEGIN_DECLS
88
typedef uint16_t in_port_t;
99
typedef uint32_t in_addr_t;
1010

11+
struct in_addr {
12+
in_addr_t s_addr;
13+
};
14+
1115
struct in6_addr {
1216
uint8_t s6_addr[16];
1317
};

kernel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ add_executable(nightingale_kernel
6767
mt/spin.c
6868
mt/sync_testbed.c
6969
mt/thread.c
70+
net/debug.c
7071
syscall.c
7172
tests.c
7273
time.c

kernel/drv/e1000.c

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@
1010

1111
#define PAGE_SIZE 4096
1212

13-
#define TX_RING_SIZE 32
14-
#define RX_RING_SIZE 32
13+
#define TX_DESC_COUNT 80
14+
#define RX_DESC_COUNT 80
1515
#define TX_BUFFER_SIZE 2048
1616
#define RX_BUFFER_SIZE 2048
1717
#define TX_RING_PAGES \
18-
((TX_RING_SIZE * sizeof(struct e1000_tx_desc) + PAGE_SIZE - 1) / PAGE_SIZE)
18+
((TX_DESC_COUNT * sizeof(struct e1000_tx_desc) + PAGE_SIZE - 1) / PAGE_SIZE)
1919
#define RX_RING_PAGES \
20-
((RX_RING_SIZE * sizeof(struct e1000_rx_desc) + PAGE_SIZE - 1) / PAGE_SIZE)
20+
((RX_DESC_COUNT * sizeof(struct e1000_rx_desc) + PAGE_SIZE - 1) / PAGE_SIZE)
2121
#define TX_BUFFER_PAGES \
22-
((TX_RING_SIZE * TX_BUFFER_SIZE + PAGE_SIZE - 1) / PAGE_SIZE)
22+
((TX_DESC_COUNT * TX_BUFFER_SIZE + PAGE_SIZE - 1) / PAGE_SIZE)
2323
#define RX_BUFFER_PAGES \
24-
((TX_RING_SIZE * RX_BUFFER_SIZE + PAGE_SIZE - 1) / PAGE_SIZE)
24+
((TX_DESC_COUNT * RX_BUFFER_SIZE + PAGE_SIZE - 1) / PAGE_SIZE)
2525

2626
#define r32(reg) (*(volatile uint32_t *)(e->mmio_base + reg))
2727
#define w32(reg, val) (*(volatile uint32_t *)(e->mmio_base + reg) = val)
@@ -47,8 +47,8 @@ struct e1000_rx_desc {
4747

4848
static_assert(sizeof(struct e1000_tx_desc) == 16);
4949
static_assert(sizeof(struct e1000_rx_desc) == 16);
50-
static_assert(TX_RING_SIZE * sizeof(struct e1000_tx_desc) % 128 == 0);
51-
static_assert(RX_RING_SIZE * sizeof(struct e1000_rx_desc) % 128 == 0);
50+
static_assert(TX_DESC_COUNT * sizeof(struct e1000_tx_desc) % 128 == 0);
51+
static_assert(RX_DESC_COUNT * sizeof(struct e1000_rx_desc) % 128 == 0);
5252

5353
struct e1000 {
5454
pci_address_t addr;
@@ -78,6 +78,8 @@ enum e1000_reg {
7878
STATUS = 0x00008,
7979
EECD = 0x00010,
8080
EERD = 0x00014,
81+
FCT = 0x00030,
82+
VET = 0x00038,
8183
ICR = 0x000C0,
8284
ITR = 0x000C4,
8385
ICS = 0x000C8,
@@ -198,9 +200,9 @@ static void e1000_enable_interrupts(struct e1000 *e, uint32_t mask) {
198200
w32(IMS, mask);
199201
}
200202

201-
static void e1000_trigger_interrupt(struct e1000 *e, uint32_t mask) {
202-
w32(ICS, mask);
203-
}
203+
// static void e1000_trigger_interrupt(struct e1000 *e, uint32_t mask) {
204+
// w32(ICS, mask);
205+
// }
204206

205207
static uint32_t e1000_read_interrupt_cause(struct e1000 *e) { return r32(ICR); }
206208

@@ -214,15 +216,15 @@ static void e1000_set_link_state(struct e1000 *e) {
214216
static void e1000_enable_rx(struct e1000 *e) {
215217
w32(RDBAL, e->rx_ring_phy);
216218
w32(RDBAH, 0);
217-
w32(RDLEN, RX_RING_SIZE * sizeof(struct e1000_rx_desc));
219+
w32(RDLEN, RX_DESC_COUNT * sizeof(struct e1000_rx_desc));
218220
w32(RDH, 0);
219-
w32(RDT, RX_RING_SIZE - 1);
221+
w32(RDT, RX_DESC_COUNT - 1);
220222

221223
w32(RDTR, 0);
222224
w32(RADV, 0);
223225
w32(RSRPD, 0);
224226

225-
w32(ITR, 1'000'000 / 10'000 * 4);
227+
w32(ITR, 651); // 1'000'000 / 10'000 * 4);
226228
w32(FCRTL, 0);
227229
w32(FCRTH, 0);
228230

@@ -232,7 +234,7 @@ static void e1000_enable_rx(struct e1000 *e) {
232234
static void e1000_enable_tx(struct e1000 *e) {
233235
w32(TDBAL, e->tx_ring_phy);
234236
w32(TDBAH, 0);
235-
w32(TDLEN, TX_RING_SIZE * sizeof(struct e1000_tx_desc));
237+
w32(TDLEN, TX_DESC_COUNT * sizeof(struct e1000_tx_desc));
236238
w32(TDH, 0);
237239
w32(TDT, 0);
238240

@@ -259,7 +261,7 @@ static void e1000_send(struct e1000 *e, void *data, size_t len) {
259261
desc->length = len;
260262
desc->cmd = CMD_EOP | CMD_IFCS | CMD_RS | CMD_RPS;
261263
desc->status = 0;
262-
tail = (tail + 1) % TX_RING_SIZE;
264+
tail = (tail + 1) % TX_DESC_COUNT;
263265

264266
printf("e1000: sending %zu bytes, tail is now %u\n", len, tail);
265267

@@ -277,11 +279,16 @@ static void e1000_receive(struct e1000 *e) {
277279
if (!(desc->status & 1))
278280
break;
279281

282+
void *data = e->rx_buffer + e->rx * RX_BUFFER_SIZE;
283+
280284
printf("e1000: received %u bytes\n", desc->length);
281-
hexdump(e->rx_buffer + e->rx * RX_BUFFER_SIZE, desc->length, 0);
285+
hexdump(data, desc->length, 0);
286+
287+
void net_debug(int, void *, size_t);
288+
net_debug(0, data, desc->length);
282289

283290
desc->status = 0;
284-
e->rx = (e->rx + 1) % RX_RING_SIZE;
291+
e->rx = (e->rx + 1) % RX_DESC_COUNT;
285292
w32(RDT, e->rx);
286293
}
287294
}
@@ -307,6 +314,11 @@ static void e1000_init(struct e1000 *e) {
307314
e1000_set_rx_mac(e);
308315
e1000_read_irq(e);
309316

317+
// 13.4.10, "this register should be programmed with 88_08h"
318+
w32(FCT, 0x8808);
319+
// 13.4.11, "this register should be programmed with 8100h"
320+
w32(VET, 0x8100);
321+
310322
e->tx_ring_phy = pm_alloc_contiguous(TX_RING_PAGES);
311323
e->tx_descs = (struct e1000_tx_desc *)(e->tx_ring_phy | limine_hhdm());
312324
e->rx_ring_phy = pm_alloc_contiguous(RX_RING_PAGES);
@@ -316,19 +328,19 @@ static void e1000_init(struct e1000 *e) {
316328
e->rx_buffer_phy = pm_alloc_contiguous(RX_BUFFER_PAGES);
317329
e->rx_buffer = (void *)(e->rx_buffer_phy | limine_hhdm());
318330

319-
memset(e->tx_descs, 0, TX_RING_SIZE * sizeof(struct e1000_tx_desc));
320-
memset(e->rx_descs, 0, RX_RING_SIZE * sizeof(struct e1000_rx_desc));
321-
memset(e->tx_buffer, 0, TX_RING_SIZE * TX_BUFFER_SIZE);
322-
memset(e->rx_buffer, 0, RX_RING_SIZE * RX_BUFFER_SIZE);
331+
memset(e->tx_descs, 0, TX_DESC_COUNT * sizeof(struct e1000_tx_desc));
332+
memset(e->rx_descs, 0, RX_DESC_COUNT * sizeof(struct e1000_rx_desc));
333+
memset(e->tx_buffer, 0, TX_DESC_COUNT * TX_BUFFER_SIZE);
334+
memset(e->rx_buffer, 0, RX_DESC_COUNT * RX_BUFFER_SIZE);
323335

324336
// Initialize rx ring
325-
for (int i = 0; i < RX_RING_SIZE; i++) {
337+
for (int i = 0; i < RX_DESC_COUNT; i++) {
326338
e->rx_descs[i].addr = e->rx_buffer_phy + i * RX_BUFFER_SIZE;
327339
e->rx_descs[i].status = 0;
328340
}
329341

330342
// Initialize tx ring
331-
for (int i = 0; i < TX_RING_SIZE; i++) {
343+
for (int i = 0; i < TX_DESC_COUNT; i++) {
332344
e->tx_descs[i].addr = e->tx_buffer_phy + i * TX_BUFFER_SIZE;
333345
e->tx_descs[i].status = 0;
334346
}
@@ -378,6 +390,11 @@ void e1000_test(pci_address_t addr) {
378390
0x56, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
379391
0x52, 0x54, 0x00, 0x12, 0x34, 0x56, 0x0a, 0x00, 0x02, 0x0f, 0x00,
380392
0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x02 };
393+
printf("sending frame:\n");
394+
395+
void net_debug(int, void *, size_t);
396+
net_debug(0, ethernet_frame, sizeof(ethernet_frame));
397+
381398
e1000_send(e, ethernet_frame, sizeof(ethernet_frame));
382399

383400
printf("%i -> %i\n", r32(TDH), r32(TDT));

kernel/net/debug.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#include <arpa/inet.h>
2+
#include <net/hdr.h>
3+
#include <ng/debug.h>
4+
#include <stdio.h>
5+
6+
enum layer_type {
7+
ETHERNET,
8+
IPV4,
9+
ARP,
10+
UDP,
11+
TCP,
12+
};
13+
14+
void print_eth_addr(struct eth_addr *addr) {
15+
printf("%02x:%02x:%02x:%02x:%02x:%02x",
16+
addr->addr[0], addr->addr[1], addr->addr[2],
17+
addr->addr[3], addr->addr[4], addr->addr[5]);
18+
}
19+
20+
void print_ip4_addr(struct in_addr *addr) {
21+
for (int i = 0; i < 4; i++) {
22+
printf("%d", addr->s_addr >> (i * 8) & 0xff);
23+
if (i < 3) {
24+
printf(".");
25+
}
26+
}
27+
}
28+
29+
void net_debug(enum layer_type type, void *data, size_t len) {
30+
printf(" ");
31+
switch (type) {
32+
case ETHERNET: {
33+
struct eth_hdr *hdr = data;
34+
printf("Ethernet: ");
35+
print_eth_addr(&hdr->src);
36+
printf(" -> ");
37+
print_eth_addr(&hdr->dest);
38+
printf("\n");
39+
switch (ntohs(hdr->type)) {
40+
case ETH_TYPE_ARP:
41+
net_debug(ARP, hdr + 1, len - sizeof(*hdr));
42+
break;
43+
case ETH_TYPE_IP:
44+
net_debug(IPV4, hdr + 1, len - sizeof(*hdr));
45+
break;
46+
default:
47+
printf("Unknown Ethernet type: %04x\n", ntohs(hdr->type));
48+
}
49+
break;
50+
}
51+
case IPV4: {
52+
struct ip4_hdr *hdr = data;
53+
printf("IPv4: ");
54+
print_ip4_addr(&hdr->src);
55+
printf(" -> ");
56+
print_ip4_addr(&hdr->dest);
57+
printf("\n");
58+
switch (hdr->protocol) {
59+
case IPPROTO_UDP:
60+
net_debug(UDP, hdr + 1, len - sizeof(*hdr));
61+
break;
62+
case IPPROTO_TCP:
63+
net_debug(TCP, hdr + 1, len - sizeof(*hdr));
64+
break;
65+
default:
66+
printf("Unknown IPv4 protocol: %02x\n", hdr->protocol);
67+
}
68+
}
69+
case ARP: {
70+
struct arp_hdr *hdr = data;
71+
printf("ARP: ");
72+
switch (ntohs(hdr->opcode)) {
73+
case ARP_REQUEST:
74+
printf("Who is ");
75+
print_ip4_addr(&hdr->dest_proto_addr);
76+
printf("? Tell ");
77+
print_ip4_addr(&hdr->src_proto_addr);
78+
printf("\n");
79+
break;
80+
case ARP_REPLY:
81+
print_ip4_addr(&hdr->src_proto_addr);
82+
printf(" is at ");
83+
print_eth_addr(&hdr->src_hw_addr);
84+
printf("\n");
85+
break;
86+
default:
87+
printf("Unknown ARP opcode: %04x\n", ntohs(hdr->opcode));
88+
}
89+
break;
90+
}
91+
case UDP: {
92+
struct udp_hdr *hdr = data;
93+
printf("UDP: %d -> %d\n", ntohs(hdr->src_port), ntohs(hdr->dest_port));
94+
hexdump(hdr + 1, len - sizeof(*hdr), 0);
95+
break;
96+
}
97+
case TCP: {
98+
struct tcp_hdr *hdr = data;
99+
printf("TCP: %d -> %d\n", ntohs(hdr->src_port), ntohs(hdr->dest_port));
100+
hexdump(hdr + 1, len - sizeof(*hdr), 0);
101+
break;
102+
}
103+
default:
104+
printf("Unknown layer type: %d\n", type);
105+
}
106+
}

0 commit comments

Comments
 (0)