int run_tests() { int i; int success = 0, total = 0; for (i = 0; i < (sizeof(cases) / sizeof(cases[0])); i++) { uint8_t buf[512], *rp, unpack[512]; struct ip6_packet packet; struct ieee154_frame_addr fr, result_fr; memset(buf, 0, 512); total++; printf("\n\n----- Test case %i ----\n", i+1); setup_test(&cases[i], &packet.ip6_hdr, &fr); printf("IEEE 802.15.4 frame: "); print_buffer(&fr, sizeof(struct ieee154_frame_addr)); printf("\n"); printf("IPv6 Header:\n"); print_buffer(&packet.ip6_hdr, sizeof(struct ip6_hdr)); printf("\n"); rp = lowpan_pack_headers(&packet, &fr, buf, 512); printf("Packed result:\n"); print_buffer(buf, rp - buf); rp = lowpan_unpack_headers(unpack, sizeof(unpack), &result_fr, buf, rp - buf); printf("Unpacked result:\n"); print_buffer(unpack, 40); if (memcmp(unpack, &packet.ip6_hdr, 40) == 0) success++; } printf("%s: %i/%i tests succeeded\n", __FILE__, success, total); if (success == total) return 0; return 1; }
int lowpan_frag_get(uint8_t *frag, size_t len, struct ip6_packet *packet, struct ieee154_frame_addr *frame, struct lowpan_ctx *ctx) { uint8_t *buf, *lowpan_buf, *ieee_buf = frag; uint16_t extra_payload; /* pack 802.15.4 */ buf = lowpan_buf = pack_ieee154_header(frag, len, frame); if (ctx->offset == 0) { int offset = 0; #if LIB6LOWPAN_HC_VERSION == -1 /* just copy the ipv6 header around... */ *buf++ = LOWPAN_IPV6_PATTERN; memcpy(buf, &packet->ip6_hdr, sizeof(struct ip6_hdr)); buf += sizeof(struct ip6_hdr); #elif !defined(LIB6LOWPAN_HC_VERSION) || LIB6LOWPAN_HC_VERSION == 6 /* pack the IPv6 header */ buf = lowpan_pack_headers(packet, frame, buf, len - (buf - frag)); if (!buf) return -1; /* pack the next headers */ offset = pack_nhc_chain(&buf, len - (buf - ieee_buf), packet); if (offset < 0) return -2; #endif /* copy the rest of the payload into this fragment */ extra_payload = ntohs(packet->ip6_hdr.ip6_plen) - offset; /* may need to fragment -- insert a FRAG1 header if so */ if (extra_payload > len - (buf - ieee_buf)) { struct packed_lowmsg lowmsg; memmove(lowpan_buf + LOWMSG_FRAG1_LEN, lowpan_buf, buf - lowpan_buf); lowmsg.data = lowpan_buf; lowmsg.len = LOWMSG_FRAG1_LEN; lowmsg.headers = 0; setupHeaders(&lowmsg, LOWMSG_FRAG1_HDR); setFragDgramSize(&lowmsg, ntohs(packet->ip6_hdr.ip6_plen) + sizeof(struct ip6_hdr)); setFragDgramTag(&lowmsg, ctx->tag); lowpan_buf += LOWMSG_FRAG1_LEN; buf += LOWMSG_FRAG1_LEN; extra_payload = len - (buf - ieee_buf); extra_payload -= (extra_payload % 8); } if (iov_read(packet->ip6_data, offset, extra_payload, buf) != extra_payload) { return -3; } ctx->offset = offset + extra_payload + sizeof(struct ip6_hdr); return (buf - frag) + extra_payload; } else { struct packed_lowmsg lowmsg; buf = lowpan_buf = pack_ieee154_header(frag, len, frame); /* setup the FRAGN header */ lowmsg.data = lowpan_buf; lowmsg.len = LOWMSG_FRAGN_LEN; lowmsg.headers = 0; setupHeaders(&lowmsg, LOWMSG_FRAGN_HDR); if (setFragDgramSize(&lowmsg, ntohs(packet->ip6_hdr.ip6_plen) + sizeof(struct ip6_hdr))) return -5; if (setFragDgramTag(&lowmsg, ctx->tag)) return -6; if (setFragDgramOffset(&lowmsg, ctx->offset / 8)) return -7; buf += LOWMSG_FRAGN_LEN; extra_payload = ntohs(packet->ip6_hdr.ip6_plen) + sizeof(struct ip6_hdr) - ctx->offset; if (extra_payload > len - (buf - ieee_buf)) { extra_payload = len - (buf - ieee_buf); extra_payload -= (extra_payload % 8); } if (iov_read(packet->ip6_data, ctx->offset - sizeof(struct ip6_hdr), extra_payload, buf) != extra_payload) { return -4; } ctx->offset += extra_payload; if (extra_payload == 0) return 0; else return (lowpan_buf - ieee_buf) + LOWMSG_FRAGN_LEN + extra_payload; } }