/*---------------------------------------------------------------------------*/ static int parse(void) { frame802154_t frame; int len; len = packetbuf_datalen(); if(frame802154_parse(packetbuf_dataptr(), len, &frame) && packetbuf_hdrreduce(len - frame.payload_len)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return FRAMER_FAILED; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%u (%u)\n", packetbuf_datalen(), len); return len - frame.payload_len; } return FRAMER_FAILED; }
/*---------------------------------------------------------------------------*/ static int parse(void) { frame802154_t frame; int len; len = packetbuf_datalen(); if(frame802154_parse(packetbuf_dataptr(), len, &frame)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return 0; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%u (%u)\n", packetbuf_datalen(), len); return 0; } return 0; }
/*---------------------------------------------------------------------------*/ void myneighbours_update(const rimeaddr_t *neighbour, int16_t lqi) { int i, j; /* Locate neighbour */ for (i=0; i < MAX_NEIGHBOURS; i++) { if ( rimeaddr_cmp(&neighbours[i].addr, neighbour) || rimeaddr_cmp(&neighbours[i].addr, &rimeaddr_null)) { break; } } if (i>=MAX_NEIGHBOURS) { /* Neighbour list is full! */ return; } if (rimeaddr_cmp(&neighbours[i].addr, neighbour)) { /* Update existing neighbour */ neighbours[i].lqi = lqi; PRINTADDR(neighbours[i].addr.u8); printf(" lqi = %i UPDATED\r\n", neighbours[i].lqi); return; } /* Add new neighbour */ rimeaddr_copy(&neighbours[i].addr, neighbour); neighbours[i].lqi = lqi; PRINTADDR(neighbours[i].addr.u8); printf(" lqi = %i ADDED\r\n", neighbours[i].lqi); }
/*---------------------------------------------------------------------------*/ static int parse(void) { frame802154_t frame; int hdr_len; hdr_len = frame802154_parse(packetbuf_dataptr(), packetbuf_datalen(), &frame); if(hdr_len && packetbuf_hdrreduce(hdr_len)) { packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type); if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != frame802154_get_pan_id() && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return FRAMER_FAILED; } if(!frame802154_is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); if(frame.fcf.sequence_number_suppression == 0) { packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); } else { packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, 0xffff); } #if NETSTACK_CONF_WITH_RIME packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); #endif #if LLSEC802154_USES_AUX_HEADER if(frame.fcf.security_enabled) { packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); #if LLSEC802154_USES_FRAME_COUNTER packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]); #endif /* LLSEC802154_USES_FRAME_COUNTER */ #if LLSEC802154_USES_EXPLICIT_KEYS packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode); packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index); packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } #endif /* LLSEC802154_USES_AUX_HEADER */ PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen()); return hdr_len; } return FRAMER_FAILED; }
/*---------------------------------------------------------------------------*/ static int read_packet(void) { frame802154_t frame; int len; packetbuf_clear(); len = radio->read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); if(frame802154_parse(packetbuf_dataptr(), len, &frame) && packetbuf_hdrreduce(len - frame.payload_len)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Not broadcast or for our PAN */ PRINTF("6MAC: for another pan %u\n", frame.dest_pid); return 0; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr.u8)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &frame.dest_addr); if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr)) { /* Not for this node */ PRINTF("6MAC: not for us\n"); return 0; } } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &frame.src_addr); #if MAC_FILTER if(mac_filter()){ PRINTF("Filter dropped a packet!"); return -1; } #endif PRINTF("6MAC-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%u\n", packetbuf_datalen()); return packetbuf_datalen(); } else { PRINTF("6MAC: failed to parse hdr\n"); } } return 0; }
/*---------------------------------------------------------------------------*/ static int parse(void) { struct nullmac_hdr *hdr; hdr = packetbuf_dataptr(); if(packetbuf_hdrreduce(sizeof(struct nullmac_hdr))) { packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &(hdr->sender)); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &(hdr->receiver)); PRINTF("PNULLMAC-IN: "); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%u (%u)\n", packetbuf_datalen(), sizeof(struct nullmac_hdr)); return sizeof(struct nullmac_hdr); } return FRAMER_FAILED; }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { frame802154_t frame; int len; len = packetbuf_datalen(); if(frame802154_parse(packetbuf_dataptr(), len, &frame) && packetbuf_hdrreduce(len - frame.payload_len)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Not broadcast or for our PAN */ PRINTF("6MAC: for another pan %u\n", frame.dest_pid); return; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)&frame.dest_addr); if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr)) { /* Not for this node */ PRINTF("6MAC: not for us\n"); return; } } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *)&frame.src_addr); PRINTF("6MAC-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); printf("\n\n!Incoming Data %u!\n\n", packetbuf_datalen()); NETSTACK_MAC.input(); } else { PRINTF("6MAC: failed to parse hdr\n"); } }
/*---------------------------------------------------------------------------*/ static int create_frame(int type, int do_create) { frame802154_t params; int hdr_len; /* init to zeros */ memset(¶ms, 0, sizeof(params)); if(!initialized) { initialized = 1; mac_dsn = random_rand() & 0xff; } /* Build the FCF. */ params.fcf.frame_type = packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE); params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING); if(packetbuf_holds_broadcast()) { params.fcf.ack_required = 0; } else { params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK); } params.fcf.panid_compression = 0; /* Insert IEEE 802.15.4 (2006) version bits. */ params.fcf.frame_version = FRAME802154_IEEE802154_2006; #if LLSEC802154_SECURITY if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { params.fcf.security_enabled = 1; } /* Setting security-related attributes */ params.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1); params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3); #if LLSEC802154_USES_EXPLICIT_KEYS params.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE); params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); params.aux_hdr.key_source.u16[0] = packetbuf_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_SECURITY */ /* Increment and set the data sequence number. */ if(!do_create) { /* Only length calculation - no sequence number is needed and should not be consumed. */ } else if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) { params.seq = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); } else { /* Ensure that the sequence number 0 is not used as it would bypass the above check. */ if(mac_dsn == 0) { mac_dsn++; } params.seq = mac_dsn++; packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, params.seq); } /* Complete the addressing fields. */ /** \todo For phase 1 the addresses are all long. We'll need a mechanism in the rime attributes to tell the mac to use long or short for phase 2. */ if(LINKADDR_SIZE == 2) { /* Use short address mode if linkaddr size is short. */ params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; } else { params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; } params.dest_pid = mac_dst_pan_id; if(packetbuf_holds_broadcast()) { /* Broadcast requires short address mode. */ params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; params.dest_addr[0] = 0xFF; params.dest_addr[1] = 0xFF; } else { linkaddr_copy((linkaddr_t *)¶ms.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); /* Use short address mode if linkaddr size is small */ if(LINKADDR_SIZE == 2) { params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; } else { params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; } } /* Set the source PAN ID to the global variable. */ params.src_pid = mac_src_pan_id; /* * Set up the source address using only the long address mode for * phase 1. */ linkaddr_copy((linkaddr_t *)¶ms.src_addr, packetbuf_addr(PACKETBUF_ADDR_SENDER)); params.payload = packetbuf_dataptr(); params.payload_len = packetbuf_datalen(); hdr_len = frame802154_hdrlen(¶ms); if(!do_create) { /* Only calculate header length */ return hdr_len; } else if(packetbuf_hdralloc(hdr_len)) { frame802154_create(¶ms, packetbuf_hdrptr()); PRINTF("15.4-OUT: %2X", params.fcf.frame_type); PRINTADDR(params.dest_addr); PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen()); return hdr_len; } else { PRINTF("15.4-OUT: too large header: %u\n", hdr_len); return FRAMER_FAILED; } }
/*---------------------------------------------------------------------------*/ static int create(void) { frame802154_t params; int len; /* init to zeros */ memset(¶ms, 0, sizeof(params)); if(!initialized) { initialized = 1; mac_dsn = random_rand() & 0xff; } /* Build the FCF. */ params.fcf.frame_type = FRAME802154_DATAFRAME; params.fcf.security_enabled = 0; params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING); if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { params.fcf.ack_required = 0; } else { params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK); } params.fcf.panid_compression = 0; /* Insert IEEE 802.15.4 (2003) version bit. */ params.fcf.frame_version = FRAME802154_IEEE802154_2003; /* Increment and set the data sequence number. */ if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) { params.seq = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); } else { params.seq = mac_dsn++; packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, params.seq); } /* params.seq = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); */ /* Complete the addressing fields. */ /** \todo For phase 1 the addresses are all long. We'll need a mechanism in the rime attributes to tell the mac to use long or short for phase 2. */ if(sizeof(linkaddr_t) == 2) { /* Use short address mode if linkaddr size is short. */ params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; } else { params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; } params.dest_pid = mac_dst_pan_id; /* * If the output address is NULL in the Rime buf, then it is broadcast * on the 802.15.4 network. */ if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { /* Broadcast requires short address mode. */ params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; params.dest_addr[0] = 0xFF; params.dest_addr[1] = 0xFF; } else { linkaddr_copy((linkaddr_t *)¶ms.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); /* Use short address mode if linkaddr size is small */ if(sizeof(linkaddr_t) == 2) { params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; } else { params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; } } /* Set the source PAN ID to the global variable. */ params.src_pid = mac_src_pan_id; /* * Set up the source address using only the long address mode for * phase 1. */ linkaddr_copy((linkaddr_t *)¶ms.src_addr, &linkaddr_node_addr); params.payload = packetbuf_dataptr(); params.payload_len = packetbuf_datalen(); len = frame802154_hdrlen(¶ms); if(packetbuf_hdralloc(len)) { frame802154_create(¶ms, packetbuf_hdrptr(), len); PRINTF("15.4-OUT: %2X", params.fcf.frame_type); PRINTADDR(params.dest_addr); PRINTF("%d %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen()); return len; } else { PRINTF("15.4-OUT: too large header: %u\n", len); return FRAMER_FAILED; } }
/*---------------------------------------------------------------------------*/ static int send_packet(void) { frame802154_t params; uint8_t len; /* init to zeros */ memset(¶ms, 0, sizeof(params)); /* Build the FCF. */ params.fcf.frame_type = FRAME802154_DATAFRAME; params.fcf.security_enabled = 0; params.fcf.frame_pending = 0; params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_RELIABLE); params.fcf.panid_compression = 0; /* Insert IEEE 802.15.4 (2003) version bit. */ params.fcf.frame_version = FRAME802154_IEEE802154_2003; /* Increment and set the data sequence number. */ params.seq = mac_dsn++; /* Complete the addressing fields. */ /** \todo For phase 1 the addresses are all long. We'll need a mechanism in the rime attributes to tell the mac to use long or short for phase 2. */ params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; params.dest_pid = mac_dst_pan_id; /* * If the output address is NULL in the Rime buf, then it is broadcast * on the 802.15.4 network. */ if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { /* Broadcast requires short address mode. */ params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; params.dest_addr.u8[0] = 0xFF; params.dest_addr.u8[1] = 0xFF; } else { rimeaddr_copy(¶ms.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; } /* Set the source PAN ID to the global variable. */ params.src_pid = mac_src_pan_id; /* * Set up the source address using only the long address mode for * phase 1. */ rimeaddr_copy(¶ms.src_addr, &rimeaddr_node_addr); params.payload = packetbuf_dataptr(); params.payload_len = packetbuf_datalen(); len = frame802154_hdrlen(¶ms); PRINTF("payload=%s, len=%d, hdrlen=%d\n", params.payload, params.payload_len, len); if(packetbuf_hdralloc(len)) { frame802154_create(¶ms, packetbuf_hdrptr(), len); //PRINTF("6MAC-UT: %2X\n", params.fcf.frame_type); PRINTADDR(params.dest_addr.u8); //PRINTF("%u %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen()); return radio->send(packetbuf_hdrptr(), packetbuf_totlen()); } else { PRINTF("6MAC-UT: too large header: %u\n", len); } return 0; }
/*---------------------------------------------------------------------------*/ static int parse(void) { frame802154_t frame; int hdr_len; hdr_len = frame_emmac_parse(packetbuf_dataptr(), packetbuf_datalen(), &frame); if(hdr_len && packetbuf_hdrreduce(hdr_len)) { packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type); if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return FRAMER_FAILED; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } if(frame.fcf.timestamp_flag){ packetbuf_set_attr(PACKETBUF_ATTR_NODE_TIMESTAMP, frame.timestamp); packetbuf_set_attr(PACKETBUF_ATTR_NODE_CLOCK_TIME, frame.clock_time); } if(frame.fcf.rand_seed_flag) packetbuf_set_attr(PACKETBUF_ATTR_NODE_RAND_SEED, frame.random_seed); if(frame.fcf.frame_type==0) packetbuf_set_attr(PACKETBUF_ATTR_NODE_BLACKLIST, frame.blacklist); packetbuf_set_attr(PACKETBUF_ATTR_NODE_TIMESTAMP_FLAG, frame.fcf.timestamp_flag); packetbuf_set_attr(PACKETBUF_ATTR_NODE_RAND_SEED_FLAG, frame.fcf.rand_seed_flag); packetbuf_set_attr(PACKETBUF_ATTR_NODE_STATE_FLAG, frame.fcf.state_flag); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); #if LLSEC802154_SECURITY_LEVEL if(frame.fcf.security_enabled) { packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]); #if LLSEC802154_USES_EXPLICIT_KEYS packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode); packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index); packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } #endif /* LLSEC802154_SECURITY_LEVEL */ PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen()); return hdr_len; } return FRAMER_FAILED; }
/*---------------------------------------------------------------------------*/ static int parse_80211(void) { int len; uint16_t pan_id; rimeaddr_t* dst_mac_address; rimeaddr_t* src_mac_address; len = packetbuf_datalen(); /* The first 8 bytes are the destination address * of the remote node [IEEE 802.11 MAC address] * and it can well be an Ethernet broadcast one. */ dst_mac_address = (rimeaddr_t*)(packetbuf_dataptr()); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)dst_mac_address); /* We now need to remove these bytes from the * packet buffer so the plain IPv6 packet can * be sent properly. */ if(packetbuf_hdrreduce(RIMEADDR_SIZE) == 0) { PRINTF("SLIP_FRAMER: ERROR; Could not remove MAC address info from incoming slip frame.\n"); return -1; } /* The following 8 bytes contain the source address * of the local [host] interface. */ src_mac_address = (rimeaddr_t*)(packetbuf_dataptr()); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *)src_mac_address); /* TODO Sanity check; this address should be the local node. */ if (!ether_addr_equal((uint8_t*)src_mac_address, uip_lladdr.addr)) { PRINTF("SLIP_FRAMER; Packet coming from UART has a wrong source MAC Address!\n"); PRINTADDR(src_mac_address); return -1; } /* We now need to remove these bytes from the * packet buffer so the plain IPv6 packet can * be sent properly. */ if(packetbuf_hdrreduce(RIMEADDR_SIZE) == 0) { PRINTF("SLIP_FRAMER: ERROR; Could not remove MAC address info from incoming slip frame.\n"); return -1; } /* The next 2 bytes contain the PAN ID. We should drop * the packet if it does not carry the selected PAN ID */ pan_id = *((uint16_t*)(packetbuf_dataptr())); if (pan_id != mac_src_pan_id && pan_id != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %04x\n", pan_id); return -1; } /* We now need to remove these bytes from the * packet buffer so the plain IPv6 packet can * be sent properly. */ if(packetbuf_hdrreduce(sizeof(uint16_t)) == 0) { PRINTF("SLIP_FRAMER: ERROR; Could not remove PAN ID info from incoming slip frame.\n"); return -1; } /* We would like to print some log information. */ PRINTF("802.11-framer-IN: %02x%02x ",(uint8_t)pan_id,(uint8_t)(pan_id>>8)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF(" After parse: %u (%u)\n", packetbuf_datalen(), len); /* We are now ready to send the packet down. */ return 0; }
/*---------------------------------------------------------------------------*/ static void send_packet(mac_callback_t sent, void *ptr) { frame802154_t params; uint8_t len; /* init to zeros */ memset(¶ms, 0, sizeof(params)); /* Build the FCF. */ params.fcf.frame_type = FRAME802154_DATAFRAME; params.fcf.security_enabled = 0; params.fcf.frame_pending = 0; params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_RELIABLE); params.fcf.panid_compression = 0; /* Insert IEEE 802.15.4 (2003) version bit. */ params.fcf.frame_version = FRAME802154_IEEE802154_2003; /* Increment and set the data sequence number. */ params.seq = mac_dsn++; /* Complete the addressing fields. */ /** \todo For phase 1 the addresses are all long. We'll need a mechanism in the rime attributes to tell the mac to use long or short for phase 2. */ params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; params.dest_pid = mac_dst_pan_id; /* * If the output address is NULL in the Rime buf, then it is broadcast * on the 802.15.4 network. */ if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { /* Broadcast requires short address mode. */ params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; params.dest_addr[0] = 0xFF; params.dest_addr[1] = 0xFF; } else { rimeaddr_copy((rimeaddr_t *)¶ms.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; } /* Set the source PAN ID to the global variable. */ params.src_pid = mac_src_pan_id; /* * Set up the source address using only the long address mode for * phase 1. */ #if NETSTACK_CONF_BRIDGE_MODE rimeaddr_copy((rimeaddr_t *)¶ms.src_addr,packetbuf_addr(PACKETBUF_ADDR_SENDER)); #else rimeaddr_copy((rimeaddr_t *)¶ms.src_addr, &rimeaddr_node_addr); #endif params.payload = packetbuf_dataptr(); params.payload_len = packetbuf_datalen(); len = frame802154_hdrlen(¶ms); if(packetbuf_hdralloc(len)) { int ret; frame802154_create(¶ms, packetbuf_hdrptr(), len); PRINTF("6MAC-UT: %2X", params.fcf.frame_type); PRINTADDR(params.dest_addr); PRINTF("%u %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen()); ret = NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen()); if(sent) { switch(ret) { case RADIO_TX_OK: sent(ptr, MAC_TX_OK, 1); break; case RADIO_TX_ERR: sent(ptr, MAC_TX_ERR, 1); break; } } } else { PRINTF("6MAC-UT: too large header: %u\n", len); } }
/** * Filters incoming traffic in accordance with RFC 4301, section 5.2. * * \return 0 implies that the packet should be let through, 1 that it should be dropped. */ uint8_t ipsec_filter(sad_entry_t *sad_entry, ipsec_addr_t *addr) { //#define PRINTF printf //#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15]) /*PRINTF("Packet with address:\n"); PRINTADDR(addr); */ if (sad_entry) { /** * This packet was protected. * * Assert that the packet's addr is a subset of the SA's selector * (p. 62 part 4 and 5) * We don't implement the IKE notification as described in part 5. * * The reason that we don't assert this earlier is that the next layer * might enjoy confidentiality protection and hence we must decrypt it first to * get the port numbers from the next layer protocol. */ PRINTF("TRAFFIC DESC:\n"); PRINTADDRSET(&sad_entry->traffic_desc); PRINTF("ADDR:\n"); PRINTADDR(addr); if (ipsec_a_is_member_of_b(addr, &sad_entry->traffic_desc)) { // FIX: Update SA statistics return 0; } // Drop the packet PRINTF(IPSEC "Dropping incoming packet because the SAD entry's (referenced by the packet's SPI) selector didn't match the address of the packet\n"); } else { /* * This packet was unprotected. We fetch the SPD entry so that we can verify that this is in accordance * with our policy. */ spd_entry_t *spd_entry = spd_get_entry_by_addr(addr); PRINTF("Applicable packet policy:\n"); PRINTSPDENTRY(spd_entry); switch (spd_entry->proc_action) { case SPD_ACTION_BYPASS: return 0; case SPD_ACTION_PROTECT: /** * Unprotected packets that match a PROTECT policy MUST * 1) be discarded * 2) there should not be any attempt of negotiating an SA * (3b. p. 62) */ PRINTF(IPSEC "Dropping unprotected incoming packet (policy PROTECT)\n"); break; case SPD_ACTION_DISCARD: PRINTF(IPSEC "Dropping unprotected incoming packet (policy DISCARD)\n"); } } #define PRINTF #define PRINT6ADDR return 1; // Drop the packet }