2 * Copyright (c) 2001-2003 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>
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.
39 * THIS CODE NEEDS TO BE FIXED - IT IS NOT In SYNC WITH CURRENT ETHARP API
42 #include "lwip/debug.h"
47 #include "lwip/pbuf.h"
50 #include "netif/arp.h"
52 /* Define those to better describe your network interface. */
57 struct eth_addr *ethaddr;
58 /* Add whatever per-interface state that is needed here. */
61 static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
63 /* Forward declarations. */
64 static void ethernetif_input(struct netif *netif);
65 static err_t ethernetif_output(struct netif *netif, struct pbuf *p,
66 struct ip_addr *ipaddr);
68 /*-----------------------------------------------------------------------------------*/
70 low_level_init(struct netif *netif)
72 struct ethernetif *ethernetif;
74 ethernetif = netif->state;
76 /* Obtain MAC address from network interface. */
77 ethernetif->ethaddr->addr[0] = ;
78 ethernetif->ethaddr->addr[1] = ;
79 ethernetif->ethaddr->addr[2] = ;
81 /* Do whatever else is needed to initialize interface. */
83 /*-----------------------------------------------------------------------------------*/
87 * Should do the actual transmission of the packet. The packet is
88 * contained in the pbuf that is passed to the function. This pbuf
92 /*-----------------------------------------------------------------------------------*/
95 low_level_output(struct ethernetif *ethernetif, struct pbuf *p)
101 for(q = p; q != NULL; q = q->next) {
102 /* Send the data from the pbuf to the interface, one pbuf at a
103 time. The size of the data in each pbuf is kept in the ->len
105 send data from(q->payload, q->len);
108 signal that packet should be sent();
111 lwip_stats.link.xmit++;
112 #endif /* LINK_STATS */
116 /*-----------------------------------------------------------------------------------*/
120 * Should allocate a pbuf and transfer the bytes of the incoming
121 * packet from the interface into the pbuf.
124 /*-----------------------------------------------------------------------------------*/
126 low_level_input(struct ethernetif *ethernetif)
131 /* Obtain the size of the packet and put it into the "len"
135 /* We allocate a pbuf chain of pbufs from the pool. */
136 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
139 /* We iterate over the pbuf chain until we have read the entire
140 packet into the pbuf. */
141 for(q = p; q != NULL; q = q->next) {
142 /* Read enough bytes to fill this pbuf in the chain. The
143 available data in the pbuf is given by the q->len
145 read data into(q->payload, q->len);
147 acknowledge that packet has been read();
149 lwip_stats.link.recv++;
150 #endif /* LINK_STATS */
154 lwip_stats.link.memerr++;
155 lwip_stats.link.drop++;
156 #endif /* LINK_STATS */
161 /*-----------------------------------------------------------------------------------*/
163 * ethernetif_output():
165 * This function is called by the TCP/IP stack when an IP packet
166 * should be sent. It calls the function called low_level_output() to
167 * do the actuall transmission of the packet.
170 /*-----------------------------------------------------------------------------------*/
172 ethernetif_output(struct netif *netif, struct pbuf *p,
173 struct ip_addr *ipaddr)
175 struct ethernetif *ethernetif;
177 struct eth_hdr *ethhdr;
178 struct eth_addr *dest, mcastaddr;
179 struct ip_addr *queryaddr;
183 ethernetif = netif->state;
185 /* Make room for Ethernet header. */
186 if(pbuf_header(p, 14) != 0) {
187 /* The pbuf_header() call shouldn't fail, but we allocate an extra
188 pbuf just in case. */
189 q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM);
192 lwip_stats.link.drop++;
193 lwip_stats.link.memerr++;
194 #endif /* LINK_STATS */
201 /* Construct Ethernet header. Start with looking up deciding which
202 MAC address to use as a destination address. Broadcasts and
203 multicasts are special, all other addresses are looked up in the
206 if(ip_addr_isany(ipaddr) ||
207 ip_addr_isbroadcast(ipaddr, &(netif->netmask))) {
208 dest = (struct eth_addr *)ðbroadcast;
209 } else if(ip_addr_ismulticast(ipaddr)) {
210 /* Hash IP multicast address to MAC address. */
211 mcastaddr.addr[0] = 0x01;
212 mcastaddr.addr[1] = 0x0;
213 mcastaddr.addr[2] = 0x5e;
214 mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
215 mcastaddr.addr[4] = ip4_addr3(ipaddr);
216 mcastaddr.addr[5] = ip4_addr4(ipaddr);
220 if(ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
221 /* Use destination IP address if the destination is on the same
225 /* Otherwise we use the default router as the address to send
226 the Ethernet frame to. */
227 queryaddr = &(netif->gw);
229 dest = arp_lookup(queryaddr);
233 /* If the arp_lookup() didn't find an address, we send out an ARP
234 query for the IP address. */
236 q = arp_query(netif, ethernetif->ethaddr, queryaddr);
238 err = low_level_output(ethernetif, q);
243 lwip_stats.link.drop++;
244 lwip_stats.link.memerr++;
245 #endif /* LINK_STATS */
250 for(i = 0; i < 6; i++) {
251 ethhdr->dest.addr[i] = dest->addr[i];
252 ethhdr->src.addr[i] = ethernetif->ethaddr->addr[i];
255 ethhdr->type = htons(ETHTYPE_IP);
257 return low_level_output(ethernetif, p);
260 /*-----------------------------------------------------------------------------------*/
262 * ethernetif_input():
264 * This function should be called when a packet is ready to be read
265 * from the interface. It uses the function low_level_input() that
266 * should handle the actual reception of bytes from the network
270 /*-----------------------------------------------------------------------------------*/
272 ethernetif_input(struct netif *netif)
274 struct ethernetif *ethernetif;
275 struct eth_hdr *ethhdr;
279 ethernetif = netif->state;
281 p = low_level_input(ethernetif);
286 lwip_stats.link.recv++;
287 #endif /* LINK_STATS */
291 switch(htons(ethhdr->type)) {
293 arp_ip_input(netif, p);
295 netif->input(p, netif);
298 p = arp_arp_input(netif, ethernetif->ethaddr, p);
300 low_level_output(ethernetif, p);
310 /*-----------------------------------------------------------------------------------*/
315 sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
317 /*-----------------------------------------------------------------------------------*/
321 * Should be called at the beginning of the program to set up the
322 * network interface. It calls the function low_level_init() to do the
323 * actual setup of the hardware.
326 /*-----------------------------------------------------------------------------------*/
328 ethernetif_init(struct netif *netif)
330 struct ethernetif *ethernetif;
332 ethernetif = mem_malloc(sizeof(struct ethernetif));
333 netif->state = ethernetif;
334 netif->name[0] = IFNAME0;
335 netif->name[1] = IFNAME1;
336 netif->output = ethernetif_output;
337 netif->linkoutput = low_level_output;
339 ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
341 low_level_init(netif);
344 sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
346 /*-----------------------------------------------------------------------------------*/