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 #include <ip_addr.h>
00027 #include <arpa/inet.h>
00028 #include <net/if_arp.h>
00029 #include <string.h>
00030 #include <stdio.h>
00031
00032 ip_addr_t ip_addr_v4( register uint32_t i )
00033 {
00034 ip_addr_t ip = { AF_INET };
00035 memset(&(ip.sa_data[0]),'\0',sizeof(ip.sa_data));
00036 ((struct in_addr*)IP_ADDR_IN(&ip))->s_addr = htonl( i );
00037 return ip;
00038 }
00039
00040 uint32_t ip_v4_addr( register ip_addr_t *ip )
00041 {
00042 if ( ip->sa_family != AF_INET ) return 0;
00043 return ntohl( ((struct in_addr*)IP_ADDR_IN(ip))->s_addr );
00044 }
00045
00046
00047 ip_addr_t ip_addr_in( register struct in_addr *in )
00048 {
00049 ip_addr_t ip = { AF_INET };
00050 memset(&(ip.sa_data[0]),'\0',sizeof(ip.sa_data));
00051 *((struct in_addr*)IP_ADDR_IN(&ip)) = *in;
00052 return ip;
00053 }
00054
00055 struct in_addr ip_in_addr( register ip_addr_t *ip )
00056 {
00057
00058 return *((struct in_addr*)IP_ADDR_IN(ip));
00059 }
00060
00061
00062 ip_addr_t ip_addr_sin( register struct sockaddr_in *sin )
00063 {
00064 ip_addr_t ip;
00065 *((struct sockaddr_in*)&ip) = *sin;
00066 return ip;
00067 }
00068
00069 struct sockaddr_in ip_sin_addr( register ip_addr_t *ip )
00070 {
00071 return *((struct sockaddr_in*)ip);
00072 }
00073
00074
00075 ip_addr_t ip_addr_in6( register struct in6_addr *in6 )
00076 {
00077 ip_addr_t ip = { AF_INET6 };
00078 memset(&(ip.sa_data[0]),'\0',sizeof(ip.sa_data));
00079 *((struct in6_addr*)IP_ADDR_IN6(&ip)) = *in6;
00080 return ip;
00081 }
00082
00083
00084 struct in6_addr ip_in6_addr( register ip_addr_t *ip)
00085 {
00086 return *((struct in6_addr*)IP_ADDR_IN6(ip));
00087 }
00088
00089
00090
00091 ip_addr_t ip_addr_sin6( register struct sockaddr_in6 *sin6 )
00092 {
00093 ip_addr_t ip;
00094 *((struct sockaddr_in6*)&ip) = *sin6;
00095 return ip;
00096 }
00097
00098 struct sockaddr_in6 ip_sin6_addr( register ip_addr_t *ip )
00099 {
00100 return *((struct sockaddr_in6*)ip);
00101 }
00102
00103
00104 ip_addr_t ip_addr_in6bytes(register in6_bytes_t *in6)
00105 {
00106 ip_addr_t ip = { AF_INET6 };
00107 memset(&(ip.sa_data[0]),'\0',sizeof(ip.sa_data));
00108 *((struct in6_addr*)IP_ADDR_IN6(&ip)) = *((struct in6_addr*)in6);
00109 return ip;
00110 }
00111
00112
00113 in6_bytes_t ip_in6bytes_addr( register ip_addr_t *ip )
00114 {
00115 return *((in6_bytes_t*)IP_ADDR_IN6(ip));
00116 }
00117
00118 ip_addr_t ip_addr_text( register const char *s )
00119 {
00120 ip_addr_t ip;
00121 memset(&ip,'\0',sizeof(ip));
00122
00123 if( inet_pton( AF_INET6, s, ((struct in6_addr*)IP_ADDR_IN6(&ip))) )
00124 ip.sa_family = AF_INET6;
00125 else
00126 if( inet_pton( AF_INET, s, ((struct in6_addr*)IP_ADDR_IN(&ip))) )
00127 ip.sa_family = AF_INET;
00128
00129 return ip;
00130 }
00131
00132 static void hex_dump( uint8_t *src, uint32_t src_len, uint8_t *dst, uint32_t dst_len, char sep)
00133 {
00134 while( src_len-- && (dst_len-=3) )
00135 dst+=sprintf((char*)dst,"%.2x%c",*(src++),sep);
00136 *(--dst)='\0';
00137 }
00138
00139 char *ip_text_addr( register ip_addr_t *ip, register char *buf, register size_t len)
00140 {
00141 static char sbuf[64]="\0";
00142 char *d = buf ? buf : &(sbuf[0]);
00143 size_t sz = buf ? len : 64;
00144 char sep ='.';
00145
00146 switch(ip->sa_family)
00147 {
00148 case AF_INET:
00149 return (char*) inet_ntop(AF_INET, (struct in_addr*)IP_ADDR_IN(ip), d, sz );
00150 case AF_INET6:
00151 return (char*) inet_ntop(AF_INET6, (struct in6_addr*)IP_ADDR_IN6(ip), d, sz );
00152 #ifndef AF_LLC
00153 #define AF_LLC 26
00154 #endif
00155 case AF_LLC:
00156 sep = ':';
00157 default:
00158 hex_dump((uint8_t*)IP_ADDR_LLC(ip), sep == ':' ? 6 : __LLC_SOCK_SIZE__, (uint8_t*)d, sz, sep);
00159 return d;
00160 }
00161 return 0L;
00162 }
00163
00164 char * ip_text(ip_addr_t ip, register char *buf, register size_t sz)
00165 {
00166 return ip_text_addr(&ip, buf, sz);
00167 }
00168
00169 ip_addr_t ip_addr_binary(uint8_t *addr_data, uint8_t len)
00170 {
00171 ip_addr_t ip;
00172 uint8_t *addr=0;
00173 memset(&ip, '\0', sizeof(ip_addr_t));
00174
00175 switch( len )
00176 {
00177 case 4:
00178 ip.sa_family = AF_INET;
00179 addr = (uint8_t*) IP_ADDR_IN( &ip );
00180 break;
00181 case 6:
00182 ip.sa_family = AF_LLC;
00183 addr = (uint8_t*) IP_ADDR_IN6( &ip );
00184 break;
00185 case 16:
00186 ip.sa_family = AF_INET6;
00187 addr = (uint8_t*) IP_ADDR_LLC( &ip );
00188 break;
00189 default:
00190 return ip;
00191 }
00192 memcpy(addr, addr_data, len);
00193 return ip;
00194 }
00195
00196 ip_addr_t ip_v4_broadcast( ip_addr_t *ipp, uint8_t prefix )
00197 {
00198 ip_addr_t ip = { AF_INET };
00199 memset(&(ip.sa_data[0]),'\0',sizeof(ip.sa_data));
00200 uint32_t ip4 = ntohl( ((struct in_addr*)IP_ADDR_IN( ipp ))->s_addr );
00201 ((struct sockaddr_in*)&(ip))->sin_addr.s_addr=
00202 htonl( ( ip4 & (((1 << prefix)-1) << (32 - prefix)))
00203 |(((1<< (32 - prefix))-1))
00204 );
00205 return ip;
00206 }
00207
00208 uint8_t ip_v4_netmask_to_prefix( ip_addr_t *netmask )
00209 {
00210 if ( netmask->sa_family != AF_INET ) return 0;
00211 register uint32_t nm = ntohl(((struct sockaddr_in*)netmask)->sin_addr.s_addr), i=32, b=1;
00212 for(; i && ((nm & b) != b); i-=1, b <<= 1);
00213 return i;
00214 }
00215
00216 ip_addr_t ip_v4_prefix_to_netmask( uint8_t prefix )
00217 {
00218 ip_addr_t ip = { .sa_family = AF_INET };
00219
00220 ((struct sockaddr_in*)&ip)->sin_addr.s_addr =
00221 htonl( (( 1 << prefix ) - 1) << (32 - prefix));
00222
00223 return ip;
00224 }
00225
00226 ip_addr_t ip_mask( ip_addr_t *ipA, uint8_t prefix )
00227 {
00228 ip_addr_t ip;
00229 ip = *ipA;
00230 switch( ipA->sa_family )
00231 {
00232 case AF_INET:
00233 {
00234 uint32_t a = ntohl(IP_ADDR_IN(ipA)->s_addr);
00235 prefix &= 0x1f;
00236 (IP_ADDR_IN(&ip))->s_addr =
00237 htonl( a & (((1 << prefix) -1 ) << (32 - prefix)) );
00238 } break;
00239 case AF_INET6:
00240 {
00241 uint8_t n =
00242 prefix & 0x7f,
00243 *a = ((uint8_t*)IP_ADDR_IN6(&ip)),
00244 *b = &(a[16]);
00245 for(; (b > a) && (n >= 8); b--, n-=8)
00246 *b=0;
00247 if( n )
00248 *b &=((1<<n)-1)<<(8-n);
00249 } break;
00250 }
00251 return ip;
00252 }