Subject: [6lowpan] minimalist processing code

From: Philip Levis <[email-masked]>
Date: Thu, 9 Nov 2006 23:56:10 -0800

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-masked]
https://www1.ietf.org/mailman/listinfo/6lowpan

---

From: "Daniel Park" <[email-masked]>
Date: Sat, 11 Nov 2006 04:24:41 +0900

Philip,

Good job. Also, I'd encourage other guys implementing the previous
format to post their processing code on this list if allowed. That
would be very helpful for the 6lowpan folks to compare them.

Anyway, frankly speaking, I don't have any preference either the
previous format or the new one. Instead, I'd encourage the 6lowpan WG
to select ONE solution for further deployment quickly. Simplicity is
the best way for the success I believe.

Please speed up. Otherwise, we can lose our change in the market.

Cheers,

-- 

Daniel (Soohong Daniel Park)
Mobile Convergence Laboratory, SAMSUNG Electronics.