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