]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/lwIP_MCF5235_GCC/lwip/src/core/netif.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / lwIP_MCF5235_GCC / lwip / src / core / netif.c
1 /**\r
2  * @file\r
3  *\r
4  * lwIP network interface abstraction\r
5  */\r
6 \r
7 /*\r
8  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.\r
9  * All rights reserved.\r
10  *\r
11  * Redistribution and use in source and binary forms, with or without modification,\r
12  * are permitted provided that the following conditions are met:\r
13  *\r
14  * 1. Redistributions of source code must retain the above copyright notice,\r
15  *    this list of conditions and the following disclaimer.\r
16  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
17  *    this list of conditions and the following disclaimer in the documentation\r
18  *    and/or other materials provided with the distribution.\r
19  * 3. The name of the author may not be used to endorse or promote products\r
20  *    derived from this software without specific prior written permission.\r
21  *\r
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\r
25  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\r
27  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY\r
31  * OF SUCH DAMAGE.\r
32  *\r
33  * This file is part of the lwIP TCP/IP stack.\r
34  *\r
35  * Author: Adam Dunkels <adam@sics.se>\r
36  *\r
37  */\r
38 \r
39 #include "lwip/opt.h"\r
40 \r
41 #include "lwip/def.h"\r
42 #include "lwip/ip_addr.h"\r
43 #include "lwip/netif.h"\r
44 #include "lwip/tcp.h"\r
45 \r
46 struct netif *netif_list = NULL;\r
47 struct netif *netif_default = NULL;\r
48 \r
49 /**\r
50  * Add a network interface to the list of lwIP netifs.\r
51  *\r
52  * @param netif a pre-allocated netif structure\r
53  * @param ipaddr IP address for the new netif\r
54  * @param netmask network mask for the new netif\r
55  * @param gw default gateway IP address for the new netif\r
56  * @param state opaque data passed to the new netif\r
57  * @param init callback function that initializes the interface\r
58  * @param input callback function that is called to pass\r
59  * ingress packets up in the protocol layer stack.\r
60  *\r
61  * @return netif, or NULL if failed.\r
62  */\r
63 struct netif *\r
64 netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,\r
65   struct ip_addr *gw,\r
66   void *state,\r
67   err_t (* init)(struct netif *netif),\r
68   err_t (* input)(struct pbuf *p, struct netif *netif))\r
69 {\r
70   static s16_t netifnum = 0;\r
71   \r
72 #if LWIP_DHCP\r
73   /* netif not under DHCP control by default */\r
74   netif->dhcp = NULL;\r
75 #endif\r
76   /* remember netif specific state information data */\r
77   netif->state = state;\r
78   netif->num = netifnum++;\r
79   netif->input = input;\r
80 \r
81   netif_set_addr(netif, ipaddr, netmask, gw);\r
82 \r
83   /* call user specified initialization function for netif */\r
84   if (init(netif) != ERR_OK) {\r
85     return NULL;\r
86   }\r
87 \r
88   /* add this netif to the list */\r
89   netif->next = netif_list;\r
90   netif_list = netif;\r
91   LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",\r
92     netif->name[0], netif->name[1]));\r
93   ip_addr_debug_print(NETIF_DEBUG, ipaddr);\r
94   LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));\r
95   ip_addr_debug_print(NETIF_DEBUG, netmask);\r
96   LWIP_DEBUGF(NETIF_DEBUG, (" gw "));\r
97   ip_addr_debug_print(NETIF_DEBUG, gw);\r
98   LWIP_DEBUGF(NETIF_DEBUG, ("\n"));\r
99   return netif;\r
100 }\r
101 \r
102 void\r
103 netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask,\r
104     struct ip_addr *gw)\r
105 {\r
106   netif_set_ipaddr(netif, ipaddr);\r
107   netif_set_netmask(netif, netmask);\r
108   netif_set_gw(netif, gw);\r
109 }\r
110 \r
111 void netif_remove(struct netif * netif)\r
112 {\r
113   if ( netif == NULL ) return;\r
114 \r
115   /*  is it the first netif? */\r
116   if (netif_list == netif) {\r
117     netif_list = netif->next;\r
118   }\r
119   else {\r
120     /*  look for netif further down the list */\r
121     struct netif * tmpNetif;\r
122     for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {\r
123       if (tmpNetif->next == netif) {\r
124         tmpNetif->next = netif->next;\r
125         break;\r
126         }\r
127     }\r
128     if (tmpNetif == NULL)\r
129       return; /*  we didn't find any netif today */\r
130   }\r
131   /* this netif is default? */\r
132   if (netif_default == netif)\r
133     /* reset default netif */\r
134     netif_default = NULL;\r
135   LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );\r
136 }\r
137 \r
138 struct netif *\r
139 netif_find(char *name)\r
140 {\r
141   struct netif *netif;\r
142   u8_t num;\r
143 \r
144   if (name == NULL) {\r
145     return NULL;\r
146   }\r
147 \r
148   num = name[2] - '0';\r
149 \r
150   for(netif = netif_list; netif != NULL; netif = netif->next) {\r
151     if (num == netif->num &&\r
152        name[0] == netif->name[0] &&\r
153        name[1] == netif->name[1]) {\r
154       LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1]));\r
155       return netif;\r
156     }\r
157   }\r
158   LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1]));\r
159   return NULL;\r
160 }\r
161 \r
162 void\r
163 netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)\r
164 {\r
165   /* TODO: Handling of obsolete pcbs */\r
166   /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */\r
167 #if LWIP_TCP\r
168   struct tcp_pcb *pcb;\r
169   struct tcp_pcb_listen *lpcb;\r
170 \r
171   /* address is actually being changed? */\r
172   if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)\r
173   {\r
174     /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */\r
175     LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));\r
176     pcb = tcp_active_pcbs;\r
177     while (pcb != NULL) {\r
178       /* PCB bound to current local interface address? */\r
179       if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {\r
180         /* this connection must be aborted */\r
181         struct tcp_pcb *next = pcb->next;\r
182         LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));\r
183         tcp_abort(pcb);\r
184         pcb = next;\r
185       } else {\r
186         pcb = pcb->next;\r
187       }\r
188     }\r
189     for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {\r
190       /* PCB bound to current local interface address? */\r
191       if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {\r
192         /* The PCB is listening to the old ipaddr and\r
193          * is set to listen to the new one instead */\r
194         ip_addr_set(&(lpcb->local_ip), ipaddr);\r
195       }\r
196     }\r
197   }\r
198 #endif\r
199   ip_addr_set(&(netif->ip_addr), ipaddr);\r
200 #if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */\r
201   /** For Ethernet network interfaces, we would like to send a\r
202    *  "gratuitous ARP"; this is an ARP packet sent by a node in order\r
203    *  to spontaneously cause other nodes to update an entry in their\r
204    *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.\r
205    */ \r
206   etharp_query(netif, ipaddr, NULL);\r
207 #endif\r
208   LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",\r
209     netif->name[0], netif->name[1],\r
210     ip4_addr1(&netif->ip_addr),\r
211     ip4_addr2(&netif->ip_addr),\r
212     ip4_addr3(&netif->ip_addr),\r
213     ip4_addr4(&netif->ip_addr)));\r
214 }\r
215 \r
216 void\r
217 netif_set_gw(struct netif *netif, struct ip_addr *gw)\r
218 {\r
219   ip_addr_set(&(netif->gw), gw);\r
220   LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",\r
221     netif->name[0], netif->name[1],\r
222     ip4_addr1(&netif->gw),\r
223     ip4_addr2(&netif->gw),\r
224     ip4_addr3(&netif->gw),\r
225     ip4_addr4(&netif->gw)));\r
226 }\r
227 \r
228 void\r
229 netif_set_netmask(struct netif *netif, struct ip_addr *netmask)\r
230 {\r
231   ip_addr_set(&(netif->netmask), netmask);\r
232   LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",\r
233     netif->name[0], netif->name[1],\r
234     ip4_addr1(&netif->netmask),\r
235     ip4_addr2(&netif->netmask),\r
236     ip4_addr3(&netif->netmask),\r
237     ip4_addr4(&netif->netmask)));\r
238 }\r
239 \r
240 void\r
241 netif_set_default(struct netif *netif)\r
242 {\r
243   netif_default = netif;\r
244   LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",\r
245            netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));\r
246 }\r
247 \r
248 /**\r
249  * Bring an interface up, available for processing\r
250  * traffic.\r
251  * \r
252  * @note: Enabling DHCP on a down interface will make it come\r
253  * up once configured.\r
254  * \r
255  * @see dhcp_start()\r
256  */ \r
257 void netif_set_up(struct netif *netif)\r
258 {\r
259   netif->flags |= NETIF_FLAG_UP;\r
260 }\r
261 \r
262 /**\r
263  * Ask if an interface is up\r
264  */ \r
265 u8_t netif_is_up(struct netif *netif)\r
266 {\r
267   return (netif->flags & NETIF_FLAG_UP)?1:0;\r
268 }\r
269 \r
270 /**\r
271  * Bring an interface down, disabling any traffic processing.\r
272  *\r
273  * @note: Enabling DHCP on a down interface will make it come\r
274  * up once configured.\r
275  * \r
276  * @see dhcp_start()\r
277  */ \r
278 void netif_set_down(struct netif *netif)\r
279 {\r
280   netif->flags &= ~NETIF_FLAG_UP;\r
281 }\r
282 \r
283 void\r
284 netif_init(void)\r
285 {\r
286   netif_list = netif_default = NULL;\r
287 }\r
288 \r