F
Frédéric Perrin
Hello,
I've tried reading some networking code, and I see the following for IP
packets in OpenBSD:
/* Structure of an internet header, naked of options. */
struct ip {
#if _BYTE_ORDER == _LITTLE_ENDIAN
u_int ip_hl:4, /* header length */
ip_v:4; /* version */
#endif
#if _BYTE_ORDER == _BIG_ENDIAN
u_int ip_v:4, /* version */
ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
u_int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
u_int16_t ip_off; /* fragment offset field */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_int16_t ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
And in the function that processes incoming IP packets, the structure is
read as (I simplified somewhat):
void ipv4_input(struct mbuf *m)
{
struct ip *ip;
ipstat.ips_total++;
if (m->m_len < sizeof (struct ip)) {
ipstat.ips_toosmall++;
goto bad;
}
#define mtod(m,t) ((t)((m)->m_data))
ip = mtod(m, struct ip *);
if (ip->ip_v != IPVERSION) {
ipstat.ips_badvers++;
goto bad;
}
/* do re-assembly, process the IP fields... */
I am surprised by the lack of a `packed' attribute. I haven't seen a
`-fpack-struct' option in the Makefile's, either (but I'll admit to not
having looked very hard). How can we be sure that some architecture is
not going to require that, say, u_int16_t fields in a structure need to
be aligned on 64-bit boundaries because it is faster for the processor?
Doing so would make the structure not match the wire layout of packets
(and the input function would fail early at the length check).
The files I quoted above (ip.h and ip_input.c) are visible on the web at
<http://www.openbsd.org/cgi-bin/cvsweb/src/sys/netinet/>.
Regards,
I've tried reading some networking code, and I see the following for IP
packets in OpenBSD:
/* Structure of an internet header, naked of options. */
struct ip {
#if _BYTE_ORDER == _LITTLE_ENDIAN
u_int ip_hl:4, /* header length */
ip_v:4; /* version */
#endif
#if _BYTE_ORDER == _BIG_ENDIAN
u_int ip_v:4, /* version */
ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
u_int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
u_int16_t ip_off; /* fragment offset field */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_int16_t ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
And in the function that processes incoming IP packets, the structure is
read as (I simplified somewhat):
void ipv4_input(struct mbuf *m)
{
struct ip *ip;
ipstat.ips_total++;
if (m->m_len < sizeof (struct ip)) {
ipstat.ips_toosmall++;
goto bad;
}
#define mtod(m,t) ((t)((m)->m_data))
ip = mtod(m, struct ip *);
if (ip->ip_v != IPVERSION) {
ipstat.ips_badvers++;
goto bad;
}
/* do re-assembly, process the IP fields... */
I am surprised by the lack of a `packed' attribute. I haven't seen a
`-fpack-struct' option in the Makefile's, either (but I'll admit to not
having looked very hard). How can we be sure that some architecture is
not going to require that, say, u_int16_t fields in a structure need to
be aligned on 64-bit boundaries because it is faster for the processor?
Doing so would make the structure not match the wire layout of packets
(and the input function would fail early at the length check).
The files I quoted above (ip.h and ip_input.c) are visible on the web at
<http://www.openbsd.org/cgi-bin/cvsweb/src/sys/netinet/>.
Regards,