VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/lwip/src/netif/ethernetif.c@ 17797

Last change on this file since 17797 was 17797, checked in by vboxsync, 16 years ago

OSE: export INIP feature for use with iSCSI

  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1/*
2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
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.
15 *
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
25 * OF SUCH DAMAGE.
26 *
27 * This file is part of the lwIP TCP/IP stack.
28 *
29 * Author: Adam Dunkels <[email protected]>
30 *
31 */
32
33/*
34 * This file is a skeleton for developing Ethernet network interface
35 * drivers for lwIP. Add code to the low_level functions and do a
36 * search-and-replace for the word "ethernetif" to replace it with
37 * something that better describes your network interface.
38 */
39
40#include "lwip/opt.h"
41#include "lwip/def.h"
42#include "lwip/mem.h"
43#include "lwip/pbuf.h"
44#include "lwip/sys.h"
45#include <lwip/stats.h>
46
47#include "netif/etharp.h"
48
49/* Define those to better describe your network interface. */
50#define IFNAME0 'e'
51#define IFNAME1 'n'
52
53struct ethernetif {
54 struct eth_addr *ethaddr;
55 /* Add whatever per-interface state that is needed here. */
56};
57
58static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
59
60/* Forward declarations. */
61static void ethernetif_input(struct netif *netif);
62static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
63 struct ip_addr *ipaddr);
64
65static void
66low_level_init(struct netif *netif)
67{
68 struct ethernetif *ethernetif = netif->state;
69
70 /* set MAC hardware address length */
71 netif->hwaddr_len = 6;
72
73 /* set MAC hardware address */
74 netif->hwaddr[0] = ;
75 ...
76 netif->hwaddr[5] = ;
77
78 /* maximum transfer unit */
79 netif->mtu = 1500;
80
81 /* broadcast capability */
82 netif->flags = NETIF_FLAG_BROADCAST;
83
84 /* Do whatever else is needed to initialize interface. */
85}
86
87/*
88 * low_level_output():
89 *
90 * Should do the actual transmission of the packet. The packet is
91 * contained in the pbuf that is passed to the function. This pbuf
92 * might be chained.
93 *
94 */
95
96static err_t
97low_level_output(struct netif *netif, struct pbuf *p)
98{
99 struct ethernetif *ethernetif = netif->state;
100 struct pbuf *q;
101
102 initiate transfer();
103
104#if ETH_PAD_SIZE
105 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
106#endif
107
108 for(q = p; q != NULL; q = q->next) {
109 /* Send the data from the pbuf to the interface, one pbuf at a
110 time. The size of the data in each pbuf is kept in the ->len
111 variable. */
112 send data from(q->payload, q->len);
113 }
114
115 signal that packet should be sent();
116
117#if ETH_PAD_SIZE
118 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
119#endif
120
121#if LINK_STATS
122 lwip_stats.link.xmit++;
123#endif /* LINK_STATS */
124
125 return ERR_OK;
126}
127
128/*
129 * low_level_input():
130 *
131 * Should allocate a pbuf and transfer the bytes of the incoming
132 * packet from the interface into the pbuf.
133 *
134 */
135
136static struct pbuf *
137low_level_input(struct netif *netif)
138{
139 struct ethernetif *ethernetif = netif->state;
140 struct pbuf *p, *q;
141 u16_t len;
142
143 /* Obtain the size of the packet and put it into the "len"
144 variable. */
145 len = ;
146
147#if ETH_PAD_SIZE
148 len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
149#endif
150
151 /* We allocate a pbuf chain of pbufs from the pool. */
152 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
153
154 if (p != NULL) {
155
156#if ETH_PAD_SIZE
157 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
158#endif
159
160 /* We iterate over the pbuf chain until we have read the entire
161 * packet into the pbuf. */
162 for(q = p; q != NULL; q = q->next) {
163 /* Read enough bytes to fill this pbuf in the chain. The
164 * available data in the pbuf is given by the q->len
165 * variable. */
166 read data into(q->payload, q->len);
167 }
168 acknowledge that packet has been read();
169
170#if ETH_PAD_SIZE
171 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
172#endif
173
174#if LINK_STATS
175 lwip_stats.link.recv++;
176#endif /* LINK_STATS */
177 } else {
178 drop packet();
179#if LINK_STATS
180 lwip_stats.link.memerr++;
181 lwip_stats.link.drop++;
182#endif /* LINK_STATS */
183 }
184
185 return p;
186}
187
188/*
189 * ethernetif_output():
190 *
191 * This function is called by the TCP/IP stack when an IP packet
192 * should be sent. It calls the function called low_level_output() to
193 * do the actual transmission of the packet.
194 *
195 */
196
197static err_t
198ethernetif_output(struct netif *netif, struct pbuf *p,
199 struct ip_addr *ipaddr)
200{
201
202 /* resolve hardware address, then send (or queue) packet */
203 return etharp_output(netif, ipaddr, p);
204
205}
206
207/*
208 * ethernetif_input():
209 *
210 * This function should be called when a packet is ready to be read
211 * from the interface. It uses the function low_level_input() that
212 * should handle the actual reception of bytes from the network
213 * interface.
214 *
215 */
216
217static void
218ethernetif_input(struct netif *netif)
219{
220 struct ethernetif *ethernetif;
221 struct eth_hdr *ethhdr;
222 struct pbuf *p;
223
224 ethernetif = netif->state;
225
226 /* move received packet into a new pbuf */
227 p = low_level_input(netif);
228 /* no packet could be read, silently ignore this */
229 if (p == NULL) return;
230 /* points to packet payload, which starts with an Ethernet header */
231 ethhdr = p->payload;
232
233#if LINK_STATS
234 lwip_stats.link.recv++;
235#endif /* LINK_STATS */
236
237 ethhdr = p->payload;
238
239 switch (htons(ethhdr->type)) {
240 /* IP packet? */
241 case ETHTYPE_IP:
242#if 0
243/* CSi disabled ARP table update on ingress IP packets.
244 This seems to work but needs thorough testing. */
245 /* update ARP table */
246 etharp_ip_input(netif, p);
247#endif
248 /* skip Ethernet header */
249 pbuf_header(p, -sizeof(struct eth_hdr));
250 /* pass to network layer */
251 netif->input(p, netif);
252 break;
253
254 case ETHTYPE_ARP:
255 /* pass p to ARP module */
256 etharp_arp_input(netif, ethernetif->ethaddr, p);
257 break;
258 default:
259 pbuf_free(p);
260 p = NULL;
261 break;
262 }
263}
264
265static void
266arp_timer(void *arg)
267{
268 etharp_tmr();
269 sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
270}
271
272/*
273 * ethernetif_init():
274 *
275 * Should be called at the beginning of the program to set up the
276 * network interface. It calls the function low_level_init() to do the
277 * actual setup of the hardware.
278 *
279 */
280
281err_t
282ethernetif_init(struct netif *netif)
283{
284 struct ethernetif *ethernetif;
285
286 ethernetif = mem_malloc(sizeof(struct ethernetif));
287
288 if (ethernetif == NULL)
289 {
290 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
291 return ERR_MEM;
292 }
293
294#if LWIP_SNMP
295 /* ifType ethernetCsmacd(6) @see RFC1213 */
296 netif->link_type = 6;
297 /* your link speed here */
298 netif->link_speed = ;
299 netif->ts = 0;
300 netif->ifinoctets = 0;
301 netif->ifinucastpkts = 0;
302 netif->ifinnucastpkts = 0;
303 netif->ifindiscards = 0;
304 netif->ifoutoctets = 0;
305 netif->ifoutucastpkts = 0;
306 netif->ifoutnucastpkts = 0;
307 netif->ifoutdiscards = 0;
308#endif
309
310 netif->state = ethernetif;
311 netif->name[0] = IFNAME0;
312 netif->name[1] = IFNAME1;
313 netif->output = ethernetif_output;
314 netif->linkoutput = low_level_output;
315
316 ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
317
318 low_level_init(netif);
319
320 etharp_init();
321
322 sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
323
324 return ERR_OK;
325}
326
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette