00001 /** @file ip_addr.h 00002 * 00003 * Generic IP address representation and conversion utilities. 00004 * 00005 * @author Jason Vas Dias <jvdias@redhat.com> 00006 */ 00007 /* Copyright(C) Jason Vas Dias <jvdias@redhat.com> Red Hat Inc. May 2006 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation at 00012 * http://www.fsf.org/licensing/licenses/gpl.txt 00013 * and included in this software distribution as the "LICENSE" file. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 */ 00020 #ifndef IP_ADDR_H 00021 #define IP_ADDR_H 00022 00023 #include <sys/types.h> 00024 #include <sys/socket.h> 00025 #include <netinet/in.h> 00026 #include <arpa/inet.h> 00027 #include <stdint.h> 00028 #ifndef AF_LLC 00029 #define AF_LLC 26 00030 #endif 00031 #ifndef __LLC_SOCK_SIZE__ 00032 #define __LLC_SOCK_SIZE__ 16 00033 #endif 00034 00035 /** 00036 * @addtogroup IP 00037 * @{ 00038 */ 00039 /** 00040 * IP addresses structure big enough for an IPv6 address by default 00041 * (minimum size == sizeof(struct sockaddr_in6)). 00042 * Compatible with all of struct sockaddr, struct sockaddr_in, and 00043 * struct sockaddr_in6. 00044 * If used to represent an IPv4 or IPv6 address, 00045 * (&(s->sin_addr) == &(s->sin6_addr) == &(s->sa_pad)) . 00046 * If used to represent an AF_LLC address (ethernet), 00047 * &(((ip_addr_t*)s)->sa_data) == &(((struct sockaddr*)s)->sa_data). 00048 * 00049 */ 00050 typedef struct ip_sockaddr_s 00051 { 00052 uint16_t sa_family; /* __SA_COMMON */ 00053 uint8_t sa_data[ sizeof(struct sockaddr_in6) - sizeof(uint16_t) ]; 00054 } __attribute__((aligned(__alignof__(__ss_aligntype)))) ip_addr_t; 00055 00056 /** 00057 * IP_ADDR_SIZE macro: returns the actual size of the ip_addr_t structure pointed to by 'ip'. 00058 */ 00059 #define IP_ADDR_SIZE( ip ) ( ((ip)->sa_family == AF_INET) ? sizeof(struct sockaddr_in) \ 00060 :(((ip)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \ 00061 :(((ip)->sa_family == AF_LLC) ? __LLC_SOCK_SIZE__ : 0) \ 00062 ) \ 00063 ) 00064 00065 /* Yes, we should really handle AF_UNIX, X.25, ATM, IRDA, ... etc. sockaddr types also, 00066 * but libnl doesn't, and we don't want to include kernel headers, so we restrict 00067 * ourselves to the types that libnl handles. 00068 */ 00069 00070 /** 00071 * IP_ADDR_IN macro: returns the address of the AF_INET IPv4 address field within the 00072 * ip_addr_t structure pointed to by 'ip'. 00073 */ 00074 #define IP_ADDR_IN( ip ) (&((((struct sockaddr_in*)(ip))->sin_addr))) 00075 00076 /** 00077 * IP_ADDR_IN6 macro: returns the address of the AF_INET6 IPv6 address field within the 00078 * ip_addr_t structure pointed to by 'ip'. 00079 */ 00080 #define IP_ADDR_IN6( ip ) (&((((struct sockaddr_in6*)(ip))->sin6_addr))) 00081 00082 /** 00083 * IP_ADDR_LLC macro: returns the address of the AF_LLC Link Layer (ethernet) address 00084 * field within the ip_addr_t structure pointed to by 'ip'. 00085 */ 00086 #define IP_ADDR_LLC( ip ) (&((ip)->sa_data[(2*sizeof(__ss_aligntype))-sizeof(sa_family_t)])) 00087 00088 /** 00089 * IP_ADDR macro: returns the address of the IP address 00090 * field within the ip_addr_t structure pointed to by 'ip'. 00091 */ 00092 #define IP_ADDR( ip ) ( ((ip)->sa_family == AF_INET) ? (void*) IP_ADDR_IN(ip) \ 00093 :(((ip)->sa_family == AF_INET6) ? (void*) IP_ADDR_IN6(ip) \ 00094 :(((ip)->sa_family == AF_LLC) ? (void*) IP_ADDR_LLC(ip) : 0 ) \ 00095 ) \ 00096 ) 00097 00098 /** 00099 * IP_ADDR_AF macro: returns the address of the IP address 00100 * of family 'af' field within the ip_addr_t structure pointed to by 'ip'. 00101 */ 00102 #define IP_ADDR_AF( ip, af) ( ((af) == AF_INET) ? (void*) IP_ADDR_IN(ip) \ 00103 :(((af) == AF_INET6) ? (void*) IP_ADDR_IN6(ip) \ 00104 :(((af) == AF_LLC) ? (void*) IP_ADDR_LLC(ip) : 0 ) \ 00105 ) \ 00106 ) 00107 00108 /** 00109 * ip_addr_v4(uint32_t int_ip): returns the ip_addr_t struct of the 32-bit AF_INET address 00110 * int_ip, converting int_ip to network byte order. 00111 */ 00112 extern 00113 ip_addr_t ip_addr_v4( register uint32_t ); 00114 00115 /** 00116 * ip_addr_v4(ip): returns the the 32 bit integer representation of the AF_INET address 00117 * represented by ip_addr_t IP, in host byte order. 00118 */ 00119 extern 00120 uint32_t ip_v4_addr( register ip_addr_t* ); 00121 00122 /** 00123 * ip_addr_in( in_addr ): returns the ip_addr_t representation of the struct in_addr 00124 * AF_INET address argument. 00125 */ 00126 extern 00127 ip_addr_t ip_addr_in( register struct in_addr * ); 00128 00129 /** 00130 * ip_in_addr(ip): returns the struct in_addr AF_INET address represented by the 00131 * ip_addr_t pointed to by ip. 00132 */ 00133 extern 00134 struct in_addr ip_in_addr( register ip_addr_t * ); 00135 00136 /** 00137 * ip_addr_sin( sin ): returns the ip_addr_t representation of the struct sockaddr_in 00138 * pointer sin. 00139 */ 00140 extern 00141 ip_addr_t ip_addr_sin( register struct sockaddr_in * ); 00142 00143 /** 00144 * ip_sin_addr( ip ): returns the struct sockaddr_in representation of the ip_addr_t 00145 * pointed to by ip. 00146 */ 00147 extern 00148 struct sockaddr_in ip_sin_addr( register ip_addr_t * ); 00149 00150 /** 00151 * ip_addr_in6( in6 ): returns the ip_addr_t representation of the struct in6_addr 00152 * pointed to by in6 . 00153 */ 00154 extern 00155 ip_addr_t ip_addr_in6( register struct in6_addr * ); 00156 00157 /** 00158 * ip_in6_addr( ip ): returns the struct in6_addr representation of the ip_addr_t 00159 * pointed to by ip. 00160 */ 00161 extern 00162 struct in6_addr ip_in6_addr( register ip_addr_t *); 00163 00164 00165 /** 00166 * ip_addr_sin6( sin6 ): returns the ip_addr_t representation of the struct sockaddr_in6 00167 * pointed to by sin6. 00168 */ 00169 extern 00170 ip_addr_t ip_addr_sin6(register struct sockaddr_in6 * ); 00171 00172 /** 00173 * ip_sin6_addr( ip ): returns the sockaddr_in6 representation of the ip_addr_t pointed to 00174 * by ip. 00175 */ 00176 extern 00177 struct sockaddr_in6 ip_sin6_addr( register ip_addr_t * ); 00178 00179 00180 /** 00181 * struct in6_bytes_s: representation of an IPv6 address as an array of 16 bytes: 00182 */ 00183 typedef 00184 struct in6_bytes_s 00185 { uint8_t a[16]; 00186 } in6_bytes_t; 00187 00188 /** 00189 * ip_addr_in6bytes( in6bytes ): returns the ip_addr_t representation of the 00190 * in6_bytes_t pointed to by in6_bytes 00191 */ 00192 extern 00193 ip_addr_t ip_addr_in6bytes( register in6_bytes_t * ); 00194 00195 /** 00196 * ip_in6bytes_addr( ip ): returns the in6_bytes_t representation of the 00197 * ip_addr_t pointed to by ip. 00198 */ 00199 extern 00200 in6_bytes_t ip_in6bytes_addr( register ip_addr_t * ); 00201 00202 /** 00203 * ip_addr_text( str ): converts string str to an IP address represented 00204 * by the returned ip_addr_t, if possible. If not possible, a null IP address 00205 * (with sa_family == 0) is returned. 00206 */ 00207 extern 00208 ip_addr_t ip_addr_text( register const char * ); 00209 00210 /** 00211 * ip_text_addr( ip, buf, size ): converts the ip_addr_t pointed to by ip to 00212 * a string. If buf is 0 or size is less than the string length required, 00213 * uses a static buffer; otherwise, buf is used to store the string. 00214 */ 00215 extern 00216 char * ip_text_addr( register ip_addr_t *, register char *, register size_t); 00217 00218 /** 00219 * ip_text_addr( ip, buf, size ): converts the ip_addr_t ip to 00220 * a string. If buf is 0 or size is less than the string length required, 00221 * uses a static buffer; otherwise, buf is used to store the string. 00222 */ 00223 extern 00224 char * ip_text(ip_addr_t ip, register char *, register size_t); 00225 00226 /** 00227 * ip_addr_binary ( buf, len ): returns the ip_addr_t representation 00228 * of the len address bytes pointed to by buf; if len is not a 00229 * recognized address length (the fixed length of an AF_INET, AF_INET6, 00230 * or AF_LLC ethernet address), returns a null ip address with sa_family==0. 00231 */ 00232 extern 00233 ip_addr_t ip_addr_binary(uint8_t *buf, uint8_t len); 00234 00235 /** 00236 * ip_v4_broadcast( ip, prefix ): returns the IPv4 broadcast 00237 * address of the AF_INET IPv4 address pointed to by ip with 00238 * the given prefix . 00239 */ 00240 extern 00241 ip_addr_t ip_v4_broadcast( ip_addr_t *, uint8_t prefix ); 00242 00243 /** 00244 * ip_v4_netmask_to_prefix( netmask ): returns the prefix length 00245 * of all-one bits in the ip_addr_t pointed to by netmask. 00246 */ 00247 extern 00248 uint8_t ip_v4_netmask_to_prefix( ip_addr_t *netmask ); 00249 00250 /** 00251 * ip_v4_prefix_to_netmask( prefix ): returns the netmask address 00252 * of prefix all-one bits . 00253 */ 00254 extern 00255 ip_addr_t ip_v4_prefix_to_netmask( uint8_t prefix ); 00256 00257 /** 00258 * ip_mask( ip, prefix ): returns the subnet address of the IPv4 or IPv6 00259 * address pointed to by ip with the given prefix. 00260 */ 00261 extern 00262 ip_addr_t ip_mask( ip_addr_t *, uint8_t prefix ); 00263 00264 /**@}*/ 00265 #endif