00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef ROHC_PROTOCOLS_IPV4_H
00026 #define ROHC_PROTOCOLS_IPV4_H
00027
00028 #include "rohc_utils.h"
00029
00030 #include <stdint.h>
00031
00032 #ifdef __KERNEL__
00033 # include <endian.h>
00034 #else
00035 # include "config.h"
00036 #endif
00037
00038
00039
00040 #define IPV4_ADDR_FORMAT \
00041 "%02x%02x%02x%02x (%u.%u.%u.%u)"
00042
00043
00044
00045 #define IPV4_ADDR_RAW(x) \
00046 (x)[0], (x)[1], (x)[2], (x)[3], \
00047 (x)[0], (x)[1], (x)[2], (x)[3]
00048
00049
00050
00051
00052
00053 struct ipv4_hdr
00054 {
00055 #if WORDS_BIGENDIAN == 1
00056 uint8_t version:4;
00057 uint8_t ihl:4;
00058 #else
00059 uint8_t ihl:4;
00060 uint8_t version:4;
00061 #endif
00062
00063
00064 union
00065 {
00066 uint8_t tos;
00067 uint8_t dscp_ecn;
00068 struct
00069 {
00070 #if WORDS_BIGENDIAN == 1
00071 uint8_t dscp:6;
00072 uint8_t ecn:2;
00073 #else
00074 uint8_t ecn:2;
00075 uint8_t dscp:6;
00076 #endif
00077 } __attribute__((packed));
00078 } __attribute__((packed));
00079
00080 uint16_t tot_len;
00081 uint16_t id;
00082
00083
00084 union
00085 {
00086 uint16_t frag_off;
00087 #define IPV4_RF 0x8000
00088 #define IPV4_DF 0x4000
00089 #define IPV4_MF 0x2000
00090 #define IPV4_OFFMASK 0x1fff
00091 struct
00092 {
00093 #if WORDS_BIGENDIAN == 1
00094 uint8_t reserved:1;
00095 uint8_t df:1;
00096 uint8_t mf:1;
00097 uint8_t frag_off1:5;
00098 #else
00099 uint8_t frag_off1:5;
00100 uint8_t mf:1;
00101 uint8_t df:1;
00102 uint8_t reserved:1;
00103 #endif
00104 uint8_t frag_off2;
00105 } __attribute__((packed));
00106 } __attribute__((packed));
00107
00108 uint8_t ttl;
00109 uint8_t protocol;
00110 uint16_t check;
00111 uint32_t saddr;
00112 uint32_t daddr;
00113
00114 uint8_t options[0];
00115
00116 } __attribute__((packed));
00117
00118
00119
00120 #if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
00121 (defined(__GNUC__) && defined(__GNUC_MINOR__) && \
00122 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))))
00123 _Static_assert(sizeof(struct ipv4_hdr) == 20,
00124 "IPv4 header should exactly 20-byte long");
00125 #endif
00126
00127
00128 static inline bool ipv4_is_fragment(const struct ipv4_hdr *const ipv4_hdr)
00129 __attribute__((warn_unused_result, nonnull(1), pure));
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 static inline bool ipv4_is_fragment(const struct ipv4_hdr *const ipv4)
00141 {
00142 return !!((rohc_ntoh16(ipv4->frag_off) & (~IPV4_DF)) != 0);
00143 }
00144
00145
00146 #endif
00147