int randTest() { int place = 0; packed_lowmsg_t pkt; pkt.data = buf; pkt.len = 20; uint16_t mesh_orig, mesh_final, frag_size, frag_tag; uint8_t mesh_hops, bcast_seq, frag_offset; uint8_t mesh, bcast, frag1, fragN; uint16_t val16; uint8_t val8; mesh_orig = rand() % 0xffff; mesh_final = rand() % 0xffff; frag_size = rand() % 0x07ff; frag_tag = rand() % 0xffff; mesh_hops = rand() % 0x0f; bcast_seq = rand() % 0xff; frag_offset = rand() & 0xff; mesh = rand() % 2; bcast = rand() % 2; frag1 = (rand() % 3); if (frag1 == 0) fragN = 1; else fragN = 0; setupHeaders(&pkt, mesh, bcast, frag1, fragN); if (mesh) { setMeshHopsLeft(&pkt, mesh_hops); setMeshOriginAddr(&pkt, mesh_orig); setMeshFinalAddr(&pkt, mesh_final); } if (bcast) { setBcastSeqno(&pkt, bcast_seq); } if (frag1) { setFragDgramSize(&pkt, frag_size); setFragDgramTag(&pkt, frag_tag); } if (fragN) { setFragDgramSize(&pkt, frag_size); setFragDgramTag(&pkt, frag_tag); setFragDgramOffset(&pkt, frag_offset); } // test it out. if (mesh) { if (getMeshHopsLeft(&pkt, &val8)) { place = 1; goto done; } if (val8 != mesh_hops) { place = 2; goto done; } if (getMeshOriginAddr(&pkt, &val16)) { place = 3; goto done; } if (val16 != mesh_orig) { place = 4; goto done; } if (getMeshFinalAddr(&pkt, &val16)) { place = 5; goto done; } if (val16 != mesh_final) { place = 6; goto done; } } if (bcast) { if (getBcastSeqno(&pkt, &val8)) { place = 7; goto done; } if (val8 != bcast_seq) { place = 8; goto done; } } if (frag1) { if (getFragDgramSize(&pkt, &val16)) { place = 9; goto done; } if (val16 != frag_size) { place = 10; goto done; } if (getFragDgramTag(&pkt, &val16)) { place = 11; goto done; } if (val16 != frag_tag) { place = 12; goto done; } } if (fragN) { if (getFragDgramSize(&pkt, &val16)) { place = 13; goto done; } if (val16 != frag_size) { place = 14; goto done; } if (getFragDgramTag(&pkt, &val16)) { place = 15; goto done; } if (val16 != frag_tag) { place = 16; goto done; } if (getFragDgramOffset(&pkt, &val8)) { place = 17; goto done; } if (val8 != frag_offset) { place = 18; goto done; } } return 0; done: printf("\nThere was an error: place %i\n", place); printf(" Test headers: mesh: %i bcast: %i frag1: %i fragN: %i\n", mesh, bcast, frag1, fragN); if (mesh) printf(" mesh hops: 0x%x origin: 0x%x final: 0x%x\n", mesh_hops, mesh_orig, mesh_final); if (bcast) printf(" bcast seqno: 0x%x\n", bcast_seq); if (frag1) printf(" frag1 size: 0x%x tag: 0x%x\n", frag_size, frag_tag); if (fragN) printf(" fragN size: 0x%x tag: 0x%x offset: 0x%x\n", frag_size, frag_tag, frag_offset); printf(" Packed packet contents:\n"); printPacket(buf, 100); printf("\n"); return 1; }
int main(char **argv, int argc) { packed_lowmsg_t pkt; int i, failures = 0; #if 0 time_t ival; // unseed this if you don't want it to be deterministic time(&ival); printf("Time: %i\n", ival); srand(ival); #endif pkt.len = 100; pkt.data = buf; /* printf("---- Start IP Compression tests\n"); */ /* printPacket(pkt9, 3); */ /* printPacket(pkt10, 4); */ /* printPacket(pkt11, 17); */ /* printPacket(pkt12, 17); */ /* printPacket(pkt13, 41); */ /* printPacket(pkt14, 53); */ /* printPacket(pkt15, 11); */ /* printPacket(pkt16, 7); */ /* printPacket(pkt17, 9); */ printf("---- Start IP gen tests\n"); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_HC2); setIPHopsLeft(&pkt, 0xfa); printPacket(buf, 100); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_HC2 | LOWMSG_SRC_PREFIX_INLINE); setIPProtocol(&pkt, IANA_UDP); setIPHopsLeft(&pkt, 0xfa); setIPSrcPrefix(&pkt, a64_1); printPacket(buf, 100); return; zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_HC2 | LOWMSG_DST_SUFFIX_INLINE); setIPHopsLeft(&pkt, 0xfa); setIPDstSuffix(&pkt, a64_2); printPacket(buf, 100); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_HC2 | LOWMSG_DST_PREFIX_INLINE | LOWMSG_DST_SUFFIX_INLINE | LOWMSG_MESH_HDR | LOWMSG_BCAST_HDR | LOWMSG_FRAGN_HDR); setBcastSeqno(&pkt, 0x1f); setMeshHopsLeft(&pkt, 3); setMeshOriginAddr(&pkt, 0xa); setMeshFinalAddr(&pkt, 0xfb); setFragDgramSize(&pkt, 0x0ff); setFragDgramTag(&pkt, 0xcafe); setFragDgramOffset(&pkt, 0x23); setIPHopsLeft(&pkt, 0xfa); setIPDstPrefix(&pkt, a64_3); setIPDstSuffix(&pkt, a64_2); printPacket(buf, 100); return; zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_HC2 | LOWMSG_DST_SUFFIX_INLINE | LOWMSG_NEXTHDR_INLINE | LOWMSG_TCFL_INLINE); setIPHopsLeft(&pkt, 0xfa); setIPDstSuffix(&pkt, a64_2); setIPTcFl(&pkt, 0xf1, 0x1babe); setIPProtocol(&pkt, 0xfa); printPacket(buf, 100); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_HC2 | LOWMSG_DST_SUFFIX_INLINE | LOWMSG_TCFL_INLINE); setIPHopsLeft(&pkt, 0xfa); setIPDstSuffix(&pkt, a64_2); setIPTcFl(&pkt, 0xf1, 0x1babe); setIPProtocol(&pkt, IANA_UDP); printPacket(buf, 100); zeroPkt(); // ICMP. setupIPHeaders(&pkt, LOWMSG_DST_SUFFIX_INLINE | LOWMSG_TCFL_INLINE); printf("header flags 0x%x\n", pkt.headers); setIPHopsLeft(&pkt, 0xfa); setIPDstSuffix(&pkt, a64_2); setIPTcFl(&pkt, 0xf1, 0x1babe); setIPProtocol(&pkt, IANA_ICMP); struct icmp6_hdr *h = getIPPayload(&pkt); h->type = 0xf1; h->code = 0x2f; h->cksum = hton16(0xbabe); printPacket(buf, 100); zeroPkt(); // ICMP. setupIPHeaders(&pkt, 0); setIPHopsLeft(&pkt, 0xfa); setIPProtocol(&pkt, IANA_ICMP); h = getIPPayload(&pkt); h->type = 0xf1; h->code = 0x2f; h->cksum = hton16(0xbabe); printPacket(buf, 100); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_DST_SUFFIX_INLINE | LOWMSG_TCFL_INLINE); setIPHopsLeft(&pkt, 0xfa); setIPDstSuffix(&pkt, a64_2); setIPTcFl(&pkt, 0xf1, 0x1babe); setIPProtocol(&pkt, IANA_ICMP); h = getIPPayload(&pkt); h->type = 0xf1; h->code = 0x2f; h->cksum = hton16(0xbabe); printPacket(buf, 100); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_DST_SUFFIX_INLINE | LOWMSG_TCFL_INLINE | LOWMSG_MESH_HDR | LOWMSG_BCAST_HDR | LOWMSG_FRAGN_HDR); setBcastSeqno(&pkt, 0x1f); setMeshHopsLeft(&pkt, 3); setMeshOriginAddr(&pkt, 0xa); setMeshFinalAddr(&pkt, 0xfb); setFragDgramSize(&pkt, 0x0ff); setFragDgramTag(&pkt, 0xcafe); setFragDgramOffset(&pkt, 0x23); setIPHopsLeft(&pkt, 0xfa); setIPDstSuffix(&pkt, a64_2); setIPTcFl(&pkt, 0xf1, 0x1babe); setIPProtocol(&pkt, IANA_ICMP); h = getIPPayload(&pkt); h->type = 0xf1; h->code = 0x2f; h->cksum = hton16(0xbabe); printPacket(buf, 100); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_DST_SUFFIX_INLINE | LOWMSG_HC2 | LOWMSG_TCFL_INLINE | LOWMSG_MESH_HDR | LOWMSG_BCAST_HDR | LOWMSG_FRAGN_HDR); setBcastSeqno(&pkt, 0x1f); setMeshHopsLeft(&pkt, 3); setMeshOriginAddr(&pkt, 0xa); setMeshFinalAddr(&pkt, 0xfb); setFragDgramSize(&pkt, 0x0ff); setFragDgramTag(&pkt, 0xcafe); setFragDgramOffset(&pkt, 0x23); setIPHopsLeft(&pkt, 0xfa); setIPDstSuffix(&pkt, a64_2); setIPTcFl(&pkt, 0xf1, 0x1babe); setIPProtocol(&pkt, IANA_UDP); setUDPSrcPort(&pkt, 0x5); setUDPDstPort(&pkt, 0x6); setUDPChkSum(&pkt, 0xcafe); printPacket(buf, 100); zeroPkt(); // setup completly compressed IP packet. setupIPHeaders(&pkt, LOWMSG_HC2 | LOWMSG_TCFL_INLINE | LOWMSG_MESH_HDR | LOWMSG_HC2_UDP_SRC_INLINE | /* LOWMSG_HC2_UDP_LEN_INLINE | */ LOWMSG_BCAST_HDR); setBcastSeqno(&pkt, 0xaa); setMeshHopsLeft(&pkt, 3); setMeshOriginAddr(&pkt, 0xa); setMeshFinalAddr(&pkt, 0xfb); /* setFragDgramSize(&pkt, 0x0ff); */ /* setFragDgramTag(&pkt, 0xcafe); */ /* setFragDgramOffset(&pkt, 0xda); */ setIPHopsLeft(&pkt, 0x11); if (setIPTcFl(&pkt, 0xf1, 0x1babe)) printf("Error\n");; setIPProtocol(&pkt, IANA_UDP); setUDPSrcPort(&pkt, 0x5656); setUDPDstPort(&pkt, 0x6); /* setUDPLength(&pkt, 0x4320); */ setUDPChkSum(&pkt, 0xcafe); printPacket(buf, 100); /* setupIPHeaders(&pkt, 0 | LOWMSG_HC2 | */ /* // LOWMSG_TCFL_INLINE | */ /* LOWMSG_MESH_HDR | */ /* LOWMSG_HC2_UDP_SRC_INLINE | */ /* // LOWMSG_HC2_UDP_LEN_INLINE | */ /* // LOWMSG_DST_PREFIX_INLINE | */ /* // LOWMSG_DST_SUFFIX_INLINE | */ /* LOWMSG_BCAST_HDR | LOWMSG_FRAGN_HDR); */ /* setBcastSeqno(&pkt, 0x0); */ /* setMeshHopsLeft(&pkt, 0xff - 0x0); */ /* setMeshOriginAddr(&pkt, 0xa); */ /* setMeshFinalAddr(&pkt, 0xfb); */ /* setFragDgramSize(&pkt, 0x0ff); */ /* setFragDgramTag(&pkt, 0xcafe); */ /* setFragDgramOffset(&pkt, 0xda); */ /* setIPHopsLeft(&pkt, 0x11); */ /* // setIPTcFl(&pkt, 0xf1, 0x1babe); */ /* setIPProtocol(&pkt, IANA_UDP); */ /* // setIPDstPrefix(&pkt, &ip[0]); */ /* // setIPDstSuffix(&pkt, &ip[8]); */ /* setUDPSrcPort(&pkt, 0x1 + 0xff + 0 ); */ /* setUDPDstPort (&pkt, 0x5 ); */ /* setUDPChkSum(&pkt, 0xcafe); */ /* //setUDPLength(&pkt, 0x4321); */ /* printPacket(buf, 100); */ return 0; printf("---- Start hand-formed packet test ----\n"); printPacket(pkt1, 2); printPacket(pkt2, 5); printPacket(pkt3, 5); printPacket(pkt4, 5); printPacket(pkt5, 7); printPacket(pkt6, 4); printPacket(pkt7, 5); printPacket(pkt8, 12); printf("---- Start pack generation test ----\n"); pkt.len = 20; pkt.data = buf; zeroPkt(); setupHeaders(&pkt, LOWMSG_MESH_HDR); setMeshHopsLeft(&pkt, 3); setMeshOriginAddr(&pkt, 0xa); setMeshFinalAddr(&pkt, 0xfb); printPacket(buf, 20); zeroPkt(); setupHeaders(&pkt, LOWMSG_BCAST_HDR); printPacket(buf, 20); zeroPkt(); pkt.headers = 0; setupHeaders(&pkt, LOWMSG_FRAG1_HDR); setFragDgramSize(&pkt, 0x309); setFragDgramTag(&pkt, 0x601f); printPacket(buf, 20); zeroPkt(); setupHeaders(&pkt, LOWMSG_FRAGN_HDR); printPacket(buf, 20); zeroPkt(); setupHeaders(&pkt, LOWMSG_MESH_HDR | LOWMSG_BCAST_HDR); printPacket(buf, 20); zeroPkt(); setupHeaders(&pkt, LOWMSG_BCAST_HDR | LOWMSG_FRAG1_HDR); printPacket(buf, 20); zeroPkt(); setupHeaders(&pkt, LOWMSG_BCAST_HDR | LOWMSG_FRAGN_HDR); printPacket(buf, 20); zeroPkt(); setupHeaders(&pkt, LOWMSG_MESH_HDR | LOWMSG_BCAST_HDR | LOWMSG_FRAGN_HDR); setBcastSeqno(&pkt, 0x1f); setMeshHopsLeft(&pkt, 3); setMeshOriginAddr(&pkt, 0xa); setMeshFinalAddr(&pkt, 0xfb); setFragDgramSize(&pkt, 0x0ff); setFragDgramTag(&pkt, 0xcafe); setFragDgramOffset(&pkt, 0x23); printPacket(buf, 20); #if 0 printf("---- Starting random tests ----\n"); for (i = 0; i < NTESTS; i++) { zeroPkt(); if (randTest()) failures++; } printf("Failed %i/%i random tests\n", failures, NTESTS); #endif return 0; }
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; } }