2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
27 * This file is part of the lwIP TCP/IP stack.
29 * Author: Adam Dunkels <adam@sics.se>
41 #include "lwip/pbuf.h"
43 #include <lwip/stats.h>
45 #include <netif/etharp.h>
47 #define PKTMAP 0x10000000
50 struct eth_addr
*ethaddr
;
55 low_level_init(struct netif
*netif
)
59 netif
->hwaddr_len
= 6;
61 netif
->flags
= NETIF_FLAG_BROADCAST
;
63 // MAC address is hardcoded to eliminate a system call
64 netif
->hwaddr
[0] = 0x52;
65 netif
->hwaddr
[1] = 0x54;
66 netif
->hwaddr
[2] = 0x00;
67 netif
->hwaddr
[3] = 0x12;
68 netif
->hwaddr
[4] = 0x34;
69 netif
->hwaddr
[5] = 0x56;
75 * Should do the actual transmission of the packet. The packet is
76 * contained in the pbuf that is passed to the function. This pbuf
81 low_level_output(struct netif
*netif
, struct pbuf
*p
)
83 int r
= sys_page_alloc(0, (void *)PKTMAP
, PTE_U
|PTE_W
|PTE_P
);
85 panic("jif: could not allocate page of memory");
86 struct jif_pkt
*pkt
= (struct jif_pkt
*)PKTMAP
;
91 char *txbuf
= pkt
->jp_data
;
94 for (q
= p
; q
!= NULL
; q
= q
->next
) {
95 /* Send the data from the pbuf to the interface, one pbuf at a
96 time. The size of the data in each pbuf is kept in the ->len
99 if (txsize
+ q
->len
> 2000)
100 panic("oversized packet, fragment %d txsize %d\n", q
->len
, txsize
);
101 memcpy(&txbuf
[txsize
], q
->payload
, q
->len
);
105 pkt
->jp_len
= txsize
;
107 ipc_send(jif
->envid
, NSREQ_OUTPUT
, (void *)pkt
, PTE_P
|PTE_W
|PTE_U
);
108 sys_page_unmap(0, (void *)pkt
);
116 * Should allocate a pbuf and transfer the bytes of the incoming
117 * packet from the interface into the pbuf.
121 low_level_input(void *va
)
123 struct jif_pkt
*pkt
= (struct jif_pkt
*)va
;
124 s16_t len
= pkt
->jp_len
;
126 struct pbuf
*p
= pbuf_alloc(PBUF_RAW
, len
, PBUF_POOL
);
130 /* We iterate over the pbuf chain until we have read the entire
131 * packet into the pbuf. */
132 void *rxbuf
= (void *) pkt
->jp_data
;
135 for (q
= p
; q
!= NULL
; q
= q
->next
) {
136 /* Read enough bytes to fill this pbuf in the chain. The
137 * available data in the pbuf is given by the q->len
140 if (bytes
> (len
- copied
))
141 bytes
= len
- copied
;
142 memcpy(q
->payload
, rxbuf
+ copied
, bytes
);
151 * This function is called by the TCP/IP stack when an IP packet
152 * should be sent. It calls the function called low_level_output() to
153 * do the actual transmission of the packet.
158 jif_output(struct netif
*netif
, struct pbuf
*p
,
159 struct ip_addr
*ipaddr
)
161 /* resolve hardware address, then send (or queue) packet */
162 return etharp_output(netif
, p
, ipaddr
);
168 * This function should be called when a packet is ready to be read
169 * from the interface. It uses the function low_level_input() that
170 * should handle the actual reception of bytes from the network
176 jif_input(struct netif
*netif
, void *va
)
179 struct eth_hdr
*ethhdr
;
184 /* move received packet into a new pbuf */
185 p
= low_level_input(va
);
187 /* no packet could be read, silently ignore this */
188 if (p
== NULL
) return;
189 /* points to packet payload, which starts with an Ethernet header */
192 switch (htons(ethhdr
->type
)) {
194 /* update ARP table */
195 etharp_ip_input(netif
, p
);
196 /* skip Ethernet header */
197 pbuf_header(p
, -(int)sizeof(struct eth_hdr
));
198 /* pass to network layer */
199 netif
->input(p
, netif
);
203 /* pass p to ARP module */
204 etharp_arp_input(netif
, jif
->ethaddr
, p
);
215 * Should be called at the beginning of the program to set up the
216 * network interface. It calls the function low_level_init() to do the
217 * actual setup of the hardware.
222 jif_init(struct netif
*netif
)
225 envid_t
*output_envid
;
227 jif
= mem_malloc(sizeof(struct jif
));
230 LWIP_DEBUGF(NETIF_DEBUG
, ("jif_init: out of memory\n"));
234 output_envid
= (envid_t
*)netif
->state
;
237 netif
->output
= jif_output
;
238 netif
->linkoutput
= low_level_output
;
239 memcpy(&netif
->name
[0], "en", 2);
241 jif
->ethaddr
= (struct eth_addr
*)&(netif
->hwaddr
[0]);
242 jif
->envid
= *output_envid
;
244 low_level_init(netif
);
248 // qemu user-net is dumb; if the host OS does not send and ARP request
249 // first, the qemu will send packets destined for the host using the mac
250 // addr 00:00:00:00:00; do a arp request for the user-net NAT at 10.0.2.2
251 uint32_t ipaddr
= inet_addr("10.0.2.2");
252 etharp_query(netif
, (struct ip_addr
*) &ipaddr
, 0);