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 #include "lwip/opt.h"
00042 #include "lwip/ip.h"
00043 #include "lwip/def.h"
00044 #include "lwip/mem.h"
00045 #include "lwip/ip_frag.h"
00046 #include "lwip/inet_chksum.h"
00047 #include "lwip/netif.h"
00048 #include "lwip/icmp.h"
00049 #include "lwip/igmp.h"
00050 #include "lwip/raw.h"
00051 #include "lwip/udp.h"
00052 #include "lwip/tcp_impl.h"
00053 #include "lwip/snmp.h"
00054 #include "lwip/dhcp.h"
00055 #include "lwip/autoip.h"
00056 #include "lwip/stats.h"
00057 #include "arch/perf.h"
00058
00059 #include <string.h>
00060
00061
00062
00063 #ifndef LWIP_INLINE_IP_CHKSUM
00064 #define LWIP_INLINE_IP_CHKSUM 1
00065 #endif
00066 #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
00067 #define CHECKSUM_GEN_IP_INLINE 1
00068 #else
00069 #define CHECKSUM_GEN_IP_INLINE 0
00070 #endif
00071
00072 #if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
00073 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 1
00074
00075
00076
00077
00078
00079
00080 #if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
00081
00082 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \
00083 || (LWIP_IP_ACCEPT_UDP_PORT(port)))
00084 #elif defined(LWIP_IP_ACCEPT_UDP_PORT)
00085
00086 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port))
00087 #else
00088
00089 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT))
00090 #endif
00091
00092 #else
00093 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 0
00094 #endif
00095
00096
00097
00098
00099
00100 struct netif *current_netif;
00101
00102
00103
00104
00105 const struct ip_hdr *current_header;
00106
00107 ip_addr_t current_iphdr_src;
00108
00109 ip_addr_t current_iphdr_dest;
00110
00111
00112 static u16_t ip_id;
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 struct netif *
00124 ip_route(ip_addr_t *dest)
00125 {
00126 struct netif *netif;
00127
00128 #ifdef LWIP_HOOK_IP4_ROUTE
00129 netif = LWIP_HOOK_IP4_ROUTE(dest);
00130 if (netif != NULL) {
00131 return netif;
00132 }
00133 #endif
00134
00135
00136 for (netif = netif_list; netif != NULL; netif = netif->next) {
00137
00138 if (netif_is_up(netif)) {
00139 if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
00140
00141 return netif;
00142 }
00143 }
00144 }
00145 if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
00146 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00147 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
00148 IP_STATS_INC(ip.rterr);
00149 snmp_inc_ipoutnoroutes();
00150 return NULL;
00151 }
00152
00153 return netif_default;
00154 }
00155
00156 #if IP_FORWARD
00157
00158
00159
00160
00161
00162
00163
00164
00165 static int
00166 ip_canforward(struct pbuf *p)
00167 {
00168 u32_t addr = ip4_addr_get_u32(ip_current_dest_addr());
00169
00170 if (p->flags & PBUF_FLAG_LLBCAST) {
00171
00172 return 0;
00173 }
00174 if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) {
00175
00176
00177 return 0;
00178 }
00179 if (IP_EXPERIMENTAL(addr)) {
00180 return 0;
00181 }
00182 if (IP_CLASSA(addr)) {
00183 u32_t net = addr & IP_CLASSA_NET;
00184 if ((net == 0) || (net == (IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) {
00185
00186 return 0;
00187 }
00188 }
00189 return 1;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 static void
00202 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
00203 {
00204 struct netif *netif;
00205
00206 PERF_START;
00207
00208 if (!ip_canforward(p)) {
00209 goto return_noroute;
00210 }
00211
00212
00213 if (ip_addr_islinklocal(¤t_iphdr_dest)) {
00214 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00215 ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
00216 ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
00217 goto return_noroute;
00218 }
00219
00220
00221 netif = ip_route(¤t_iphdr_dest);
00222 if (netif == NULL) {
00223 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
00224 ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
00225 ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
00226
00227 goto return_noroute;
00228 }
00229 #if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF
00230
00231
00232 if (netif == inp) {
00233 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
00234 goto return_noroute;
00235 }
00236 #endif
00237
00238
00239 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
00240
00241 if (IPH_TTL(iphdr) == 0) {
00242 snmp_inc_ipinhdrerrors();
00243 #if LWIP_ICMP
00244
00245 if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
00246 icmp_time_exceeded(p, ICMP_TE_TTL);
00247 }
00248 #endif
00249 return;
00250 }
00251
00252
00253 if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
00254 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
00255 } else {
00256 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
00257 }
00258
00259 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00260 ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest),
00261 ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest)));
00262
00263 IP_STATS_INC(ip.fw);
00264 IP_STATS_INC(ip.xmit);
00265 snmp_inc_ipforwdatagrams();
00266
00267 PERF_STOP("ip_forward");
00268
00269 if (netif->mtu && (p->tot_len > netif->mtu)) {
00270 if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
00271 #if IP_FRAG
00272 ip_frag(p, netif, ip_current_dest_addr());
00273 #else
00274
00275 #endif
00276 } else {
00277
00278 icmp_dest_unreach(p, ICMP_DUR_FRAG);
00279 }
00280 return;
00281 }
00282
00283 netif->output(netif, p, ¤t_iphdr_dest);
00284 return;
00285 return_noroute:
00286 snmp_inc_ipoutnoroutes();
00287 }
00288 #endif
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 err_t
00305 ip_input(struct pbuf *p, struct netif *inp)
00306 {
00307 struct ip_hdr *iphdr;
00308 struct netif *netif;
00309 u16_t iphdr_hlen;
00310 u16_t iphdr_len;
00311 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
00312 int check_ip_src=1;
00313 #endif
00314
00315 IP_STATS_INC(ip.recv);
00316 snmp_inc_ipinreceives();
00317
00318
00319 iphdr = (struct ip_hdr *)p->payload;
00320 if (IPH_V(iphdr) != 4) {
00321 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
00322 ip_debug_print(p);
00323 pbuf_free(p);
00324 IP_STATS_INC(ip.err);
00325 IP_STATS_INC(ip.drop);
00326 snmp_inc_ipinhdrerrors();
00327 return ERR_OK;
00328 }
00329
00330 #ifdef LWIP_HOOK_IP4_INPUT
00331 if (LWIP_HOOK_IP4_INPUT(p, inp)) {
00332
00333 return ERR_OK;
00334 }
00335 #endif
00336
00337
00338 iphdr_hlen = IPH_HL(iphdr);
00339
00340 iphdr_hlen *= 4;
00341
00342 iphdr_len = ntohs(IPH_LEN(iphdr));
00343
00344
00345 if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
00346 if (iphdr_hlen > p->len) {
00347 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
00348 ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
00349 iphdr_hlen, p->len));
00350 }
00351 if (iphdr_len > p->tot_len) {
00352 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
00353 ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
00354 iphdr_len, p->tot_len));
00355 }
00356
00357 pbuf_free(p);
00358 IP_STATS_INC(ip.lenerr);
00359 IP_STATS_INC(ip.drop);
00360 snmp_inc_ipindiscards();
00361 return ERR_OK;
00362 }
00363
00364
00365 #if CHECKSUM_CHECK_IP
00366 if (inet_chksum(iphdr, iphdr_hlen) != 0) {
00367
00368 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
00369 ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
00370 ip_debug_print(p);
00371 pbuf_free(p);
00372 IP_STATS_INC(ip.chkerr);
00373 IP_STATS_INC(ip.drop);
00374 snmp_inc_ipinhdrerrors();
00375 return ERR_OK;
00376 }
00377 #endif
00378
00379
00380
00381 pbuf_realloc(p, iphdr_len);
00382
00383
00384 ip_addr_copy(current_iphdr_dest, iphdr->dest);
00385 ip_addr_copy(current_iphdr_src, iphdr->src);
00386
00387
00388 #if LWIP_IGMP
00389 if (ip_addr_ismulticast(¤t_iphdr_dest)) {
00390 if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ¤t_iphdr_dest))) {
00391 netif = inp;
00392 } else {
00393 netif = NULL;
00394 }
00395 } else
00396 #endif
00397 {
00398
00399
00400
00401 int first = 1;
00402 netif = inp;
00403 do {
00404 LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
00405 ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr),
00406 ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask),
00407 ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask),
00408 ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask)));
00409
00410
00411 if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
00412
00413 if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) ||
00414
00415 ip_addr_isbroadcast(¤t_iphdr_dest, netif)) {
00416 LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
00417 netif->name[0], netif->name[1]));
00418
00419 break;
00420 }
00421 #if LWIP_AUTOIP
00422
00423
00424 if ((netif->autoip != NULL) &&
00425 ip_addr_cmp(¤t_iphdr_dest, &(netif->autoip->llipaddr))) {
00426 LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n",
00427 netif->name[0], netif->name[1]));
00428
00429 break;
00430 }
00431 #endif
00432 }
00433 if (first) {
00434 first = 0;
00435 netif = netif_list;
00436 } else {
00437 netif = netif->next;
00438 }
00439 if (netif == inp) {
00440 netif = netif->next;
00441 }
00442 } while(netif != NULL);
00443 }
00444
00445 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 if (netif == NULL) {
00456
00457 if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
00458 struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
00459 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
00460 ntohs(udphdr->dest)));
00461 if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
00462 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n"));
00463 netif = inp;
00464 check_ip_src = 0;
00465 }
00466 }
00467 }
00468 #endif
00469
00470
00471 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
00472
00473 if (check_ip_src && !ip_addr_isany(¤t_iphdr_src))
00474 #endif
00475 { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) ||
00476 (ip_addr_ismulticast(¤t_iphdr_src))) {
00477
00478 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
00479
00480 pbuf_free(p);
00481 IP_STATS_INC(ip.drop);
00482 snmp_inc_ipinaddrerrors();
00483 snmp_inc_ipindiscards();
00484 return ERR_OK;
00485 }
00486 }
00487
00488
00489 if (netif == NULL) {
00490
00491 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
00492 #if IP_FORWARD
00493
00494 if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp)) {
00495
00496 ip_forward(p, iphdr, inp);
00497 } else
00498 #endif
00499 {
00500 snmp_inc_ipinaddrerrors();
00501 snmp_inc_ipindiscards();
00502 }
00503 pbuf_free(p);
00504 return ERR_OK;
00505 }
00506
00507 if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
00508 #if IP_REASSEMBLY
00509 LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",
00510 ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
00511
00512 p = ip_reass(p);
00513
00514 if (p == NULL) {
00515 return ERR_OK;
00516 }
00517 iphdr = (struct ip_hdr *)p->payload;
00518 #else
00519 pbuf_free(p);
00520 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
00521 ntohs(IPH_OFFSET(iphdr))));
00522 IP_STATS_INC(ip.opterr);
00523 IP_STATS_INC(ip.drop);
00524
00525 snmp_inc_ipinunknownprotos();
00526 return ERR_OK;
00527 #endif
00528 }
00529
00530 #if IP_OPTIONS_ALLOWED == 0
00531
00532 #if LWIP_IGMP
00533
00534 if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
00535 #else
00536 if (iphdr_hlen > IP_HLEN) {
00537 #endif
00538 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
00539 pbuf_free(p);
00540 IP_STATS_INC(ip.opterr);
00541 IP_STATS_INC(ip.drop);
00542
00543 snmp_inc_ipinunknownprotos();
00544 return ERR_OK;
00545 }
00546 #endif
00547
00548
00549 LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
00550 ip_debug_print(p);
00551 LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
00552
00553 current_netif = inp;
00554 current_header = iphdr;
00555
00556 #if LWIP_RAW
00557
00558 if (raw_input(p, inp) == 0)
00559 #endif
00560 {
00561 switch (IPH_PROTO(iphdr)) {
00562 #if LWIP_UDP
00563 case IP_PROTO_UDP:
00564 #if LWIP_UDPLITE
00565 case IP_PROTO_UDPLITE:
00566 #endif
00567 snmp_inc_ipindelivers();
00568 udp_input(p, inp);
00569 break;
00570 #endif
00571 #if LWIP_TCP
00572 case IP_PROTO_TCP:
00573 snmp_inc_ipindelivers();
00574 tcp_input(p, inp);
00575 break;
00576 #endif
00577 #if LWIP_ICMP
00578 case IP_PROTO_ICMP:
00579 snmp_inc_ipindelivers();
00580 icmp_input(p, inp);
00581 break;
00582 #endif
00583 #if LWIP_IGMP
00584 case IP_PROTO_IGMP:
00585 igmp_input(p, inp, ¤t_iphdr_dest);
00586 break;
00587 #endif
00588 default:
00589 #if LWIP_ICMP
00590
00591 if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) &&
00592 !ip_addr_ismulticast(¤t_iphdr_dest)) {
00593 p->payload = iphdr;
00594 icmp_dest_unreach(p, ICMP_DUR_PROTO);
00595 }
00596 #endif
00597 pbuf_free(p);
00598
00599 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
00600
00601 IP_STATS_INC(ip.proterr);
00602 IP_STATS_INC(ip.drop);
00603 snmp_inc_ipinunknownprotos();
00604 }
00605 }
00606
00607 current_netif = NULL;
00608 current_header = NULL;
00609 ip_addr_set_any(¤t_iphdr_src);
00610 ip_addr_set_any(¤t_iphdr_dest);
00611
00612 return ERR_OK;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 err_t
00641 ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
00642 u8_t ttl, u8_t tos,
00643 u8_t proto, struct netif *netif)
00644 {
00645 #if IP_OPTIONS_SEND
00646 return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
00647 }
00648
00649
00650
00651
00652
00653
00654
00655 err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
00656 u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
00657 u16_t optlen)
00658 {
00659 #endif
00660 struct ip_hdr *iphdr;
00661 ip_addr_t dest_addr;
00662 #if CHECKSUM_GEN_IP_INLINE
00663 u32_t chk_sum = 0;
00664 #endif
00665
00666
00667
00668 LWIP_ASSERT("p->ref == 1", p->ref == 1);
00669
00670 snmp_inc_ipoutrequests();
00671
00672
00673 if (dest != IP_HDRINCL) {
00674 u16_t ip_hlen = IP_HLEN;
00675 #if IP_OPTIONS_SEND
00676 u16_t optlen_aligned = 0;
00677 if (optlen != 0) {
00678 #if CHECKSUM_GEN_IP_INLINE
00679 int i;
00680 #endif
00681
00682 optlen_aligned = ((optlen + 3) & ~3);
00683 ip_hlen += optlen_aligned;
00684
00685 if (pbuf_header(p, optlen_aligned)) {
00686 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
00687 IP_STATS_INC(ip.err);
00688 snmp_inc_ipoutdiscards();
00689 return ERR_BUF;
00690 }
00691 MEMCPY(p->payload, ip_options, optlen);
00692 if (optlen < optlen_aligned) {
00693
00694 memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
00695 }
00696 #if CHECKSUM_GEN_IP_INLINE
00697 for (i = 0; i < optlen_aligned/2; i++) {
00698 chk_sum += ((u16_t*)p->payload)[i];
00699 }
00700 #endif
00701 }
00702 #endif
00703
00704 if (pbuf_header(p, IP_HLEN)) {
00705 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n"));
00706
00707 IP_STATS_INC(ip.err);
00708 snmp_inc_ipoutdiscards();
00709 return ERR_BUF;
00710 }
00711
00712 iphdr = (struct ip_hdr *)p->payload;
00713 LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
00714 (p->len >= sizeof(struct ip_hdr)));
00715
00716 IPH_TTL_SET(iphdr, ttl);
00717 IPH_PROTO_SET(iphdr, proto);
00718 #if CHECKSUM_GEN_IP_INLINE
00719 chk_sum += LWIP_MAKE_U16(proto, ttl);
00720 #endif
00721
00722
00723 ip_addr_copy(iphdr->dest, *dest);
00724 #if CHECKSUM_GEN_IP_INLINE
00725 chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
00726 chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
00727 #endif
00728
00729 IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
00730 IPH_TOS_SET(iphdr, tos);
00731 #if CHECKSUM_GEN_IP_INLINE
00732 chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl);
00733 #endif
00734 IPH_LEN_SET(iphdr, htons(p->tot_len));
00735 #if CHECKSUM_GEN_IP_INLINE
00736 chk_sum += iphdr->_len;
00737 #endif
00738 IPH_OFFSET_SET(iphdr, 0);
00739 IPH_ID_SET(iphdr, htons(ip_id));
00740 #if CHECKSUM_GEN_IP_INLINE
00741 chk_sum += iphdr->_id;
00742 #endif
00743 ++ip_id;
00744
00745 if (ip_addr_isany(src)) {
00746 ip_addr_copy(iphdr->src, netif->ip_addr);
00747 } else {
00748
00749 ip_addr_copy(iphdr->src, *src);
00750 }
00751
00752 #if CHECKSUM_GEN_IP_INLINE
00753 chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
00754 chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
00755 chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
00756 chk_sum = (chk_sum >> 16) + chk_sum;
00757 chk_sum = ~chk_sum;
00758 iphdr->_chksum = chk_sum;
00759 #else
00760 IPH_CHKSUM_SET(iphdr, 0);
00761 #if CHECKSUM_GEN_IP
00762 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
00763 #endif
00764 #endif
00765 } else {
00766
00767 iphdr = (struct ip_hdr *)p->payload;
00768 ip_addr_copy(dest_addr, iphdr->dest);
00769 dest = &dest_addr;
00770 }
00771
00772 IP_STATS_INC(ip.xmit);
00773
00774 LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
00775 ip_debug_print(p);
00776
00777 #if ENABLE_LOOPBACK
00778 if (ip_addr_cmp(dest, &netif->ip_addr)) {
00779
00780 LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
00781 return netif_loop_output(netif, p, dest);
00782 }
00783 #if LWIP_IGMP
00784 if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
00785 netif_loop_output(netif, p, dest);
00786 }
00787 #endif
00788 #endif
00789 #if IP_FRAG
00790
00791 if (netif->mtu && (p->tot_len > netif->mtu)) {
00792 return ip_frag(p, netif, dest);
00793 }
00794 #endif
00795
00796 LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
00797 return netif->output(netif, p, dest);
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817 err_t
00818 ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
00819 u8_t ttl, u8_t tos, u8_t proto)
00820 {
00821 struct netif *netif;
00822
00823
00824
00825 LWIP_ASSERT("p->ref == 1", p->ref == 1);
00826
00827 if ((netif = ip_route(dest)) == NULL) {
00828 LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00829 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
00830 IP_STATS_INC(ip.rterr);
00831 return ERR_RTE;
00832 }
00833
00834 return ip_output_if(p, src, dest, ttl, tos, proto, netif);
00835 }
00836
00837 #if LWIP_NETIF_HWADDRHINT
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 err_t
00857 ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
00858 u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
00859 {
00860 struct netif *netif;
00861 err_t err;
00862
00863
00864
00865 LWIP_ASSERT("p->ref == 1", p->ref == 1);
00866
00867 if ((netif = ip_route(dest)) == NULL) {
00868 LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
00869 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
00870 IP_STATS_INC(ip.rterr);
00871 return ERR_RTE;
00872 }
00873
00874 NETIF_SET_HWADDRHINT(netif, addr_hint);
00875 err = ip_output_if(p, src, dest, ttl, tos, proto, netif);
00876 NETIF_SET_HWADDRHINT(netif, NULL);
00877
00878 return err;
00879 }
00880 #endif
00881
00882 #if IP_DEBUG
00883
00884
00885
00886 void
00887 ip_debug_print(struct pbuf *p)
00888 {
00889 struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
00890
00891 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
00892 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00893 LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n",
00894 IPH_V(iphdr),
00895 IPH_HL(iphdr),
00896 IPH_TOS(iphdr),
00897 ntohs(IPH_LEN(iphdr))));
00898 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00899 LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n",
00900 ntohs(IPH_ID(iphdr)),
00901 ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
00902 ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
00903 ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
00904 ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
00905 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00906 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n",
00907 IPH_TTL(iphdr),
00908 IPH_PROTO(iphdr),
00909 ntohs(IPH_CHKSUM(iphdr))));
00910 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00911 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n",
00912 ip4_addr1_16(&iphdr->src),
00913 ip4_addr2_16(&iphdr->src),
00914 ip4_addr3_16(&iphdr->src),
00915 ip4_addr4_16(&iphdr->src)));
00916 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00917 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n",
00918 ip4_addr1_16(&iphdr->dest),
00919 ip4_addr2_16(&iphdr->dest),
00920 ip4_addr3_16(&iphdr->dest),
00921 ip4_addr4_16(&iphdr->dest)));
00922 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
00923 }
00924 #endif