#ifndef cp_mme_h #define cp_mme_h /* Cesar project {{{ * * Copyright (C) 2008 Spidcom * * <<>> * * }}} */ /** * \file cp/mme.h * \brief Definition of the MME types. * \ingroup cp */ #include "lib/bitstream.h" #include "lib/blk.h" #include "cp/types.h" #include "cp/secu/secu.h" #include #include "mac/common/defs.h" #include "mmtypes.h" /** Payload encryption key select. */ enum cp_mme_peks_t { /** Encrypted using destination station DAK. */ CP_MME_PEKS_DAK, /** Encrypted using NMK known to station. */ CP_MME_PEKS_NMK, /** First TEK identifier. */ CP_MME_PEKS_TEK_MIN, /** Last TEK identifier. */ CP_MME_PEKS_TEK_MAX = 0xe, /** Number of TEK identifiers. */ CP_MME_PEKS_TEK_NB = CP_MME_PEKS_TEK_MAX - CP_MME_PEKS_TEK_MIN + 1, /** No encryption. */ CP_MME_PEKS_NONE = 0xf, /** Number of valid PEKS in a MME. */ CP_MME_PEKS_NB, /** Special value meaning no encapsulation in a * CM_ENCRYPTED_PAYLOAD.IND. */ CP_MME_PEKS_SPC_NOT_EMBEDDED = 0x100, }; typedef enum cp_mme_peks_t cp_mme_peks_t; /** MME peer (sender or recipient, depending of the MME direction). * * This structure contains information needed to send a MME to the right * destination. It is contained in the RX MME handle in order to respond to a * received MME. */ struct cp_mme_peer_t { /** Peer MAC address. */ mac_t mac; /* First Ethernet type found at offset ETH_TYPE_OFFSET */ u16 eth_type; /* 0 if the eth_type isn't a vlan */ u16 vlan_tci; /** Peer TEI, or 0xff if not TEI based. */ cp_tei_t tei; }; typedef struct cp_mme_peer_t cp_mme_peer_t; /** Relay information for the MME relay. */ struct cp_mme_relay_t { /** Mac address corresponding to the Final destination in the REQ and the * Original source for the IND. */ mac_t mac_fa; /** Final TEI. */ cp_tei_t ftei; }; typedef struct cp_mme_relay_t cp_mme_relay_t; /** Provide how the MME is encrypted. */ enum cp_mme_encrypt_t { CP_MME_RX_NOT_ENCRYPTED, CP_MME_RX_NEK_ENCRYPTED, CP_MME_RX_SOFT_ENCRYPTED, CP_MME_RX_NB }; /** MME handle for RX. */ struct cp_mme_rx_t { /** pointer to the received MME. */ u8 *p_mme; /** pointer to the MME's fragments. */ blk_t *p_frag; /** Pointer to the current frag. */ blk_t *p_frag_current; /** MMType the type of MME. */ uint mmtype; /** MMV of the message. Use for the CM_MME_ERROR.IND. */ uint mmv; /** size of the MME (including header). */ uint length; /** Peer information. */ cp_mme_peer_t peer; /** Payload encryption. */ cp_mme_peks_t peks; /** Protocol run information if present. */ cp_secu_protocol_run_t prun; /** Bitstream context. */ bitstream_t bitstream; /** CP context used by the destructor of the MME_rx_t message. */ cp_t *cp; /** IV or UUID. */ cp_key_t iv_uuid; /** Relay information. */ cp_mme_relay_t relay; /** Encrypt, True if the MME is encrypted.*/ enum cp_mme_encrypt_t encrypt; /** Jump environment. */ jmp_buf jump_env; }; typedef struct cp_mme_rx_t cp_mme_rx_t; /** MME handle for TX. */ struct cp_mme_tx_t { /** pointer to the Tx buffer. */ u8 *p_mme; /** Indicate if the MME is a relay. */ bool relay; /** size of the mme (including header). */ uint length; /** MMtype use to trace the MMe. */ uint mmtype; /** Peer information. */ cp_mme_peer_t peer; /** Final destination peer. Used only if the MME is relayed. */ cp_mme_peer_t final_peer; /** Payload encryption. */ cp_mme_peks_t peks; /** Protocol run information if present. */ cp_secu_protocol_run_t prun; /** use the correct bitstream. */ bitstream_t bitstream; /** CP context used by the destructor of the MME_tx_t message. */ cp_t *cp; /** Offset of the payload. */ uint payload_offset; /** RF Len. */ uint rf_len; /** IV or UUID. */ cp_key_t iv_uuid; /* FMI number of fragments. */ uint fmi_nbfrag; /* FMI Fn mi. */ uint fmi_nb; /* Fragment Messager Sequence Number. */ uint fmi_fmsn; }; typedef struct cp_mme_tx_t cp_mme_tx_t; /** Construct a cp_mme_peer_t for unicast to all STA. */ #define CP_MME_PEER_ALL_STA \ ((cp_mme_peer_t) { .mac = MAC_BROADCAST, .eth_type = HPAV_MTYPE_MME, \ .tei = MAC_TEI_MULTI_UNICAST }) /** Construct a cp_mme_peer_t from a MAC address and a TEI. */ #define CP_MME_PEER(mac_, tei_) \ ((cp_mme_peer_t) { .mac = mac_, .eth_type = HPAV_MTYPE_MME, \ .vlan_tci = 0, .tei = tei_ }) /** * Compare two cp_mme_peer_t. * \param p1 first structure * \param p2 second structure * \return true if they match. * * This only works for MAC or MAC+TEI peer structures, ignoring VLAN tag. */ extern inline bool cp_mme_peer_cmp (cp_mme_peer_t *p1, cp_mme_peer_t *p2) { /* Check parameters. */ dbg_assert (p1); dbg_assert (p2); return p1->mac == p2->mac && p1->tei == p2->tei; } #endif /* cp_mme_h */