daku...@gmail.com writes:
>Could some C++ guru please help ? May be
>my question is stupid, so pardon me.
>
>Can STL have a built-in method to handle
>ANY user defined data type ? To be specific,
>suppose I want to model a TCP/IP packet
>as a struct. As the memebers of a TCP/IP
>packet are in reality are byte arrays,
>I can visualize the entire packet as a
>large(1500) array of bytes, with the first
>so many bytes making up the source address
>and so on. So, I can use a vector of bytes
>to model a TCP/IP packet. But now the
>question is, can I just go ahead and use
>the struct as template type(like for example
>a built-in type as float, int etc.,) instead
>of first taking out the contents of the same
>TCP/IP packet and putting them into a byte
>vector ?
namespace net {
/**
* Layer 2 (Ethernet) Header
*/
struct s_ethernet {
uint8_t e_dest_mac[6];
uint8_t e_source_mac[6];
uint16_t e_ethertype;
uint16_t get_ethertype(void) { return be16toh(e_ethertype); }
} PACKED;
/**
* Layer 2 (Ethernet) Header with 802.1Q VLAN tag.
*/
struct s_802_1q_ethernet {
uint8_t e_dest_mac[6];
uint8_t e_source_mac[6];
uint32_t e_802_1q_tag;
uint16_t e_ethertype;
uint16_t get_ethertype(void) { return be16toh(e_ethertype); }
} PACKED;
/**
* Layer 3 IPv4 Header
*/
struct s_ipv4 {
#if __BYTE_ORDER == __BIG_ENDIAN
uint8_t i_version:4,
i_ihl:4;
#else
uint8_t i_ihl:4,
i_version:4;
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
uint8_t i_dscp:6,
i_ecn:2;
#else
uint8_t i_ecn:2,
i_dscp:6;
#endif
uint16_t i_length;
uint16_t i_identification;
#if __BYTE_ORDER == __BIG_ENDIAN
uint16_t i_flags:3,
i_frag_offset:13;
#else
uint16_t i_frag_offset:13,
i_flags:3;
#endif
uint8_t i_ttl;
uint8_t i_proto;
uint16_t i_checksum;
uint32_t i_source;
uint32_t i_dest;
uint16_t get_checksum(void) { return be16toh(i_checksum); }
uint32_t get_source(void) { return be32toh(i_source); }
uint32_t get_dest(void) { return be32toh(i_dest); }
} PACKED;
// And so forth for ipv6 header and extension headers and l4 headers
// such as TCP, UDP, SCTP, GENEVE, VXLAN, et. al.
};
uint8_t *packet; // Pointer to first byte of packet
net::s_ethernet *ep = reinterpret_cast<net::s_ethernet *>(packet);
size_t l2len = sizeof(net::s_ethernet);
if (ep->get_ethertype() == ETHERTYPES::ET_802_1Q_VLAN) {
net::s_802_1q_ethernet *ep802 = reinterpret_cast<net::s_802_1q_ethernet *>(packet);
l2len += sizeof(uint32_t);
... Handle vlan tag
}
net::s_ipv4 *ip = reinterpet_cast<net::s_ipv4 *>(packet + l2len);
...