Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Template/STL question - help please

44 views
Skip to first unread message

daku...@gmail.com

unread,
Sep 29, 2015, 2:20:20 AM9/29/15
to
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 ?

Any hints/suggestions would be greatly
appreciated -thanks in advance for your help.

Jorgen Grahn

unread,
Sep 29, 2015, 3:31:02 AM9/29/15
to
On Tue, 2015-09-29, daku...@gmail.com wrote:
> 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 ?

I don't understand that.

> 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)

It can be larger than that, and if you reassemble fragments
so you're looking at IP /datagrams/ rather than /packets/,
it can reach 65535 octets.

> 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.

Yes, that seems like a fair way to start.

> 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 ?

I don't understand what you're trying to say here. Which struct, and
what do you mean by a "template type"? Please explain better. It
seems like it could be an interesting question, once I understand it!

If you mean this:

std::vector<uint8_t> packet = something();
const struct ip_hdr* hdr = (struct ip_hdr*)&packet[0];

then I personally recommend against it. I always implement it as
functions which read octet by octet from the buffer:

struct in_addr src = src_of(packet);

That avoids endianness and alignment bugs, and forces you to consider
damaged packets and fragments.

> Any hints/suggestions would be greatly
> appreciated -thanks in advance for your help.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Robert Wessel

unread,
Sep 29, 2015, 4:18:57 AM9/29/15
to
On 29 Sep 2015 07:30:41 GMT, Jorgen Grahn <grahn...@snipabacken.se>
wrote:

>On Tue, 2015-09-29, daku...@gmail.com wrote:
>> 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 ?
>
>I don't understand that.
>
>> 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)
>
>It can be larger than that, and if you reassemble fragments
>so you're looking at IP /datagrams/ rather than /packets/,
>it can reach 65535 octets.


IPv6 jumbograms can be 4GiB.

Juha Nieminen

unread,
Sep 29, 2015, 4:24:32 AM9/29/15
to
daku...@gmail.com wrote:
> But now the
> question is, can I just go ahead and use
> the struct as template type

Why would you think you can't use a struct as a template type?

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Scott Lurndal

unread,
Sep 29, 2015, 9:33:37 AM9/29/15
to
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);
...
0 new messages