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
00026
00027
00028
00038 #ifndef LIBNET_IP_HEADER_H_
00039 #define LIBNET_IP_HEADER_H_
00040
00041 #include <byteorder.h>
00042 #include <sys/types.h>
00043
00047 #define IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length) \
00048 ((((length) / 8U) & 0x1f00) >> 8)
00049
00053 #define IP_COMPUTE_FRAGMENT_OFFSET_LOW(length) \
00054 (((length) / 8U) & 0xff)
00055
00059 #define IP_COMPUTE_HEADER_LENGTH(length) \
00060 ((uint8_t) ((length) / 4U))
00061
00065 #define IP_FRAGMENT_OFFSET(header) \
00066 (((GET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header) << 8) + \
00067 (header)->fragment_offset_low) * 8U)
00068
00072 #define IP_HEADER_CHECKSUM(header) \
00073 (htons(ip_checksum((uint8_t *) (header), IP_HEADER_LENGTH(header))))
00074
00078 #define IP_HEADER_DATA_LENGTH(header) \
00079 (IP_TOTAL_LENGTH(header) - IP_HEADER_LENGTH(header))
00080
00084 #define IP_HEADER_LENGTH(header) \
00085 (GET_IP_HEADER_LENGTH(header) * 4U)
00086
00090 #define IP_TOTAL_LENGTH(header) \
00091 ntohs((header)->total_length)
00092
00095
00097 #define IPFLAG_FRAGMENT_SHIFT 1
00098
00100 #define IPFLAG_FRAGMENTED_SHIFT 0
00101
00105 #define IPFLAG_DONT_FRAGMENT (0x1 << IPFLAG_FRAGMENT_SHIFT)
00106
00110 #define IPFLAG_LAST_FRAGMENT (0x0 << IPFLAG_FRAGMENTED_SHIFT)
00111
00115 #define IPFLAG_MAY_FRAGMENT (0x0 << IPFLAG_FRAGMENT_SHIFT)
00116
00120 #define IPFLAG_MORE_FRAGMENTS (0x1 << IPFLAG_FRAGMENTED_SHIFT)
00121
00127 typedef struct ip_header ip_header_t;
00128
00132 typedef struct ip_option ip_option_t;
00133
00137 typedef struct ipv4_pseudo_header ipv4_pseudo_header_t;
00138
00144 struct ip_header {
00145 uint8_t vhl;
00146
00147 #define GET_IP_HEADER_VERSION(header) \
00148 (((header)->vhl & 0xf0) >> 4)
00149 #define SET_IP_HEADER_VERSION(header, version) \
00150 ((header)->vhl = \
00151 ((version & 0x0f) << 4) | ((header)->vhl & 0x0f))
00152
00153 #define GET_IP_HEADER_LENGTH(header) \
00154 ((header)->vhl & 0x0f)
00155 #define SET_IP_HEADER_LENGTH(header, length) \
00156 ((header)->vhl = \
00157 (length & 0x0f) | ((header)->vhl & 0xf0))
00158
00159 uint8_t tos;
00160 uint16_t total_length;
00161 uint16_t identification;
00162
00163 uint8_t ffoh;
00164
00165 #define GET_IP_HEADER_FLAGS(header) \
00166 (((header)->ffoh & 0xe0) >> 5)
00167 #define SET_IP_HEADER_FLAGS(header, flags) \
00168 ((header)->ffoh = \
00169 ((flags & 0x07) << 5) | ((header)->ffoh & 0x1f))
00170
00171 #define GET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header) \
00172 ((header)->ffoh & 0x1f)
00173 #define SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header, fragment_offset_high) \
00174 ((header)->ffoh = \
00175 (fragment_offset_high & 0x1f) | ((header)->ffoh & 0xe0))
00176
00177 uint8_t fragment_offset_low;
00178 uint8_t ttl;
00179 uint8_t protocol;
00180 uint16_t header_checksum;
00181 uint32_t source_address;
00182 uint32_t destination_address;
00183 } __attribute__ ((packed));
00184
00190 struct ip_option {
00191 uint8_t type;
00192 uint8_t length;
00193 uint8_t pointer;
00194
00195 uint8_t of;
00196
00197 #define GET_IP_OPTION_OVERFLOW(option) \
00198 (((option)->of & 0xf0) >> 4)
00199 #define SET_IP_OPTION_OVERFLOW(option, overflow) \
00200 ((option)->of = \
00201 ((overflow & 0x0f) << 4) | ((option)->of & 0x0f))
00202
00203 #define GET_IP_OPTION_FLAGS(option) \
00204 ((option)->of & 0x0f)
00205 #define SET_IP_OPTION_FLAGS(option, flags) \
00206 ((option)->of = \
00207 (flags & 0x0f) | ((option)->of & 0xf0))
00208
00209 } __attribute__ ((packed));
00210
00212 struct ipv4_pseudo_header {
00213 uint32_t source_address;
00214 uint32_t destination_address;
00215 uint8_t reserved;
00216 uint8_t protocol;
00217 uint16_t data_length;
00218 } __attribute__ ((packed));
00219
00220 #endif
00221