ROHC compression/decompression library
ipv4.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Didier Barvaux
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file ipv4.h
21  * @brief The IPv4 header
22  * @author Didier Barvaux <didier@barvaux.org>
23  */
24 
25 #ifndef ROHC_PROTOCOLS_IPV4_H
26 #define ROHC_PROTOCOLS_IPV4_H
27 
28 #include "rohc_utils.h"
29 
30 #include <stdint.h>
31 
32 #ifdef __KERNEL__
33 # include <endian.h>
34 #else
35 # include "config.h" /* for WORDS_BIGENDIAN */
36 #endif
37 
38 
39 /** The format to print an IPv4 address */
40 #define IPV4_ADDR_FORMAT \
41  "%02x%02x%02x%02x (%u.%u.%u.%u)"
42 
43 
44 /** The data to print an IPv4 address in raw format */
45 #define IPV4_ADDR_RAW(x) \
46  (x)[0], (x)[1], (x)[2], (x)[3], \
47  (x)[0], (x)[1], (x)[2], (x)[3]
48 
49 
50 /**
51  * @brief The IPv4 header
52  */
53 struct ipv4_hdr
54 {
55 #if WORDS_BIGENDIAN == 1
56  uint8_t version:4; /**< The IP version */
57  uint8_t ihl:4; /**< The IP Header Length (IHL) in 32-bit words */
58 #else
59  uint8_t ihl:4;
60  uint8_t version:4;
61 #endif
62 
63  /* service may be read as TOS or DSCP + ECN */
64  union
65  {
66  uint8_t tos; /**< The Type Of Service (TOS) */
67  uint8_t dscp_ecn; /**< The combined DSCP and ECN fields */
68  struct
69  {
70 #if WORDS_BIGENDIAN == 1
71  uint8_t dscp:6; /**< The Differentiated Services Code Point (DSCP) */
72  uint8_t ecn:2; /**< The Explicit Congestion Notification (ECN) */
73 #else
74  uint8_t ecn:2;
75  uint8_t dscp:6;
76 #endif
77  } __attribute__((packed));
78  } __attribute__((packed));
79 
80  uint16_t tot_len; /**< The Total Length (header + payload) */
81  uint16_t id; /**< The IDentification of the packet */
82 
83  /* IP flags and Fragment Offset may be read in 2 ways */
84  union
85  {
86  uint16_t frag_off; /**< The IP flags + Fragment Offset in 64-bit words */
87 #define IPV4_RF 0x8000 /**< Mask for reserved flag */
88 #define IPV4_DF 0x4000 /**< Mask for Don't Fragment (DF) flag */
89 #define IPV4_MF 0x2000 /**< Mask for More Fragments (MF) flag */
90 #define IPV4_OFFMASK 0x1fff /**< mask for Fragment Offset field */
91  struct
92  {
93 #if WORDS_BIGENDIAN == 1
94  uint8_t reserved:1; /**< A reserved flag */
95  uint8_t df:1; /**< The Don't Fragment (DF) flag */
96  uint8_t mf:1; /**< The More Fragments (MF) flag */
97  uint8_t frag_off1:5; /**< The Fragment Offset in 64-bit words (part 1) */
98 #else
99  uint8_t frag_off1:5;
100  uint8_t mf:1;
101  uint8_t df:1;
102  uint8_t reserved:1;
103 #endif
104  uint8_t frag_off2; /**< The Fragment Offset in 64-bit words (part 2) */
105  } __attribute__((packed));
106  } __attribute__((packed));
107 
108  uint8_t ttl; /**< The Time To Live (TTL) */
109  uint8_t protocol; /**< The Protocol of the next header */
110  uint16_t check; /**< The checksum over the IP header */
111  uint32_t saddr; /**< The source IP address */
112  uint32_t daddr; /**< The destination IP address */
113 
114  uint8_t options[0]; /**< The IP options start here */
115 
116 } __attribute__((packed));
117 
118 
119 /* compiler sanity check for C11-compliant compilers and GCC >= 4.6 */
120 #if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
121  (defined(__GNUC__) && defined(__GNUC_MINOR__) && \
122  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))))
123 _Static_assert(sizeof(struct ipv4_hdr) == 20,
124  "IPv4 header should exactly 20-byte long");
125 #endif
126 
127 
128 static inline bool ipv4_is_fragment(const struct ipv4_hdr *const ipv4_hdr)
129  __attribute__((warn_unused_result, nonnull(1), pure));
130 
131 /**
132  * @brief Whether the IPv4 packet is fragmented or not
133  *
134  * The IPv4 packet shall be at least sizeof(struct ipv4_hdr) long.
135  *
136  * @param ipv4 The IPv4 packet to check
137  * @return true if the IPv4 packet is a fragment,
138  * false if the IPv4 packet is not a fragment
139  */
140 static inline bool ipv4_is_fragment(const struct ipv4_hdr *const ipv4)
141 {
142  return !!((rohc_ntoh16(ipv4->frag_off) & (~IPV4_DF)) != 0);
143 }
144 
145 
146 #endif
147 
uint8_t options[0]
Definition: ipv4.h:114
uint8_t dscp_ecn
Definition: ipv4.h:67
static bool ipv4_is_fragment(const struct ipv4_hdr *const ipv4_hdr)
Whether the IPv4 packet is fragmented or not.
Definition: ipv4.h:140
uint8_t mf
Definition: ipv4.h:100
uint8_t ttl
Definition: ipv4.h:108
uint8_t df
Definition: ipv4.h:101
uint8_t frag_off2
Definition: ipv4.h:104
uint8_t ihl
Definition: ipv4.h:59
uint16_t check
Definition: ipv4.h:110
uint32_t saddr
Definition: ipv4.h:111
Miscellaneous utils for ROHC libraries.
uint16_t rohc_ntoh16(const uint16_t net16)
Convert a 16-bit short integer from network to host byte orders.
Definition: rohc_utils.c:71
uint16_t frag_off
Definition: ipv4.h:86
The IPv4 header.
Definition: ipv4.h:53
uint8_t reserved
Definition: ipv4.h:102
uint32_t daddr
Definition: ipv4.h:112
uint8_t frag_off1
Definition: ipv4.h:99
uint8_t ecn
Definition: ipv4.h:74
uint8_t protocol
Definition: ipv4.h:109
uint8_t version
Definition: ipv4.h:60
uint16_t tot_len
Definition: ipv4.h:80
uint16_t id
Definition: ipv4.h:81
uint8_t tos
Definition: ipv4.h:66
uint8_t dscp
Definition: ipv4.h:75
#define IPV4_DF
Definition: ipv4.h:88