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

Reply via email to