00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "lwip/opt.h"
00043
00044 #include "lwip/def.h"
00045 #include "lwip/mem.h"
00046 #include "lwip/ip.h"
00047 #include "lwip/inet.h"
00048 #include "lwip/netif.h"
00049 #include "lwip/icmp.h"
00050 #include "lwip/udp.h"
00051 #include "lwip/tcp.h"
00052
00053 #include "lwip/stats.h"
00054
00055 #include "arch/perf.h"
00056
00057
00058
00059
00060
00061
00062 void
00063 ip_init(void)
00064 {
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074 struct netif *
00075 ip_route(struct ip_addr *dest)
00076 {
00077 struct netif *netif;
00078
00079 for(netif = netif_list; netif != NULL; netif = netif->next) {
00080 if(ip_addr_maskcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
00081 return netif;
00082 }
00083 }
00084
00085 return netif_default;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095 static void
00096 ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
00097 {
00098 struct netif *netif;
00099
00100 PERF_START;
00101
00102 if((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
00103
00104 DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
00105 #if IP_DEBUG
00106 ip_addr_debug_print(&(iphdr->dest));
00107 #endif
00108 DEBUGF(IP_DEBUG, ("\n"));
00109 pbuf_free(p);
00110 return;
00111 }
00112
00113 if(--iphdr->hoplim == 0) {
00114
00115 if(iphdr->nexthdr != IP_PROTO_ICMP) {
00116 icmp_time_exceeded(p, ICMP_TE_TTL);
00117 }
00118 pbuf_free(p);
00119 return;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
00131 #if IP_DEBUG
00132 ip_addr_debug_print(&(iphdr->dest));
00133 #endif
00134 DEBUGF(IP_DEBUG, ("\n"));
00135
00136 #ifdef IP_STATS
00137 ++lwip_stats.ip.fw;
00138 ++lwip_stats.ip.xmit;
00139 #endif
00140
00141 PERF_STOP("ip_forward");
00142
00143 netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 void
00157 ip_input(struct pbuf *p, struct netif *inp) {
00158 struct ip_hdr *iphdr;
00159 struct netif *netif;
00160
00161
00162 PERF_START;
00163
00164 #if IP_DEBUG
00165 ip_debug_print(p);
00166 #endif
00167
00168
00169 #ifdef IP_STATS
00170 ++lwip_stats.ip.recv;
00171 #endif
00172
00173
00174 iphdr = p->payload;
00175
00176
00177 if(iphdr->v != 6) {
00178 DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
00179 #if IP_DEBUG
00180 ip_debug_print(p);
00181 #endif
00182 pbuf_free(p);
00183 #ifdef IP_STATS
00184 ++lwip_stats.ip.err;
00185 ++lwip_stats.ip.drop;
00186 #endif
00187 return;
00188 }
00189
00190
00191 for(netif = netif_list; netif != NULL; netif = netif->next) {
00192 #if IP_DEBUG
00193 DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
00194 ip_addr_debug_print(&(iphdr->dest));
00195 DEBUGF(IP_DEBUG, ("netif->ip_addr "));
00196 ip_addr_debug_print(&(netif->ip_addr));
00197 DEBUGF(IP_DEBUG, ("\n"));
00198 #endif
00199 if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
00200 break;
00201 }
00202 }
00203
00204
00205 if(netif == NULL) {
00206
00207 #ifdef IP_FORWARD
00208 ip_forward(p, iphdr);
00209 #endif
00210 pbuf_free(p);
00211 return;
00212 }
00213
00214 pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
00215
00216
00217 #if IP_DEBUG
00218
00219
00220
00221 #endif
00222
00223
00224 pbuf_header(p, -IP_HLEN);
00225
00226 switch(iphdr->nexthdr) {
00227 case IP_PROTO_UDP:
00228 udp_input(p);
00229 break;
00230 case IP_PROTO_TCP:
00231 tcp_input(p);
00232 break;
00233 case IP_PROTO_ICMP:
00234 icmp_input(p, inp);
00235 break;
00236 default:
00237
00238 icmp_dest_unreach(p, ICMP_DUR_PROTO);
00239 pbuf_free(p);
00240 DEBUGF(IP_DEBUG, ("Unsupported transportation protocol %u\n",
00241 iphdr->nexthdr));
00242
00243 #ifdef IP_STATS
00244 ++lwip_stats.ip.proterr;
00245 ++lwip_stats.ip.drop;
00246 #endif
00247
00248 }
00249 PERF_STOP("ip_input");
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 err_t
00261 ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
00262 u8_t ttl,
00263 u8_t proto, struct netif *netif)
00264 {
00265 struct ip_hdr *iphdr;
00266
00267 PERF_START;
00268
00269 printf("len %u tot_len %u\n", p->len, p->tot_len);
00270 if(pbuf_header(p, IP_HLEN)) {
00271 DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
00272 #ifdef IP_STATS
00273 ++lwip_stats.ip.err;
00274 #endif
00275
00276 return ERR_BUF;
00277 }
00278 printf("len %u tot_len %u\n", p->len, p->tot_len);
00279
00280 iphdr = p->payload;
00281
00282
00283 if(dest != IP_HDRINCL) {
00284 printf("!IP_HDRLINCL\n");
00285 iphdr->hoplim = ttl;
00286 iphdr->nexthdr = proto;
00287 iphdr->len = htons(p->tot_len - IP_HLEN);
00288 ip_addr_set(&(iphdr->dest), dest);
00289
00290 iphdr->v = 6;
00291
00292 if(ip_addr_isany(src)) {
00293 ip_addr_set(&(iphdr->src), &(netif->ip_addr));
00294 } else {
00295 ip_addr_set(&(iphdr->src), src);
00296 }
00297
00298 } else {
00299 dest = &(iphdr->dest);
00300 }
00301
00302 #ifdef IP_STATS
00303 ++lwip_stats.ip.xmit;
00304 #endif
00305
00306 DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %u)\n", netif->name[0], netif->name[1], p->tot_len));
00307 #if IP_DEBUG
00308 ip_debug_print(p);
00309 #endif
00310
00311 PERF_STOP("ip_output_if");
00312 return netif->output(netif, p, dest);
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 err_t
00322 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
00323 u8_t ttl, u8_t proto)
00324 {
00325 struct netif *netif;
00326 if((netif = ip_route(dest)) == NULL) {
00327 DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%lx\n", dest->addr));
00328 #ifdef IP_STATS
00329 ++lwip_stats.ip.rterr;
00330 #endif
00331 return ERR_RTE;
00332 }
00333
00334 return ip_output_if(p, src, dest, ttl, proto, netif);
00335 }
00336
00337 #if IP_DEBUG
00338 void
00339 ip_debug_print(struct pbuf *p)
00340 {
00341 struct ip_hdr *iphdr = p->payload;
00342 char *payload;
00343
00344 payload = (char *)iphdr + IP_HLEN;
00345
00346 DEBUGF(IP_DEBUG, ("IP header:\n"));
00347 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00348 DEBUGF(IP_DEBUG, ("|%2d | %x%x | %x%x | (v, traffic class, flow label)\n",
00349 iphdr->v,
00350 iphdr->tclass1, iphdr->tclass2,
00351 iphdr->flow1, iphdr->flow2));
00352 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00353 DEBUGF(IP_DEBUG, ("| %5u | %2u | %2u | (len, nexthdr, hoplim)\n",
00354 ntohs(iphdr->len),
00355 iphdr->nexthdr,
00356 iphdr->hoplim));
00357 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00358 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
00359 ntohl(iphdr->src.addr[0]) >> 16 & 0xffff,
00360 ntohl(iphdr->src.addr[0]) & 0xffff));
00361 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
00362 ntohl(iphdr->src.addr[1]) >> 16 & 0xffff,
00363 ntohl(iphdr->src.addr[1]) & 0xffff));
00364 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
00365 ntohl(iphdr->src.addr[2]) >> 16 & 0xffff,
00366 ntohl(iphdr->src.addr[2]) & 0xffff));
00367 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (src)\n",
00368 ntohl(iphdr->src.addr[3]) >> 16 & 0xffff,
00369 ntohl(iphdr->src.addr[3]) & 0xffff));
00370 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00371 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
00372 ntohl(iphdr->dest.addr[0]) >> 16 & 0xffff,
00373 ntohl(iphdr->dest.addr[0]) & 0xffff));
00374 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
00375 ntohl(iphdr->dest.addr[1]) >> 16 & 0xffff,
00376 ntohl(iphdr->dest.addr[1]) & 0xffff));
00377 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
00378 ntohl(iphdr->dest.addr[2]) >> 16 & 0xffff,
00379 ntohl(iphdr->dest.addr[2]) & 0xffff));
00380 DEBUGF(IP_DEBUG, ("| %4lx | %4lx | (dest)\n",
00381 ntohl(iphdr->dest.addr[3]) >> 16 & 0xffff,
00382 ntohl(iphdr->dest.addr[3]) & 0xffff));
00383 DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00384 }
00385 #endif
00386