diff --git a/core/net/mac/frame802154.c b/core/net/mac/frame802154.c index fa7a46962..eb39e62c3 100644 --- a/core/net/mac/frame802154.c +++ b/core/net/mac/frame802154.c @@ -122,7 +122,8 @@ field_len(frame802154_t *p, field_length_t *flen) /* Aux security header */ if(p->fcf.security_enabled & 1) { - /* TODO Aux security header not yet implemented */ + flen->aux_sec_len = 5; + /* TODO Support key identifier mode !=0 */ #if 0 switch(p->aux_hdr.security_control.key_id_mode) { case 0: @@ -232,8 +233,10 @@ frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len) /* Aux header */ if(flen.aux_sec_len) { - /* TODO Aux security header not yet implemented */ -/* pos += flen.aux_sec_len; */ + /* TODO Support key identifier mode !=0 */ + tx_frame_buffer[pos++] = p->aux_hdr.security_control.security_level; + memcpy(tx_frame_buffer + pos, p->aux_hdr.frame_counter.u8, 4); + pos += 4; } return (int)pos; @@ -338,8 +341,17 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) } if(fcf.security_enabled) { - /* TODO aux security header, not yet implemented */ -/* return 0; */ + pf->aux_hdr.security_control.security_level = p[0] & 7; + pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3; + p += 1; + + memcpy(pf->aux_hdr.frame_counter.u8, p, 4); + p += 4; + + if(pf->aux_hdr.security_control.key_id_mode) { + /* TODO Support key identifier mode !=0 */ + return 0; + } } /* header length */ diff --git a/core/net/mac/frame802154.h b/core/net/mac/frame802154.h index 49ecbc81c..27d2041fa 100644 --- a/core/net/mac/frame802154.h +++ b/core/net/mac/frame802154.h @@ -140,10 +140,16 @@ typedef struct { uint8_t reserved; /**< 3 bit. Reserved bits */ } frame802154_scf_t; +typedef union { + uint32_t u32; + uint16_t u16[2]; + uint8_t u8[4]; +} frame802154_frame_counter_t; + /** \brief 802.15.4 Aux security header */ typedef struct { frame802154_scf_t security_control; /**< Security control bitfield */ - uint32_t frame_counter; /**< Frame counter, used for security */ + frame802154_frame_counter_t frame_counter; /**< Frame counter, used for security */ uint8_t key[9]; /**< The key itself, or an index to the key */ } frame802154_aux_hdr_t; diff --git a/core/net/mac/framer-802154.c b/core/net/mac/framer-802154.c index ce49a4dec..ef6aaf1f0 100644 --- a/core/net/mac/framer-802154.c +++ b/core/net/mac/framer-802154.c @@ -102,7 +102,9 @@ create_frame(int type, int do_create) /* Build the FCF. */ params.fcf.frame_type = FRAME802154_DATAFRAME; - params.fcf.security_enabled = 0; + if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { + params.fcf.security_enabled = 1; + } params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING); if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { params.fcf.ack_required = 0; @@ -111,8 +113,13 @@ create_frame(int type, int do_create) } params.fcf.panid_compression = 0; - /* Insert IEEE 802.15.4 (2003) version bit. */ - params.fcf.frame_version = FRAME802154_IEEE802154_2003; + /* Insert IEEE 802.15.4 (2006) version bits. */ + params.fcf.frame_version = FRAME802154_IEEE802154_2006; + + /* 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); /* Increment and set the data sequence number. */ if(!do_create) { @@ -227,6 +234,11 @@ parse(void) 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); + + /* Setting security-related attributes */ + 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]); PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); diff --git a/core/net/packetbuf.h b/core/net/packetbuf.h index c3efcb731..dfa99a92f 100644 --- a/core/net/packetbuf.h +++ b/core/net/packetbuf.h @@ -356,6 +356,9 @@ enum { PACKETBUF_ATTR_MAX_REXMIT, PACKETBUF_ATTR_NUM_REXMIT, PACKETBUF_ATTR_PENDING, + PACKETBUF_ATTR_SECURITY_LEVEL, + PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, + PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, /* Scope 2 attributes: used between end-to-end nodes. */ PACKETBUF_ATTR_HOPS,