ROHC compression/decompression library
ip.h
Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 2 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * This program is distributed in the hope that it will be useful,
00008  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  * GNU General Public License for more details.
00011  *
00012  * You should have received a copy of the GNU General Public License
00013  * along with this program; if not, write to the Free Software
00014  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  */
00016 
00023 #ifndef IP_H
00024 #define IP_H
00025 
00026 #include <netinet/ip.h>
00027 #include <netinet/ip6.h>
00028 #include <string.h>
00029 
00030 
00031 /*
00032  * Next header codes for IPv6 extensions:
00033  */
00034 
00036 #define IPV6_EXT_HOP_BY_HOP 0
00037 
00038 #define IPV6_EXT_DESTINATION 60
00039 
00040 #define IPV6_EXT_ROUTING 43
00041 
00042 #define IPV6_EXT_AUTH 51
00043 
00044 
00046 typedef enum
00047 {
00049         IPV4 = 4,
00051         IPV6 = 6,
00053         IP_UNKNOWN,
00054 } ip_version;
00055 
00056 
00061 struct ip_packet
00062 {
00064         ip_version  version;
00065 
00067         union
00068         {
00070                 struct iphdr v4;
00072                 struct ip6_hdr v6;
00073         } header;
00074 
00076         unsigned char *data;
00077 
00079         unsigned int size;
00080 };
00081 
00082 /* AH header */
00083 struct ip6_ahhdr
00084 {
00086         uint8_t   ip6ah_nxt; 
00088         uint8_t   ip6ah_len;
00090         uint16_t  ip6ah_reserved;  
00092         uint32_t  ip6ah_secur;     
00094         uint32_t  ip6ah_sn;      
00095         /* followed by Authentication Data */
00096 };
00097                     
00098 
00099 /*
00100  * Generic IP macros:
00101  */
00102 
00104 #define IP_GET_16_SUBFIELD(field, bitmask, offset) \
00105         ((ntohs(field) & (bitmask)) >> (offset))
00106 
00108 #define IP_GET_32_SUBFIELD(field, bitmask, offset) \
00109         ((ntohl(field) & (bitmask)) >> (offset))
00110 
00112 #define IP_SET_16_SUBFIELD(field, bitmask, offset, value) \
00113         (field) = (((field) & htons(~(bitmask))) | htons(((value) << (offset)) & (bitmask)))
00114 
00116 #define IP_SET_32_SUBFIELD(field, bitmask, offset, value) \
00117         (field) = (((field) & htonl(~(bitmask))) | htonl(((value) << (offset)) & (bitmask)))
00118 
00119 
00120 /*
00121  * IPv4 definitions & macros:
00122  */
00123 
00125 #define IPV4_DF_OFFSET  14
00126 
00128 #define IPV4_GET_DF(ip4) \
00129         IP_GET_16_SUBFIELD((ip4).frag_off, IP_DF, IPV4_DF_OFFSET)
00130 
00132 #define IPV4_SET_DF(ip4, value) \
00133         IP_SET_16_SUBFIELD((ip4)->frag_off, IP_DF, IPV4_DF_OFFSET, (value))
00134 
00135 
00136 /*
00137  * IPv6 definitions & macros:
00138  */
00139 
00141 #define IPV6_VERSION_MASK  0xf0000000
00142 
00143 #define IPV6_VERSION_OFFSET  28
00144 
00146 #define IPV6_TC_MASK  0x0ff00000
00147 
00148 #define IPV6_TC_OFFSET  20
00149 
00151 #define IPV6_FLOW_LABEL_MASK  0x000fffff
00152 
00154 #define IPV6_GET_VERSION(ip6) \
00155         IP_GET_32_SUBFIELD((ip6).ip6_flow, IPV6_VERSION_MASK, IPV6_VERSION_OFFSET)
00156 
00158 #define IPV6_SET_VERSION(ip6, value) \
00159         IP_SET_32_SUBFIELD((ip6)->ip6_flow, IPV6_VERSION_MASK, IPV6_VERSION_OFFSET, (value))
00160 
00162 #define IPV6_GET_TC(ip6) \
00163         IP_GET_32_SUBFIELD((ip6).ip6_flow, IPV6_TC_MASK, IPV6_TC_OFFSET)
00164 
00166 #define IPV6_SET_TC(ip6, value) \
00167         IP_SET_32_SUBFIELD((ip6)->ip6_flow, IPV6_TC_MASK, IPV6_TC_OFFSET, (value))
00168 
00170 #define IPV6_GET_FLOW_LABEL(ip6) \
00171         IP_GET_32_SUBFIELD((ip6).ip6_flow, IPV6_FLOW_LABEL_MASK, 0)
00172 
00174 #define IPV6_SET_FLOW_LABEL(ip6, value) \
00175         IP_SET_32_SUBFIELD((ip6)->ip6_flow, IPV6_FLOW_LABEL_MASK, 0, (value))
00176 
00178 #define IPV6_ADDR_FORMAT \
00179         "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x"
00180 
00182 #define IPV6_ADDR(x) \
00183         (x)->s6_addr[0], (x)->s6_addr[1], (x)->s6_addr[2], (x)->s6_addr[3], \
00184         (x)->s6_addr[4], (x)->s6_addr[5], (x)->s6_addr[6], (x)->s6_addr[7], \
00185         (x)->s6_addr[8], (x)->s6_addr[9], (x)->s6_addr[10], (x)->s6_addr[11], \
00186         (x)->s6_addr[12], (x)->s6_addr[13], (x)->s6_addr[14], (x)->s6_addr[15]
00187 
00189 #define IPV6_ADDR_CMP(x, y) \
00190         ((x)->s6_addr32[0] == (y)->s6_addr32[0] && \
00191          (x)->s6_addr32[1] == (y)->s6_addr32[1] && \
00192          (x)->s6_addr32[2] == (y)->s6_addr32[2] && \
00193          (x)->s6_addr32[3] == (y)->s6_addr32[3])
00194 
00195 
00196 /*
00197  * Inline functions
00198  */
00199 
00206 static inline uint16_t swab16(uint16_t value)
00207 {
00208         return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
00209 }
00210 
00211 
00212 /*
00213  * Function prototypes.
00214  */
00215 
00216 /* Generic functions */
00217 
00218 int ip_create(struct ip_packet *ip, unsigned char *packet, unsigned int size);
00219 int ip_get_inner_packet(struct ip_packet outer, struct ip_packet *inner);
00220 void ip_new(struct ip_packet *ip, ip_version version);
00221 
00222 unsigned char * ip_get_raw_data(struct ip_packet ip);
00223 unsigned char *ip_get_next_header(const struct ip_packet *ip,
00224                                   uint8_t *type);
00225 unsigned char *ip_get_next_layer(const struct ip_packet *ip);
00226 unsigned char *ip_get_next_ext_header_from_ip(const struct ip_packet *ip,
00227                                               uint8_t *type);
00228 unsigned char *ip_get_next_ext_header_from_ext(const unsigned char *ext,
00229                                                uint8_t *type);
00230 
00231 unsigned int ip_get_totlen(struct ip_packet ip);
00232 unsigned int ip_get_hdrlen(struct ip_packet ip);
00233 unsigned int ip_get_plen(struct ip_packet ip);
00234 
00235 int ip_is_fragment(struct ip_packet ip);
00236 ip_version ip_get_version(struct ip_packet ip);
00237 unsigned int ip_get_protocol(struct ip_packet ip);
00238 unsigned int ext_get_protocol(unsigned char * ext);
00239 unsigned int ip_get_tos(struct ip_packet ip);
00240 unsigned int ip_get_ttl(struct ip_packet ip);
00241 
00242 void ip_set_protocol(struct ip_packet *ip, uint8_t value);
00243 void ip_set_tos(struct ip_packet *ip, uint8_t value);
00244 void ip_set_ttl(struct ip_packet *ip, uint8_t value);
00245 void ip_set_saddr(struct ip_packet *ip, const unsigned char *value);
00246 void ip_set_daddr(struct ip_packet *ip, const unsigned char *value);
00247 
00248 /* IPv4 specific functions */
00249 
00250 const struct iphdr * ipv4_get_header(const struct ip_packet *const ip);
00251 int ipv4_get_id(struct ip_packet ip);
00252 int ipv4_get_id_nbo(struct ip_packet ip, unsigned int nbo);
00253 int ipv4_get_df(struct ip_packet ip);
00254 uint32_t ipv4_get_saddr(struct ip_packet ip);
00255 uint32_t ipv4_get_daddr(struct ip_packet ip);
00256 
00257 void ipv4_set_id(struct ip_packet *ip, int value);
00258 void ipv4_set_df(struct ip_packet *ip, int value);
00259 
00260 /* IPv6 specific functions */
00261 
00262 const struct ip6_hdr * ipv6_get_header(const struct ip_packet *const ip);
00263 uint32_t ipv6_get_flow_label(struct ip_packet ip);
00264 struct in6_addr * ipv6_get_saddr(struct ip_packet *ip);
00265 struct in6_addr * ipv6_get_daddr(struct ip_packet *ip);
00266 void ipv6_set_flow_label(struct ip_packet *ip, uint32_t value);
00267 unsigned short ip_get_extension_size(unsigned char *ext);
00268 unsigned short ip_get_total_extension_size(struct ip_packet ip);
00269 
00270 /* Private functions (do not use directly) */
00271 int get_ip_version(const unsigned char *packet,
00272                    unsigned int size,
00273                    ip_version *version);
00274 
00275 
00276 #endif