📄 ipp.nc
字号:
return; } /* UDP Destination Port */ if ((hc2_enc & HC2_UDP_DST_PORT_MASK) == HC2_UDP_DST_PORT_INLINE) { dst_port = get_16t(buf); buf += sizeof(dst_port); len -= sizeof(dst_port); } else { //TODO return; } /* UDP Length */ if ((hc2_enc & HC2_UDP_LEN_MASK) == HC2_UDP_LEN_INLINE) { /* check the length */ if (ntohs(get_16t(buf)) != len + sizeof(uint16_t)*2) {#ifdef ENABLE_PRINTF_DEBUG printf("length check failed\n"); printf("reported length: %d\n", len + sizeof(uint16_t)*2); printf("UDP header len: %d\n", ntohs(get_16t(buf))); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ return; } buf += sizeof(uint16_t); len -= sizeof(uint16_t); } /* Checksum */ chksum = get_16t(buf); buf += sizeof(chksum); len -= sizeof(chksum); /* --- end of decompression --- */ /* Compute and check the IP header checksum. */ tmp_chksum = 0; /* IPv6 pseaudo header */ tmp_chksum = ipv6_chksum(&rx_pkt.ip_src_addr, &rx_pkt.ip_dst_addr, NEXT_HEADER_UDP, /* len is only app data, so add UDP header * length to get the length for chksum */ len + sizeof(struct udp_hdr), tmp_chksum); /* UDP header */ tmp_len = htons(len + sizeof(struct udp_hdr)); tmp_chksum = ip_chksum((void*) &src_port, sizeof(src_port), tmp_chksum); tmp_chksum = ip_chksum((void*) &dst_port, sizeof(src_port), tmp_chksum); tmp_chksum = ip_chksum((void*) &chksum, sizeof(chksum), tmp_chksum); tmp_chksum = ip_chksum((void*) &tmp_len, sizeof(len), tmp_chksum); /* UDP payload - application data */ tmp_chksum = ip_chksum(buf, len, tmp_chksum); if (tmp_chksum != 0xffff) {#ifdef ENABLE_PRINTF_DEBUG printf("udp_input_compressed(): checksum failed\n"); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ call Leds.led0Toggle(); return; }// printf("udp_input_compressed()\n");// printf("src_port: 0x%X\n", src_port);// printf("dst_port: 0x%X\n", dst_port);// printf("len (app_data): %d\n", len);// call PrintfFlush.flush(); /* Scan the list of UDP sockets and look for one that is accepting this port */ for (c = 0, conn = udp_conns; c < COUNT_UDP_CONNS; c++, conn++) { /* printf("lport: 0x%X\n", conn->lport); printf("rport: 0x%X\n", conn->rport); printf("conn->ripaddr: "); dump_serial_packet(&(conn->ripaddr), sizeof(ip6_addr_t)); printf("src_addr: "); dump_serial_packet(&rx_pkt.ip_src_addr, sizeof(ip6_addr_t)); */ if ( (conn->lport != 0 && conn->lport == dst_port) && (conn->rport == 0 || conn->rport == src_port) && (ipv6_addr_is_zero(&(conn->ripaddr)) || (cmp_ipv6_addr(&conn->ripaddr, &rx_pkt.ip_src_addr) == 0)) ) goto udp_match_found; }#ifdef ENABLE_PRINTF_DEBUG printf("udp_input_compressed(): "\ "no connection matched - dropping UDP packet\n"); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ return; udp_match_found: if (len > 0) { signal UDPClient.receive[c](&rx_pkt.ip_src_addr, ntohs(src_port), buf, len); }}/* processed the IPv6 header (uncompressed) */void ipv6_input_uncompressed(uint8_t* buf, uint16_t len){ struct ip6_hdr *hdr = (struct ip6_hdr *) buf; /* check the version */ if ((hdr->vtc & IPV6_VERSION_MASK) != 0x60) {#ifdef ENABLE_PRINTF_DEBUG printf("IP version check failed (%X)\n", hdr->vtc & IPV6_VERSION_MASK); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ return; } /* Hop Limit */ if (! hdr->hlim) { /* Hop Limit reached zero */#ifdef ENABLE_PRINTF_DEBUG printf("Hop Limit reached zero\n"); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ return; } /* check dst IP address */ if (! ipv6_addr_is_for_me(&hdr->dst_addr)) { return; } /* Check the size of the packet. If the size reported to us in * uip_len doesn't match the size reported in the IP header, there * has been a transmission error and we drop the packet. */ if ( hdr->plen != htons(len - sizeof(struct ip6_hdr))) {#ifdef ENABLE_PRINTF_DEBUG printf("length check failed\n"); printf("l2 reported length: %d\n", len - sizeof(struct ip6_hdr)); printf("IPv6 header plen: %d (network byte order: 0x%X\n", ntohs(hdr->plen), hdr->plen); //((hdr->plen & 0xff00) >> 8) & ((hdr->plen & 0xff) << 8)); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ return; } /* copy IP addresses to rx_pkt */ memcpy(&rx_pkt.ip_src_addr, &(hdr->src_addr), sizeof(rx_pkt.ip_src_addr)); memcpy(&rx_pkt.ip_dst_addr, &(hdr->dst_addr), sizeof(rx_pkt.ip_dst_addr)); /* multipex on next header */ switch (hdr->nxt_hdr) { case NEXT_HEADER_ICMP6: icmpv6_input(buf + sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr)); break; case NEXT_HEADER_UDP: udp_input(buf + sizeof(struct ip6_hdr), len - sizeof(struct ip6_hdr)); break; /* case NEXT_HEADER_TCP: break; */ default:#ifdef ENABLE_PRINTF_DEBUG printf("unknown IPv6 next header: 0x%X\n", hdr->nxt_hdr); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ break; }}/* processed the IPv6 header (uncompressed) */void ipv6_input_compressed(uint8_t* buf, uint16_t len){ struct ip6_hdr *ip_hdr = (struct ip6_hdr *) buf; uint8_t hc1_enc; uint8_t hc2_enc = 0; uint8_t next_header; /* printf("nxt_hdr: 0x%X\n", hdr->nxt_hdr); dump_serial_packet(buf, len); call PrintfFlush.flush(); */ hc1_enc = *buf; buf += sizeof(hc1_enc); len -= sizeof(hc1_enc); /* HC2 encoding follows HC1 encoding */ if ((hc1_enc & HC1_HC2_MASK) == HC1_HC2_PRESENT) { hc2_enc = *buf; buf += sizeof(hc2_enc); len -= sizeof(hc2_enc); } /* Hop Limit */ if (*buf) { buf += sizeof(ip_hdr->hlim); len -= sizeof(ip_hdr->hlim); } else { /* Hop Limit reached zero */ return; } /* source IP address */ if ((hc1_enc & HC1_SRC_PREFIX_MASK) == HC1_SRC_PREFIX_INLINE) { memcpy(&rx_pkt.ip_src_addr, buf, sizeof(rx_pkt.ip_src_addr)/2); buf += sizeof(rx_pkt.ip_src_addr)/2; len -= sizeof(rx_pkt.ip_src_addr)/2; } else { /* linl-local prefix */ memset(&rx_pkt.ip_src_addr, 0, sizeof(rx_pkt.ip_src_addr)/2); rx_pkt.ip_src_addr.addr[0] = 0xFE; rx_pkt.ip_src_addr.addr[1] = 0x80; } if ((hc1_enc & HC1_SRC_IFACEID_MASK) == HC1_SRC_IFACEID_INLINE) { memcpy(((void*)&rx_pkt.ip_src_addr) + sizeof(rx_pkt.ip_src_addr)/2, buf, sizeof(rx_pkt.ip_src_addr)/2); buf += sizeof(rx_pkt.ip_src_addr)/2; len -= sizeof(rx_pkt.ip_src_addr)/2; } /* destination IP address */ if ((hc1_enc & HC1_DST_PREFIX_MASK) == HC1_DST_PREFIX_INLINE) { memcpy(&rx_pkt.ip_dst_addr, buf, sizeof(rx_pkt.ip_dst_addr)/2); buf += sizeof(rx_pkt.ip_dst_addr)/2; len -= sizeof(rx_pkt.ip_dst_addr)/2; } else { /* linl-local prefix */ memset(&rx_pkt.ip_dst_addr, 0, sizeof(rx_pkt.ip_dst_addr)/2); rx_pkt.ip_dst_addr.addr[0] = 0xFE; rx_pkt.ip_dst_addr.addr[1] = 0x80; } if ((hc1_enc & HC1_DST_IFACEID_MASK) == HC1_DST_IFACEID_INLINE) { memcpy(((void*)&rx_pkt.ip_dst_addr) + sizeof(rx_pkt.ip_dst_addr)/2, buf, sizeof(rx_pkt.ip_dst_addr)/2); buf += sizeof(rx_pkt.ip_dst_addr)/2; len -= sizeof(rx_pkt.ip_dst_addr)/2; } /* check dst IP address */ if (! ipv6_addr_is_for_me(&rx_pkt.ip_dst_addr)) { /* printf("IP address check failed\n"); dump_serial_packet(hdr->dst_addr.addr, sizeof(hdr->dst_addr.addr)); call PrintfFlush.flush(); */ return; } /* Traffic Class and Flow Label */ if ((hc1_enc & HC1_TCFL_MASK) == HC1_TCFL_INLINE) { //TODO return; } /* Next Header */ switch (hc1_enc & HC1_NEXTHDR_MASK) { case HC1_NEXTHDR_INLINE: next_header = *buf; buf += sizeof(uint8_t); len -= sizeof(uint8_t); break; case HC1_NEXTHDR_UDP: next_header = NEXT_HEADER_UDP; break; case HC1_NEXTHDR_ICMP: next_header = NEXT_HEADER_ICMP6; break; case HC1_NEXTHDR_TCP: next_header = NEXT_HEADER_TCP; break; default:#ifdef ENABLE_PRINTF_DEBUG printf("unknown next header HC1 encoding\n"); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ return; } /* multipex on the next header */ switch (next_header) { case NEXT_HEADER_ICMP6: icmpv6_input(buf, len); break; case NEXT_HEADER_UDP: /* HC_UDP compression */ if ((hc1_enc & HC1_HC2_MASK) == HC1_HC2_PRESENT && (hc1_enc & HC1_NEXTHDR_MASK) == HC1_NEXTHDR_UDP) { udp_input_compressed(buf, len, hc2_enc); break; } else { udp_input(buf, len); break; } /* case NEXT_HEADER_TCP: break; */ default:#ifdef ENABLE_PRINTF_DEBUG printf("unknown IPv6 next header: 0x%X\n", next_header); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ break; }}/* call the right fct for processing the IPv6 header */void layer3_input(uint8_t *buf, uint16_t len){ uint8_t *dispatch = buf; buf++; len--; /* uncompressed IPv6 */ if (*dispatch == DISPATCH_UNCOMPRESSED_IPV6) { ipv6_input_uncompressed(buf, len); } /* LOWPAN_HC1 compressed IPv6 */ else if (*dispatch == DISPATCH_COMPRESSED_IPV6) { //call Leds.led1Toggle(); return ipv6_input_compressed(buf, len); } /* unknown dispatch value if we got here */ else { //TODO: report an error }}/* process the optional 6lowpan headers */void TRUSTEDBLOCK lowpan_input(uint8_t* buf, uint8_t len ){ uint8_t *dispatch; struct lowpan_broadcast_hdr *bc_hdr; struct lowpan_frag_hdr *frag_hdr; int i; frag_buf_t *frag; uint16_t dgram_tag; uint16_t dgram_size; uint8_t dgram_offset; frag_info_t *p; frag_info_t **q; uint8_t last_frag; dispatch = buf; /* --- 6lowpan optional headers --- */ /* Mesh Addressing header */ if ( (*dispatch & DISPATCH_MESH_MASK) == DISPATCH_MESH) { // check if we're the final recipient in the mesh addressing header buf++; len--; /* Hops Left */ if ((*dispatch & 0x0F) == 0) { goto discard_packet; } /* Final Destination Address */ if (*dispatch & DISPATCH_MESH_F_FLAG) { rx_pkt.hw_dst_addr.type = HW_ADDR_LONG; memcpy(&rx_pkt.hw_dst_addr.addr_long, buf, sizeof(rx_pkt.hw_dst_addr.addr_long)); buf += sizeof(rx_pkt.hw_dst_addr.addr_long); len -= sizeof(rx_pkt.hw_dst_addr.addr_long); } else { rx_pkt.hw_dst_addr.type = HW_ADDR_SHORT; memcpy(&rx_pkt.hw_dst_addr.addr_short, buf, sizeof(rx_pkt.hw_dst_addr.addr_short)); buf += sizeof(rx_pkt.hw_dst_addr.addr_short); len -= sizeof(rx_pkt.hw_dst_addr.addr_short); } /* check if we're the recipient */ if (! hw_addr_is_for_me(&rx_pkt.hw_dst_addr)) { // TODO: if mesh forwarding enabled, then forward goto discard_packet; } /* Originator Address */ if (*dispatch & DISPATCH_MESH_O_FLAG) { rx_pkt.hw_src_addr.type = HW_ADDR_LONG; memcpy(&rx_pkt.hw_src_addr.addr_long, buf, sizeof(rx_pkt.hw_src_addr.addr_long)); buf += sizeof(rx_pkt.hw_src_addr.addr_long); len -= sizeof(rx_pkt.hw_src_addr.addr_long); } else { rx_pkt.hw_src_addr.type = HW_ADDR_SHORT; memcpy(rx_pkt.hw_src_addr.addr_short, buf, sizeof(rx_pkt.hw_src_addr.addr_short)); buf += sizeof(rx_pkt.hw_src_addr.addr_short); len -= sizeof(rx_pkt.hw_src_addr.addr_short); } dispatch = buf; } if (*dispatch == DISPATCH_BC0) { /* Broadcast header */ bc_hdr = (struct lowpan_broadcast_hdr *) buf; // do something usefull with bc_hdr->seq_no... buf += (sizeof(struct lowpan_broadcast_hdr)); len -= (sizeof(struct lowpan_broadcast_hdr)); dispatch = buf; } /* fragment header */ if ((*dispatch & DISPATCH_FRAG_MASK) == DISPATCH_FIRST_FRAG || (*dispatch & DISPATCH_FRAG_MASK) == DISPATCH_SUBSEQ_FRAG ) { frag_hdr = (struct lowpan_frag_hdr *) buf; buf += sizeof(struct lowpan_frag_hdr); len -= sizeof(struct lowpan_frag_hdr); /* collect information about the fragment */ dgram_tag = get_16t(&frag_hdr->dgram_tag); //dgram_size = get_16t(&frag_hdr->dgram_size); //dgram_size &= htons(0x07FF); dgram_size = frag_hdr->dgram_size8[1]; dgram_size += (frag_hdr->dgram_size8[0] & 0x07) << 8; dgram_size = htons(dgram_size); if ((*dispatch & DISPATCH_FRAG_MASK) == DISPATCH_SUBSEQ_FRAG) { dgram_offset = *buf; buf += 1; len -= 1; } else { dgram_offset = 0; }#ifdef ENABLE_PRINTF_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -