2 #include <netif/etharp.h>
4 static envid_t output_envid
;
5 static envid_t input_envid
;
7 static struct jif_pkt
*pkt
= (struct jif_pkt
*)REQVA
;
13 // We need to pre-announce our IP so we don't have to deal
14 // with ARP requests. Ideally, we would use gratuitous ARP
15 // for this, but QEMU's ARP implementation is dumb and only
16 // listens for very specific ARP requests, such as requests
17 // for the gateway IP.
19 uint8_t mac
[6] = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56};
20 uint32_t myip
= inet_addr(IP
);
21 uint32_t gwip
= inet_addr(DEFAULT
);
24 if ((r
= sys_page_alloc(0, pkt
, PTE_P
|PTE_U
|PTE_W
)) < 0)
25 panic("sys_page_map: %e", r
);
27 struct etharp_hdr
*arp
= (struct etharp_hdr
*)pkt
->jp_data
;
28 pkt
->jp_len
= sizeof(*arp
);
30 memset(arp
->ethhdr
.dest
.addr
, 0xff, ETHARP_HWADDR_LEN
);
31 memcpy(arp
->ethhdr
.src
.addr
, mac
, ETHARP_HWADDR_LEN
);
32 arp
->ethhdr
.type
= htons(ETHTYPE_ARP
);
33 arp
->hwtype
= htons(1); // Ethernet
34 arp
->proto
= htons(ETHTYPE_IP
);
35 arp
->_hwlen_protolen
= htons((ETHARP_HWADDR_LEN
<< 8) | 4);
36 arp
->opcode
= htons(ARP_REQUEST
);
37 memcpy(arp
->shwaddr
.addr
, mac
, ETHARP_HWADDR_LEN
);
38 memcpy(arp
->sipaddr
.addrw
, &myip
, 4);
39 memset(arp
->dhwaddr
.addr
, 0x00, ETHARP_HWADDR_LEN
);
40 memcpy(arp
->dipaddr
.addrw
, &gwip
, 4);
42 ipc_send(output_envid
, NSREQ_OUTPUT
, pkt
, PTE_P
|PTE_W
|PTE_U
);
43 sys_page_unmap(0, pkt
);
47 hexdump(const char *prefix
, const void *data
, int len
)
51 char *end
= buf
+ sizeof(buf
);
53 for (i
= 0; i
< len
; i
++) {
55 out
= buf
+ snprintf(buf
, end
- buf
,
56 "%s%04x ", prefix
, i
);
57 out
+= snprintf(out
, end
- out
, "%02x", ((uint8_t*)data
)[i
]);
58 if (i
% 16 == 15 || i
== len
- 1)
59 cprintf("%.*s\n", out
- buf
, buf
);
68 umain(int argc
, char **argv
)
70 envid_t ns_envid
= sys_getenvid();
73 binaryname
= "testinput";
75 output_envid
= fork();
77 panic("error forking");
78 else if (output_envid
== 0) {
85 panic("error forking");
86 else if (input_envid
== 0) {
91 cprintf("Sending ARP announcement...\n");
98 int32_t req
= ipc_recv((int32_t *)&whom
, pkt
, &perm
);
100 panic("ipc_recv: %e", req
);
101 if (whom
!= input_envid
)
102 panic("IPC from unexpected environment %08x", whom
);
103 if (req
!= NSREQ_INPUT
)
104 panic("Unexpected IPC %d", req
);
106 hexdump("input: ", pkt
->jp_data
, pkt
->jp_len
);
109 // Only indicate that we're waiting for packets once
110 // we've received the ARP reply
112 cprintf("Waiting for packets...\n");