69 #if LWIP_IPV6 && LWIP_6LOWPAN 83 struct ieee_802154_addr {
90 struct lowpan6_reass_helper {
92 struct lowpan6_reass_helper *next_packet;
94 struct ieee_802154_addr sender_addr;
99 static struct lowpan6_reass_helper * reass_list;
101 #if LWIP_6LOWPAN_NUM_CONTEXTS > 0 102 static ip6_addr_t lowpan6_context[LWIP_6LOWPAN_NUM_CONTEXTS];
105 static u16_t ieee_802154_pan_id;
107 static const struct ieee_802154_addr ieee_802154_broadcast = {2, {0xff, 0xff}};
109 #if LWIP_6LOWPAN_INFER_SHORT_ADDRESS 110 static struct ieee_802154_addr short_mac_addr = {2, {0,0}};
113 static err_t dequeue_datagram(
struct lowpan6_reass_helper *lrh);
123 struct lowpan6_reass_helper *lrh, *lrh_temp;
126 while (lrh != NULL) {
127 lrh_temp = lrh->next_packet;
128 if ((--lrh->timer) == 0) {
129 dequeue_datagram(lrh);
141 dequeue_datagram(
struct lowpan6_reass_helper *lrh)
143 struct lowpan6_reass_helper *lrh_temp;
145 if (reass_list == lrh) {
146 reass_list = reass_list->next_packet;
148 lrh_temp = reass_list;
149 while (lrh_temp != NULL) {
150 if (lrh_temp->next_packet == lrh) {
151 lrh_temp->next_packet = lrh->next_packet;
154 lrh_temp = lrh_temp->next_packet;
162 lowpan6_context_lookup(
const ip6_addr_t *ip6addr)
166 for (i = 0; i < LWIP_6LOWPAN_NUM_CONTEXTS; i++) {
167 if (ip6_addr_netcmp(&lowpan6_context[i], ip6addr)) {
177 lowpan6_get_address_mode(
const ip6_addr_t *ip6addr,
const struct ieee_802154_addr *mac_addr)
179 if (mac_addr->addr_len == 2) {
180 if ((ip6addr->addr[2] == (u32_t)PP_HTONL(0x000000ff)) &&
181 ((ip6addr->addr[3] & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000))) {
182 if ((ip6addr->addr[3] & PP_HTONL(0x0000ffff)) == lwip_ntohl((mac_addr->addr[0] << 8) | mac_addr->addr[1])) {
186 }
else if (mac_addr->addr_len == 8) {
187 if ((ip6addr->addr[2] == lwip_ntohl(((mac_addr->addr[0] ^ 2) << 24) | (mac_addr->addr[1] << 16) | mac_addr->addr[2] << 8 | mac_addr->addr[3])) &&
188 (ip6addr->addr[3] == lwip_ntohl((mac_addr->addr[4] << 24) | (mac_addr->addr[5] << 16) | mac_addr->addr[6] << 8 | mac_addr->addr[7]))) {
193 if ((ip6addr->addr[2] == PP_HTONL(0x000000ffUL)) &&
194 ((ip6addr->addr[3] & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000UL))) {
203 lowpan6_get_address_mode_mc(
const ip6_addr_t *ip6addr)
205 if ((ip6addr->addr[0] == PP_HTONL(0xff020000)) &&
206 (ip6addr->addr[1] == 0) &&
207 (ip6addr->addr[2] == 0) &&
208 ((ip6addr->addr[3] & PP_HTONL(0xffffff00)) == 0)) {
210 }
else if (((ip6addr->addr[0] & PP_HTONL(0xff00ffff)) == PP_HTONL(0xff000000)) &&
211 (ip6addr->addr[1] == 0)) {
212 if ((ip6addr->addr[2] == 0) &&
213 ((ip6addr->addr[3] & PP_HTONL(0xff000000)) == 0)) {
215 }
else if ((ip6addr->addr[2] & PP_HTONL(0xffffff00)) == 0) {
229 lowpan6_frag(
struct netif *
netif,
struct pbuf *p,
const struct ieee_802154_addr *src,
const struct ieee_802154_addr *dst)
231 struct pbuf * p_frag;
232 u16_t frag_len, remaining_len;
234 u8_t ieee_header_len;
235 u8_t lowpan6_header_len;
237 static u8_t frame_seq_num;
238 static u16_t datagram_tag;
239 u16_t datagram_offset;
244 if (p_frag == NULL) {
245 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
250 buffer = (u8_t*)p_frag->
payload;
252 if (dst == &ieee_802154_broadcast) {
253 buffer[ieee_header_len++] = 0x01;
255 buffer[ieee_header_len++] = 0x21;
257 buffer[ieee_header_len] = (0x00 << 4);
258 buffer[ieee_header_len] |= (dst->addr_len == 2) ? (0x02 << 2) : (0x03 << 2);
259 buffer[ieee_header_len] |= (src->addr_len == 2) ? (0x02 << 6) : (0x03 << 6);
261 buffer[ieee_header_len++] = frame_seq_num++;
263 buffer[ieee_header_len++] = ieee_802154_pan_id & 0xff;
264 buffer[ieee_header_len++] = (ieee_802154_pan_id >> 8) & 0xff;
267 buffer[ieee_header_len++] = dst->addr[i];
270 buffer[ieee_header_len++] = ieee_802154_pan_id & 0xff;
271 buffer[ieee_header_len++] = (ieee_802154_pan_id >> 8) & 0xff;
274 buffer[ieee_header_len++] = src->addr[i];
277 #if LWIP_6LOWPAN_IPHC 288 lowpan6_header_len = 2;
289 buffer[ieee_header_len] = 0x60;
290 buffer[ieee_header_len + 1] = 0;
294 #if LWIP_6LOWPAN_NUM_CONTEXTS > 0 295 buffer[ieee_header_len + 2] = 0;
300 buffer[ieee_header_len + 1] |= 0x40;
301 buffer[ieee_header_len + 2] |= (i & 0x0f) << 4;
307 buffer[ieee_header_len + 1] |= 0x04;
308 buffer[ieee_header_len + 2] |= i & 0x0f;
311 if (buffer[ieee_header_len + 2] != 0x00) {
313 buffer[ieee_header_len + 1] |= 0x80;
314 lowpan6_header_len++;
319 if (IP6H_FL(ip6hdr) == 0) {
321 buffer[ieee_header_len] |= 0x10;
322 if (IP6H_TC(ip6hdr) == 0) {
324 buffer[ieee_header_len] |= 0x08;
327 buffer[ieee_header_len + lowpan6_header_len++] = IP6H_TC(ip6hdr);
330 if (((IP6H_TC(ip6hdr) & 0x3f) == 0)) {
332 buffer[ieee_header_len] |= 0x08;
334 buffer[ieee_header_len + lowpan6_header_len] = IP6H_TC(ip6hdr) & 0xc0;
335 buffer[ieee_header_len + lowpan6_header_len++] |= (IP6H_FL(ip6hdr) >> 16) & 0x0f;
336 buffer[ieee_header_len + lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff;
337 buffer[ieee_header_len + lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff;
340 buffer[ieee_header_len + lowpan6_header_len++] = IP6H_TC(ip6hdr);
341 buffer[ieee_header_len + lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 16) & 0x0f;
342 buffer[ieee_header_len + lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff;
343 buffer[ieee_header_len + lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff;
349 if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) {
350 buffer[ieee_header_len] |= 0x04;
353 buffer[ieee_header_len + lowpan6_header_len++] = IP6H_NEXTH(ip6hdr);
357 if (IP6H_HOPLIM(ip6hdr) == 255) {
358 buffer[ieee_header_len] |= 0x03;
359 }
else if (IP6H_HOPLIM(ip6hdr) == 64) {
360 buffer[ieee_header_len] |= 0x02;
361 }
else if (IP6H_HOPLIM(ip6hdr) == 1) {
362 buffer[ieee_header_len] |= 0x01;
365 buffer[ieee_header_len + lowpan6_header_len++] = IP6H_HOPLIM(ip6hdr);
369 if (((buffer[ieee_header_len + 1] & 0x40) != 0) ||
373 buffer[ieee_header_len + 1] |= (i & 0x03) << 4;
375 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 16, 8);
376 lowpan6_header_len += 8;
378 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 22, 2);
379 lowpan6_header_len += 2;
383 buffer[ieee_header_len + 1] |= 0x40;
386 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 8, 16);
387 lowpan6_header_len += 16;
394 buffer[ieee_header_len + 1] |= 0x08;
397 buffer[ieee_header_len + 1] |= i & 0x03;
399 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 24, 16);
400 lowpan6_header_len += 16;
402 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[25];
403 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 35, 5);
404 lowpan6_header_len += 5;
406 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[25];
407 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 37, 3);
408 lowpan6_header_len += 3;
410 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[39];
412 }
else if (((buffer[ieee_header_len + 1] & 0x04) != 0) ||
416 buffer[ieee_header_len + 1] |= i & 0x03;
418 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 32, 8);
419 lowpan6_header_len += 8;
421 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 38, 2);
422 lowpan6_header_len += 2;
426 MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->
payload + 24, 16);
427 lowpan6_header_len += 16;
434 if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) {
437 buffer[ieee_header_len + lowpan6_header_len] = 0xf0;
440 if ((((u8_t *)p->
payload)[0] == 0xf0) && ((((u8_t *)p->
payload)[1] & 0xf0) == 0xb0) &&
441 (((u8_t *)p->
payload)[2] == 0xf0) && ((((u8_t *)p->
payload)[3] & 0xf0) == 0xb0)) {
443 buffer[ieee_header_len + lowpan6_header_len++] |= 0x03;
444 buffer[ieee_header_len + lowpan6_header_len++] = ((((u8_t *)p->
payload)[1] & 0x0f) << 4) | (((u8_t *)p->
payload)[3] & 0x0f);
445 }
else if (((u8_t *)p->
payload)[0] == 0xf0) {
447 buffer[ieee_header_len + lowpan6_header_len++] |= 0x02;
448 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[1];
449 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[2];
450 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[3];
451 }
else if (((u8_t *)p->
payload)[2] == 0xf0) {
453 buffer[ieee_header_len + lowpan6_header_len++] |= 0x01;
454 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[0];
455 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[1];
456 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[3];
459 lowpan6_header_len++;
460 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[0];
461 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[1];
462 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[2];
463 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[3];
467 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[6];
468 buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->
payload)[7];
476 lowpan6_header_len = 1;
477 buffer[ieee_header_len] = 0x41;
483 if (remaining_len > 0x7FF) {
484 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
491 if (remaining_len > (127 - ieee_header_len - lowpan6_header_len - 3)) {
493 i = lowpan6_header_len;
495 buffer[ieee_header_len + i + 4] = buffer[ieee_header_len + i];
499 buffer[ieee_header_len] = 0xc0 | (((p->
tot_len + lowpan6_header_len) >> 8) & 0x7);
500 buffer[ieee_header_len + 1] = (p->
tot_len + lowpan6_header_len) & 0xff;
503 buffer[ieee_header_len + 2] = datagram_tag & 0xff;
504 buffer[ieee_header_len + 3] = (datagram_tag >> 8) & 0xff;
507 frag_len = (127 - ieee_header_len - 4 - 2) & 0xf8;
509 pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len + 4, frag_len - lowpan6_header_len, 0);
510 remaining_len -= frag_len - lowpan6_header_len;
511 datagram_offset = frag_len;
514 #if LWIP_6LOWPAN_HW_CRC 521 p_frag->
len = p_frag->
tot_len = ieee_header_len + 4 + frag_len + 2;
524 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->
tot_len);
528 while ((remaining_len > 0) && (err ==
ERR_OK)) {
530 buffer[2] = frame_seq_num++;
532 buffer[ieee_header_len] |= 0x20;
534 buffer[ieee_header_len + 4] = (u8_t)(datagram_offset >> 3);
536 frag_len = (127 - ieee_header_len - 5 - 2) & 0xf8;
537 if (frag_len > remaining_len) {
538 frag_len = remaining_len;
542 remaining_len -= frag_len;
543 datagram_offset += frag_len;
546 #if LWIP_6LOWPAN_HW_CRC 553 p_frag->
len = p_frag->
tot_len = frag_len + 5 + ieee_header_len + 2;
556 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->
tot_len);
562 frag_len = remaining_len;
565 pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len, frag_len, 0);
569 #if LWIP_6LOWPAN_HW_CRC 576 p_frag->
len = p_frag->
tot_len = frag_len + lowpan6_header_len + ieee_header_len + 2;
579 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->
tot_len);
590 lowpan6_set_context(u8_t idx,
const ip6_addr_t * context)
592 if (idx >= LWIP_6LOWPAN_NUM_CONTEXTS) {
596 ip6_addr_set(&lowpan6_context[idx], context);
601 #if LWIP_6LOWPAN_INFER_SHORT_ADDRESS 603 lowpan6_set_short_addr(u8_t addr_high, u8_t addr_low)
605 short_mac_addr.addr[0] = addr_high;
606 short_mac_addr.addr[1] = addr_low;
614 lowpan4_output(
struct netif *netif,
struct pbuf *q,
const ip4_addr_t *ipaddr)
636 lowpan6_output(
struct netif *netif,
struct pbuf *q,
const ip6_addr_t *ip6addr)
640 struct ieee_802154_addr src, dest;
641 #if LWIP_6LOWPAN_INFER_SHORT_ADDRESS 646 #if LWIP_6LOWPAN_INFER_SHORT_ADDRESS 648 ip6_hdr = (
struct ip6_hdr *)q->
payload;
649 ip6_addr_set(&ip6_src, &ip6_hdr->src);
650 if (lowpan6_get_address_mode(&ip6_src, &short_mac_addr) == 3) {
652 src.addr[0] = short_mac_addr.addr[0];
653 src.addr[1] = short_mac_addr.addr[1];
662 if (ip6_addr_ismulticast(ip6addr)) {
663 MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
665 return lowpan6_frag(netif, q, &src, &ieee_802154_broadcast);
671 #if LWIP_6LOWPAN_INFER_SHORT_ADDRESS 672 if (src.addr_len == 2) {
676 dest.addr[0] = ((u8_t *)q->
payload)[38];
677 dest.addr[1] = ((u8_t *)q->
payload)[39];
678 if ((src.addr_len == 2) && (ip6_addr_netcmp(&ip6_hdr->src, &ip6_hdr->dest)) &&
679 (lowpan6_get_address_mode(ip6addr, &dest) == 3)) {
680 MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
681 return lowpan6_frag(netif, q, &src, &dest);
687 result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr);
689 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
694 if (hwaddr == NULL) {
700 SMEMCPY(dest.addr, hwaddr, netif->
hwaddr_len);
701 MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
702 return lowpan6_frag(netif, q, &src, &dest);
706 lowpan6_decompress(
struct pbuf * p,
struct ieee_802154_addr * src,
struct ieee_802154_addr * dest)
709 u8_t * lowpan6_buffer;
711 struct ip6_hdr *ip6hdr;
713 s8_t ip6_offset = IP6_HLEN;
722 lowpan6_buffer = (u8_t *)p->
payload;
723 ip6hdr = (
struct ip6_hdr *)q->
payload;
726 if (lowpan6_buffer[1] & 0x80) {
731 if ((lowpan6_buffer[0] & 0x18) == 0x00) {
732 IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], ((lowpan6_buffer[lowpan6_offset+1] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset+3]);
734 }
else if ((lowpan6_buffer[0] & 0x18) == 0x08) {
735 IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset+2]);
737 }
else if ((lowpan6_buffer[0] & 0x18) == 0x10) {
738 IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset],0);
740 }
else if ((lowpan6_buffer[0] & 0x18) == 0x18) {
741 IP6H_VTCFL_SET(ip6hdr, 6, 0, 0);
745 if ((lowpan6_buffer[0] & 0x04) == 0x00) {
746 IP6H_NEXTH_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]);
749 IP6H_NEXTH_SET(ip6hdr, 0);
753 if ((lowpan6_buffer[0] & 0x03) == 0x00) {
754 IP6H_HOPLIM_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]);
755 }
else if ((lowpan6_buffer[0] & 0x03) == 0x01) {
756 IP6H_HOPLIM_SET(ip6hdr, 1);
757 }
else if ((lowpan6_buffer[0] & 0x03) == 0x02) {
758 IP6H_HOPLIM_SET(ip6hdr, 64);
759 }
else if ((lowpan6_buffer[0] & 0x03) == 0x03) {
760 IP6H_HOPLIM_SET(ip6hdr, 255);
764 if ((lowpan6_buffer[1] & 0x40) == 0x00) {
766 if ((lowpan6_buffer[1] & 0x30) == 0x00) {
768 MEMCPY(&ip6hdr->src.addr[0], lowpan6_buffer + lowpan6_offset, 16);
769 lowpan6_offset += 16;
770 }
else if ((lowpan6_buffer[1] & 0x30) == 0x10) {
771 ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
772 ip6hdr->src.addr[1] = 0;
773 MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8);
775 }
else if ((lowpan6_buffer[1] & 0x30) == 0x20) {
776 ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
777 ip6hdr->src.addr[1] = 0;
778 ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
779 ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) |
780 lowpan6_buffer[lowpan6_offset+1]);
782 }
else if ((lowpan6_buffer[1] & 0x30) == 0x30) {
783 ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL);
784 ip6hdr->src.addr[1] = 0;
785 if (src->addr_len == 2) {
786 ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
787 ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]);
789 ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) |
790 (src->addr[2] << 8) | src->addr[3]);
791 ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) |
792 (src->addr[6] << 8) | src->addr[7]);
797 if ((lowpan6_buffer[1] & 0x30) == 0x00) {
799 ip6hdr->src.addr[0] = 0;
800 ip6hdr->src.addr[1] = 0;
801 ip6hdr->src.addr[2] = 0;
802 ip6hdr->src.addr[3] = 0;
805 if (lowpan6_buffer[1] & 0x80) {
806 i = (lowpan6_buffer[2] >> 4) & 0x0f;
810 if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) {
817 ip6hdr->src.addr[0] = lowpan6_context[i].addr[0];
818 ip6hdr->src.addr[1] = lowpan6_context[i].addr[1];
821 if ((lowpan6_buffer[1] & 0x30) == 0x10) {
822 MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8);
824 }
else if ((lowpan6_buffer[1] & 0x30) == 0x20) {
825 ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
826 ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset+1]);
828 }
else if ((lowpan6_buffer[1] & 0x30) == 0x30) {
829 if (src->addr_len == 2) {
830 ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL);
831 ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]);
833 ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) | (src->addr[2] << 8) | src->addr[3]);
834 ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) | (src->addr[6] << 8) | src->addr[7]);
840 if (lowpan6_buffer[1] & 0x08) {
842 if (lowpan6_buffer[1] & 0x04) {
849 if ((lowpan6_buffer[1] & 0x03) == 0x00) {
851 MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16);
852 lowpan6_offset += 16;
853 }
else if ((lowpan6_buffer[1] & 0x03) == 0x01) {
854 ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16));
855 ip6hdr->dest.addr[1] = 0;
856 ip6hdr->dest.addr[2] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]);
857 ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 24) | (lowpan6_buffer[lowpan6_offset + 1] << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset + 3]);
859 }
else if ((lowpan6_buffer[1] & 0x03) == 0x02) {
860 ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | lowpan6_buffer[lowpan6_offset++]);
861 ip6hdr->dest.addr[1] = 0;
862 ip6hdr->dest.addr[2] = 0;
863 ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset + 2]);
865 }
else if ((lowpan6_buffer[1] & 0x03) == 0x03) {
866 ip6hdr->dest.addr[0] = PP_HTONL(0xff020000UL);
867 ip6hdr->dest.addr[1] = 0;
868 ip6hdr->dest.addr[2] = 0;
869 ip6hdr->dest.addr[3] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]);
873 if (lowpan6_buffer[1] & 0x04) {
876 if (lowpan6_buffer[1] & 0x80) {
877 i = lowpan6_buffer[2] & 0x0f;
881 if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) {
888 ip6hdr->dest.addr[0] = lowpan6_context[i].addr[0];
889 ip6hdr->dest.addr[1] = lowpan6_context[i].addr[1];
892 ip6hdr->dest.addr[0] = PP_HTONL(0xfe800000UL);
893 ip6hdr->dest.addr[1] = 0;
896 if ((lowpan6_buffer[1] & 0x03) == 0x00) {
898 MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16);
899 lowpan6_offset += 16;
900 }
else if ((lowpan6_buffer[1] & 0x03) == 0x01) {
901 MEMCPY(&ip6hdr->dest.addr[2], lowpan6_buffer + lowpan6_offset, 8);
903 }
else if ((lowpan6_buffer[1] & 0x03) == 0x02) {
904 ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL);
905 ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]);
907 }
else if ((lowpan6_buffer[1] & 0x03) == 0x03) {
908 if (dest->addr_len == 2) {
909 ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL);
910 ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (dest->addr[0] << 8) | dest->addr[1]);
912 ip6hdr->dest.addr[2] = lwip_htonl(((dest->addr[0] ^ 2) << 24) | (dest->addr[1] << 16) | dest->addr[2] << 8 | dest->addr[3]);
913 ip6hdr->dest.addr[3] = lwip_htonl((dest->addr[4] << 24) | (dest->addr[5] << 16) | dest->addr[6] << 8 | dest->addr[7]);
920 if (lowpan6_buffer[0] & 0x04) {
921 if ((lowpan6_buffer[lowpan6_offset] & 0xf8) == 0xf0) {
925 IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_UDP);
928 if (lowpan6_buffer[lowpan6_offset] & 0x04) {
936 i = lowpan6_buffer[lowpan6_offset++] & 0x03;
938 udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]);
939 udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 2] << 8 | lowpan6_buffer[lowpan6_offset + 3]);
941 }
else if (i == 0x01) {
942 udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]);
943 udphdr->dest = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset + 2]);
945 }
else if (i == 0x02) {
946 udphdr->src = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset]);
947 udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 1] << 8 | lowpan6_buffer[lowpan6_offset + 2]);
949 }
else if (i == 0x03) {
950 udphdr->src = lwip_htons(0xf0b0 | ((lowpan6_buffer[lowpan6_offset] >> 4) & 0x0f));
951 udphdr->dest = lwip_htons(0xf0b0 | (lowpan6_buffer[lowpan6_offset] & 0x0f));
955 udphdr->chksum = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]);
957 udphdr->len = lwip_htons(p->
tot_len - lowpan6_offset + UDP_HLEN);
959 ip6_offset += UDP_HLEN;
973 if (p->
next != NULL) {
980 IP6H_PLEN_SET(ip6hdr, q->
tot_len - IP6_HLEN);
987 lowpan6_input(
struct pbuf * p,
struct netif *netif)
991 struct ieee_802154_addr src, dest;
992 u16_t datagram_size, datagram_offset, datagram_tag;
993 struct lowpan6_reass_helper *lrh, *lrh_temp;
995 MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->
tot_len);
1000 if ((puc[1] & 0x0c) == 0x0c) {
1002 for (i = 0; i < 8; i++) {
1003 dest.addr[i] = puc[datagram_offset + 7 - i];
1005 datagram_offset += 8;
1008 dest.addr[0] = puc[datagram_offset + 1];
1009 dest.addr[1] = puc[datagram_offset];
1010 datagram_offset += 2;
1013 datagram_offset += 2;
1015 if ((puc[1] & 0xc0) == 0xc0) {
1017 for (i = 0; i < 8; i++) {
1018 src.addr[i] = puc[datagram_offset + 7 - i];
1020 datagram_offset += 8;
1023 src.addr[0] = puc[datagram_offset + 1];
1024 src.addr[1] = puc[datagram_offset];
1025 datagram_offset += 2;
1033 if ((*puc & 0xf8) == 0xc0) {
1035 datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1];
1036 datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3];
1040 while (lrh != NULL) {
1041 if ((lrh->sender_addr.addr_len == src.addr_len) &&
1042 (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0)) {
1044 if ((datagram_tag == lrh->datagram_tag) && (datagram_size == lrh->datagram_size)) {
1045 MIB2_STATS_NETIF_INC(netif, ifindiscards);
1051 lrh_temp = lrh->next_packet;
1052 dequeue_datagram(lrh);
1061 lrh = lrh->next_packet;
1067 lrh = (
struct lowpan6_reass_helper *)
mem_malloc(
sizeof(
struct lowpan6_reass_helper));
1069 MIB2_STATS_NETIF_INC(netif, ifindiscards);
1074 lrh->sender_addr.addr_len = src.addr_len;
1075 for (i = 0; i < src.addr_len; i++) {
1076 lrh->sender_addr.addr[i] = src.addr[i];
1078 lrh->datagram_size = datagram_size;
1079 lrh->datagram_tag = datagram_tag;
1081 lrh->next_packet = reass_list;
1086 }
else if ((*puc & 0xf8) == 0xe0) {
1088 datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1];
1089 datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3];
1090 datagram_offset = (u16_t)puc[4] << 3;
1093 for (lrh = reass_list; lrh != NULL; lrh = lrh->next_packet) {
1094 if ((lrh->sender_addr.addr_len == src.addr_len) &&
1095 (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0) &&
1096 (datagram_tag == lrh->datagram_tag) &&
1097 (datagram_size == lrh->datagram_size)) {
1103 MIB2_STATS_NETIF_INC(netif, ifindiscards);
1108 if (lrh->pbuf->tot_len < datagram_offset) {
1112 }
else if (lrh->pbuf->tot_len > datagram_offset) {
1113 MIB2_STATS_NETIF_INC(netif, ifindiscards);
1115 dequeue_datagram(lrh);
1125 if (lrh->pbuf->tot_len >= lrh->datagram_size) {
1127 dequeue_datagram(lrh);
1149 }
else if ((*puc & 0xe0 )== 0x60) {
1151 p = lowpan6_decompress(p, &src, &dest);
1153 MIB2_STATS_NETIF_INC(netif, ifindiscards);
1157 MIB2_STATS_NETIF_INC(netif, ifindiscards);
1163 MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
1165 return ip6_input(p, netif);
1169 lowpan6_if_init(
struct netif *netif)
1171 netif->
name[0] =
'L';
1172 netif->
name[1] =
'6';
1174 netif->output = lowpan4_output;
1176 netif->output_ip6 = lowpan6_output;
1178 MIB2_INIT_NETIF(netif, snmp_ifType_other, 0);
1190 lowpan6_set_pan_id(u16_t pan_id)
1192 ieee_802154_pan_id = pan_id;
1206 tcpip_6lowpan_input(
struct pbuf *p,
struct netif *inp)
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
void mem_free(void *rmem)
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
#define NETIF_FLAG_BROADCAST
ip_addr_t current_iphdr_dest
void pbuf_cat(struct pbuf *h, struct pbuf *t)
#define LWIP_DEBUGF(debug, message)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
u8_t pbuf_free(struct pbuf *p)
void * mem_malloc(mem_size_t size)
ip_addr_t current_iphdr_src
netif_linkoutput_fn linkoutput