Simple tools for networking / objects in plain C Snapshot
|
00001 #include "addrutil.h" 00002 #include <arpa/inet.h> 00003 #include <string.h> 00004 #include <stdio.h> 00005 00006 // -------------------------------------------------------------------- 00007 int IPADDRESS_any( IPADDRESS *addr, int family ) 00008 { 00009 switch(family) { 00010 case AF_INET: 00011 addr->family = AF_INET; 00012 addr->addr.ipv4.s_addr = INADDR_ANY; 00013 break; 00014 case AF_INET6: 00015 addr->family = AF_INET6; 00016 addr->addr.ipv6 = in6addr_any; 00017 break; 00018 default: 00019 return -1; 00020 } 00021 return 0; 00022 } 00023 00024 void IPADDRESS_broadcast_ipv4( IPADDRESS *addr ) 00025 { 00026 addr->family = AF_INET; 00027 addr->addr.ipv4.s_addr = htonl(INADDR_BROADCAST); 00028 } 00029 00030 00031 int IPADDRESS_loopback( IPADDRESS *addr, int family ) 00032 { 00033 switch(family) { 00034 case AF_INET: 00035 addr->family = AF_INET; 00036 addr->addr.ipv4.s_addr = htonl(INADDR_LOOPBACK); 00037 break; 00038 case AF_INET6: 00039 addr->family = AF_INET6; 00040 addr->addr.ipv6 = in6addr_loopback; 00041 break; 00042 default: 00043 return -1; 00044 } 00045 return 0; 00046 } 00047 00048 00049 00050 int IPADDRESS_parse_string( IPADDRESS *addr, const char *str ) 00051 { 00052 if (inet_pton( AF_INET, str, &addr->addr.ipv4 )) { 00053 addr->family = AF_INET; 00054 return 0; 00055 } else if (inet_pton( AF_INET6, str, &addr->addr.ipv6 )) { 00056 addr->family = AF_INET6; 00057 return 0; 00058 } 00059 return -1; 00060 } 00061 00062 char * IPADDRESS_to_string( IPADDRESS *addr ) 00063 { 00064 char sbuf[100]; 00065 00066 if (! inet_ntop( addr->family, (const void *) &addr->addr, sbuf, sizeof(sbuf) ) ) { 00067 return 0; 00068 } 00069 return strdup( sbuf ); 00070 } 00071 00072 // -------------------------------------------------------------------- 00073 int SOCKADDR_init( SOCKADDR *saddr, IPADDRESS *addr, uint16_t port ) 00074 { 00075 memset( saddr, 0, sizeof( SOCKADDR ) ); 00076 saddr->addr_ipv4.sin_port = htons( port ); 00077 saddr->addr_ipv4.sin_family = addr->family; 00078 00079 if (addr->family == AF_INET) { 00080 saddr->addr_ipv4.sin_addr = addr->addr.ipv4; 00081 } else if (addr->family == AF_INET6) { 00082 saddr->addr_ipv6.sin6_addr = addr->addr.ipv6; 00083 } else { 00084 return -1; 00085 } 00086 return 0; 00087 } 00088 00089 socklen_t SOCKADDR_length( SOCKADDR * addr ) 00090 { 00091 if (addr->addr_ipv4.sin_family == AF_INET) { 00092 return sizeof(struct sockaddr_in); 00093 } else if (addr->addr_ipv4.sin_family == AF_INET6) { 00094 return sizeof(struct sockaddr_in6); 00095 } 00096 return -1; 00097 } 00098 00099 int SOCKADDR_family( SOCKADDR *addr ) 00100 { 00101 return addr->addr_ipv4.sin_family; 00102 } 00103 00104 void * SOCKADDR_ipaddr( SOCKADDR * addr ) 00105 { 00106 if (addr->addr_ipv4.sin_family == AF_INET) { 00107 return &addr->addr_ipv4.sin_addr; 00108 } else if (addr->addr_ipv4.sin_family == AF_INET6) { 00109 return &addr->addr_ipv6.sin6_addr; 00110 } 00111 return 0; 00112 } 00113 00114 char * SOCKADDR_to_string( SOCKADDR *saddr ) 00115 { 00116 char sbuf[100]; 00117 int nlen, remain; 00118 00119 if (SOCKADDR_family(saddr) == AF_INET6) { 00120 sbuf[0] = '['; 00121 00122 if (! inet_ntop( SOCKADDR_family( saddr ), (const void *) SOCKADDR_ipaddr( saddr ), sbuf + 1, sizeof(sbuf) - 1 ) ) { 00123 return 0; 00124 } 00125 00126 nlen = strlen(sbuf); 00127 remain = sizeof(sbuf) - nlen; 00128 00129 if (remain <= 0) { 00130 return 0; 00131 } 00132 00133 snprintf(sbuf+strlen(sbuf),remain-1,"]:%hu", ntohs( saddr->addr_ipv4.sin_port ) ); 00134 } else { 00135 if (! inet_ntop( SOCKADDR_family( saddr ), (const void *) SOCKADDR_ipaddr( saddr ), sbuf , sizeof(sbuf) ) ) { 00136 return 0; 00137 } 00138 00139 nlen = strlen(sbuf); 00140 remain = sizeof(sbuf) - nlen; 00141 00142 if (remain <= 0) { 00143 return 0; 00144 } 00145 00146 snprintf(sbuf+strlen(sbuf),remain-1,":%hu", ntohs( saddr->addr_ipv4.sin_port ) ); 00147 } 00148 return strdup(sbuf); 00149 } 00150 00151