Here's some minimal protocol processing code for the proposed format.
I elided details that would be in the existing format (such as HC1
parsing). I would not be surprised if there is a bug or two. I've
done it in C for simplicity's sake. But overall the parsing seems
pretty easy. The only tricky bit is deciding when to continue parsing
header fields (mesh) and when not (fragment). Comments/feedback welcome.
typedef nx_struct message {
cc2420_header_t hdr;
uint8_t data[0];
} message_t;
typedef ((void)(*)(message_t*, uint8_t*, uint8_t)) proto_process_t;
// Initialize with proper protocol processing functions, be sure
// to stick null handler in for unhandled protocols
proto_process_t parse_proto[128];
parse_proto[0x01] is just parsing IPv6
parse_proto[0x02] is just parsing HC1
parse_proto[0x10] is just parsing BC0
parse_proto[0x7f] just calls alternative dispatch function array (if
exists)
void parse_fragment(message_t* packet, uint8_t* payload, uint8_t len) {
uint16_t tag;
uint16_t size;
uint16_t offset;
tag = (payload[0] & 0x1f) << 5;
tag |= (payload[1] & 0xf8) >> 3;
size = (payload[1] & 0x7) << 8;
size |= payload[2];
if (payload[0] & 0xe == 0xe) {
offset = payload[3];
payload = payload + 4;
}
else {
offset = 0;
payload = payload + 3;
}
// do reassembly here, if you want to...
// check header ordering: don't have mesh within
}
uint64_t longO;
uint64_t longF;
uint16_t shortO;
uint16_t shortF;
void parse_mesh(message_t* packet, uint8_t* payload, uint8_t len) {
// more robust implementation would check that we don't walk off
// the end of a malicious packet by ensuring payload never grows
// to more than payload + len
// would also need to keep bits on whether we are using long
// or short addresses, elided for clarity
uint8_t oBit = payload[0] & 0x20;
uint8_t fBit = payload[0] & 0x10;
uint8_t hopsLeft = payload[0] & 0xf;
payload = payload + 1;
if (hopsLeft == 0xf) {
hopsLeft = payload[0];
payload = payload + 1;
len--;
}
hopsLeft--;
if (oBit) {
memcpy(&longO, payload, 8);
payload += 8;
len -= 8;
}
else {
memcpy(&shortO, payload, 2);
payload += 2;
len -= 2;
}
if (fBit) {
memcpy(&longF, payload, 8);
payload += 8;
len -= 8;
}
else {
memcpy(&shortF, payload, 2);
payload += 2;
len -= 2;
}
// Store addresses and hopsLeft in temporary storage for protocol
// processing
parse_packet(packet, payload, len);
}
void parse_packet(message_t* packet, uint8_t* payload, uint8_t len) {
if (len == 0) {return;}
uint8_t dispatch = payload[0];
if (dispatch & 0xc == 0xc) {
parse_fragment(packet, payload, len);
}
else if (dispatch & 0x8) {
parse_mesh(packet, payload, len);
}
else {
parse_proto[dispatch](packet, payload + 1, len - 1);
}
}
_______________________________________________
6lowpan mailing list
[email protected]
https://www1.ietf.org/mailman/listinfo/6lowpan