void ieee802154_retrieveHeader(OpenQueueEntry_t* msg, ieee802154_header_iht* ieee802514_header) { uint8_t temp_8b; ieee802514_header->valid=FALSE; ieee802514_header->headerLength = 0; //fcf, byte 1 if (ieee802514_header->headerLength>msg->length) { return; } temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ieee802514_header->frameType = (temp_8b >> IEEE154_FCF_FRAME_TYPE ) & 0x07;//3b ieee802514_header->securityEnabled = (temp_8b >> IEEE154_FCF_SECURITY_ENABLED) & 0x01;//1b ieee802514_header->framePending = (temp_8b >> IEEE154_FCF_FRAME_PENDING ) & 0x01;//1b ieee802514_header->ackRequested = (temp_8b >> IEEE154_FCF_ACK_REQ ) & 0x01;//1b ieee802514_header->panIDCompression = (temp_8b >> IEEE154_FCF_INTRAPAN ) & 0x01;//1b ieee802514_header->headerLength += 1; //fcf, byte 2 if (ieee802514_header->headerLength>msg->length) { return; } temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); switch ( (temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03 ) { case IEEE154_ADDR_NONE: ieee802514_header->dest.type = ADDR_NONE; break; case IEEE154_ADDR_SHORT: ieee802514_header->dest.type = ADDR_16B; break; case IEEE154_ADDR_EXT: ieee802514_header->dest.type = ADDR_64B; break; default: openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, (errorparameter_t)1, (errorparameter_t)(temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03); break; } switch ( (temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03 ) { case IEEE154_ADDR_NONE: ieee802514_header->src.type = ADDR_NONE; break; case IEEE154_ADDR_SHORT: ieee802514_header->src.type = ADDR_16B; break; case IEEE154_ADDR_EXT: ieee802514_header->src.type = ADDR_64B; break; default: openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, (errorparameter_t)2, (errorparameter_t)(temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03); break; } ieee802514_header->headerLength += 1; //sequenceNumber if (ieee802514_header->headerLength>msg->length) { return; } ieee802514_header->dsn = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ieee802514_header->headerLength += 1; //panID if (ieee802514_header->headerLength>msg->length) { return; } packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_PANID, &ieee802514_header->panid, LITTLE_ENDIAN); ieee802514_header->headerLength += 2; //dest if (ieee802514_header->headerLength>msg->length) { return; } switch (ieee802514_header->dest.type) { case ADDR_NONE: break; case ADDR_16B: packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_16B, &ieee802514_header->dest, LITTLE_ENDIAN); ieee802514_header->headerLength += 2; // poipoi: spoofing 64-bit destination address // if (idmanager_isMyAddress(&ieee802514_header->dest)==TRUE) { // memcpy(&ieee802514_header->dest,idmanager_getMyID(ADDR_64B),sizeof(open_addr_t)); // } else if (packetfunctions_isBroadcastMulticast(&ieee802514_header->dest)==FALSE) { // ieee802514_header->dest.addr_64b[7] = ieee802514_header->dest.addr_64b[1]; // ieee802514_header->dest.addr_64b[6] = ieee802514_header->dest.addr_64b[0]; // ieee802514_header->dest.addr_64b[5] = 0x00; // ieee802514_header->dest.addr_64b[4] = 0x00; // ieee802514_header->dest.addr_64b[3] = 0x00; // ieee802514_header->dest.addr_64b[2] = 0x00; // ieee802514_header->dest.addr_64b[1] = 0x00; // ieee802514_header->dest.addr_64b[0] = 0x00; // ieee802514_header->dest.type = ADDR_64B; // } if (ieee802514_header->headerLength>msg->length) { return; } break; case ADDR_64B: packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_64B, &ieee802514_header->dest, LITTLE_ENDIAN); ieee802514_header->headerLength += 8; if (ieee802514_header->headerLength>msg->length) { return; } break; } //src switch (ieee802514_header->src.type) { case ADDR_NONE: break; case ADDR_16B: packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_16B, &ieee802514_header->src, LITTLE_ENDIAN); ieee802514_header->headerLength += 2; // poipoi: spoofing 64-bit source address // ieee802514_header->src.addr_64b[7] = ieee802514_header->src.addr_64b[1]; // ieee802514_header->src.addr_64b[6] = ieee802514_header->src.addr_64b[0]; // ieee802514_header->src.addr_64b[5] = 0x00; // ieee802514_header->src.addr_64b[4] = 0x00; // ieee802514_header->src.addr_64b[3] = 0x00; // ieee802514_header->src.addr_64b[2] = 0x00; // ieee802514_header->src.addr_64b[1] = 0x00; // ieee802514_header->src.addr_64b[0] = 0x00; // ieee802514_header->src.type = ADDR_64B; if (ieee802514_header->headerLength>msg->length) { return; } break; case ADDR_64B: packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_64B, &ieee802514_header->src, LITTLE_ENDIAN); ieee802514_header->headerLength += 8; if (ieee802514_header->headerLength>msg->length) { return; } break; } // if you reach this, the header is valid ieee802514_header->valid=TRUE; }
/** \brief Retreieve the IEEE802.15.4 MAC header from a (just received) packet. Note We are writing the fields from the begnning of the header to the end. \param[in,out] msg The message just received. \param[out] ieee802514_header The internal header to write the data to. */ void ieee802154_retrieveHeader(OpenQueueEntry_t* msg, ieee802154_header_iht* ieee802514_header) { uint8_t temp_8b; // by default, let's assume the header is not valid, in case we leave this // function because the packet ends up being shorter than the header. ieee802514_header->valid=FALSE; ieee802514_header->headerLength = 0; // fcf, byte 1 if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ieee802514_header->frameType = (temp_8b >> IEEE154_FCF_FRAME_TYPE ) & 0x07;//3b ieee802514_header->securityEnabled = (temp_8b >> IEEE154_FCF_SECURITY_ENABLED) & 0x01;//1b ieee802514_header->framePending = (temp_8b >> IEEE154_FCF_FRAME_PENDING ) & 0x01;//1b ieee802514_header->ackRequested = (temp_8b >> IEEE154_FCF_ACK_REQ ) & 0x01;//1b ieee802514_header->panIDCompression = (temp_8b >> IEEE154_FCF_INTRAPAN ) & 0x01;//1b ieee802514_header->headerLength += 1; // fcf, byte 2 if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); //poipoi xv IE list present ieee802514_header->ieListPresent = (temp_8b >> IEEE154_FCF_IELIST_PRESENT ) & 0x01;//1b ieee802514_header->frameVersion = (temp_8b >> IEEE154_FCF_FRAME_VERSION ) & 0x03;//2b if (ieee802514_header->ieListPresent==TRUE && ieee802514_header->frameVersion!=IEEE154_FRAMEVERSION){ return; //invalid packet accordint to p.64 IEEE15.4e } switch ( (temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03 ) { case IEEE154_ADDR_NONE: ieee802514_header->dest.type = ADDR_NONE; break; case IEEE154_ADDR_SHORT: ieee802514_header->dest.type = ADDR_16B; break; case IEEE154_ADDR_EXT: ieee802514_header->dest.type = ADDR_64B; break; default: openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, (errorparameter_t)1, (errorparameter_t)(temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03); return; // this is an invalid packet, return } switch ( (temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03 ) { case IEEE154_ADDR_NONE: ieee802514_header->src.type = ADDR_NONE; break; case IEEE154_ADDR_SHORT: ieee802514_header->src.type = ADDR_16B; break; case IEEE154_ADDR_EXT: ieee802514_header->src.type = ADDR_64B; break; default: openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, (errorparameter_t)2, (errorparameter_t)(temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03); return; // this is an invalid packet, return } ieee802514_header->headerLength += 1; // sequenceNumber if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ieee802514_header->dsn = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ieee802514_header->headerLength += 1; // panID if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_PANID, &ieee802514_header->panid, OW_LITTLE_ENDIAN); ieee802514_header->headerLength += 2; // dest if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! switch (ieee802514_header->dest.type) { case ADDR_NONE: break; case ADDR_16B: packetfunctions_readAddress( ((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_16B, &ieee802514_header->dest, OW_LITTLE_ENDIAN ); ieee802514_header->headerLength += 2; if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! break; case ADDR_64B: packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_64B, &ieee802514_header->dest, OW_LITTLE_ENDIAN); ieee802514_header->headerLength += 8; if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! break; // no need for a default, since case would have been caught above } //src switch (ieee802514_header->src.type) { case ADDR_NONE: break; case ADDR_16B: packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_16B, &ieee802514_header->src, OW_LITTLE_ENDIAN); ieee802514_header->headerLength += 2; if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! break; case ADDR_64B: packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ADDR_64B, &ieee802514_header->src, OW_LITTLE_ENDIAN); ieee802514_header->headerLength += 8; if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! break; // no need for a default, since case would have been caught above } if (ieee802514_header->ieListPresent==TRUE && ieee802514_header->frameVersion!=IEEE154_FRAMEVERSION){ return; //invalid packet accordint to p.64 IEEE15.4e } // apply topology filter if (topology_isAcceptablePacket(ieee802514_header)==FALSE) { // the topology filter does accept this packet, return return; } // if you reach this, the header is valid ieee802514_header->valid=TRUE; }
void retrieve_AuxiliarySecurityHeader(OpenQueueEntry_t* msg, ieee802154_header_iht* tempheader){ //a check if security is enabled, for me it not useful. If I'm here, security is enabled. // if(tempheader->securityEnabled == TRUE){ // msg->l2_security = IEEE154_SEC_YES_SECURITY; // } // if(msg->l2_security==FALSE){ // return; // } uint8_t temp8b; //b check if 802.15.4 header is valid //if the header is not valid, I'm not here.. //c retrieve the Security Control field //1byte, Security Control Field temp8b = *((uint8_t*)(msg->payload)+tempheader->headerLength); msg->l2_securityLevel = (temp8b >> ASH_SCF_SECURITY_LEVEL)& 0x07;//3b authLengthChecking(msg->l2_securityLevel); msg->l2_authenticationLength = authlen; /*if(securityLevel ==0){ return; }*/ //retrieve the KeyIdMode field msg->l2_keyIdMode = (temp8b >> ASH_SCF_KEY_IDENTIFIER_MODE)& 0x03;//2b tempheader->headerLength = tempheader->headerLength+1; //retrieve the FrameCounter field and control it is not in overflow //Frame Counter field, //l uint8_t temp,i; temp = 0; msg->l2_frameCounter = 0; for(i=0;i<3;i++){ temp = *((uint8_t*)(msg->payload)+tempheader->headerLength); msg->l2_frameCounter |= temp; msg->l2_frameCounter = msg->l2_frameCounter <<8; tempheader->headerLength = tempheader->headerLength+1; } temp = *((uint8_t*)(msg->payload)+tempheader->headerLength); msg->l2_frameCounter |= temp; tempheader->headerLength = tempheader->headerLength+1; if(msg->l2_frameCounter == (0xffffffffffffffff)){ return; // frame counter overflow } //retrieve the Key Identifier field //Key Identifier Field, variable length /*switch(keyIdMode){ case (IEEE154_ADDR_NONE): break; case (IEEE154_ADDR_SHORT): packetfunctions_readAddress( ((uint8_t*)(msg->payload)+tempheader->headerLength), ADDR_16B, &keySource, OW_LITTLE_ENDIAN); tempheader->headerLength = tempheader->headerLength+2; break; case(IEEE154_ADDR_EXT): packetfunctions_readAddress( ((uint8_t*)(msg->payload)+tempheader->headerLength), ADDR_64B, &keySource, OW_LITTLE_ENDIAN); tempheader->headerLength = tempheader->headerLength+8; break; }*/ //in our impl, keyIdMode = 3 packetfunctions_readAddress( ((uint8_t*)(msg->payload)+tempheader->headerLength), ADDR_64B, &msg->l2_keySource, OW_LITTLE_ENDIAN); tempheader->headerLength = tempheader->headerLength+8; temp8b = *((uint8_t*)(msg->payload)+tempheader->headerLength); msg->l2_keyIndex = (temp8b); tempheader->headerLength = tempheader->headerLength+1; }