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