mirror of https://github.com/sipwise/sems.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.0 KiB
136 lines
3.0 KiB
#include "ip_util.h"
|
|
#include "log.h"
|
|
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <netdb.h>
|
|
#include <arpa/inet.h>
|
|
|
|
int am_inet_pton(const char* src, struct sockaddr_storage* dst)
|
|
{
|
|
char src_addr[NI_MAXHOST];
|
|
|
|
struct sockaddr_in *sin;
|
|
struct sockaddr_in6 *sin6;
|
|
|
|
bool must_be_ipv6 = false;
|
|
|
|
if(!src)
|
|
return 0;
|
|
|
|
size_t src_len = strlen(src);
|
|
if(!src_len || (src_len > NI_MAXHOST-1))
|
|
return 0;
|
|
|
|
if( (src[0] == '[') &&
|
|
(src[src_len-1] == ']') ) {
|
|
|
|
// IPv6
|
|
memcpy(src_addr,src+1,src_len-2);
|
|
src_addr[src_len-2] = '\0';
|
|
must_be_ipv6 = true;
|
|
}
|
|
else {
|
|
// IPv4
|
|
memcpy(src_addr,src,src_len+1);
|
|
}
|
|
|
|
sin = (struct sockaddr_in *)dst;
|
|
sin6 = (struct sockaddr_in6 *)dst;
|
|
|
|
if(!must_be_ipv6 && (inet_pton(AF_INET, src_addr, &sin->sin_addr) > 0)) {
|
|
dst->ss_family = AF_INET;
|
|
return 1;
|
|
}
|
|
|
|
if(inet_pton(AF_INET6, src_addr, &sin6->sin6_addr) > 0) {
|
|
dst->ss_family = AF_INET6;
|
|
#ifdef SIN6_LEN
|
|
sin6->sin6_len = sizeof(struct sockaddr_in6);
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char* am_inet_ntop(const sockaddr_storage* addr, char* str, size_t size)
|
|
{
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
|
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
|
|
|
|
if(addr->ss_family == AF_INET) {
|
|
if(!inet_ntop(AF_INET,&sin->sin_addr,str,size)) {
|
|
ERROR("Could not convert IPv4 address to string: %s",strerror(errno));
|
|
return NULL;
|
|
}
|
|
}
|
|
else {
|
|
if(!inet_ntop(AF_INET6,&sin6->sin6_addr,str,size)) {
|
|
ERROR("Could not convert IPv6 address to string: %s",strerror(errno));
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
string am_inet_ntop(const sockaddr_storage* addr)
|
|
{
|
|
char host[NI_MAXHOST] = "";
|
|
am_inet_ntop(addr,host,NI_MAXHOST);
|
|
return host;
|
|
}
|
|
|
|
const char* am_inet_ntop_sip(const sockaddr_storage* addr, char* str, size_t size)
|
|
{
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
|
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
|
|
|
|
if(addr->ss_family == AF_INET) {
|
|
if(!inet_ntop(AF_INET,&sin->sin_addr,str,size)) {
|
|
ERROR("Could not convert IPv4 address to string: %s",strerror(errno));
|
|
return NULL;
|
|
}
|
|
}
|
|
else {
|
|
if(!inet_ntop(AF_INET6,&sin6->sin6_addr,str+1,size-2)) {
|
|
ERROR("Could not convert IPv6 address to string: %s",strerror(errno));
|
|
return NULL;
|
|
}
|
|
size_t str_len = strlen(str);
|
|
str[0] = '[';
|
|
str[str_len] = ']';
|
|
str[str_len+1] = '\0';
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
void am_set_port(struct sockaddr_storage* addr, short port)
|
|
{
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
|
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
|
|
|
|
if(addr->ss_family == AF_INET) {
|
|
sin->sin_port = htons(port);
|
|
} else {
|
|
sin6->sin6_port = htons(port);
|
|
}
|
|
}
|
|
|
|
unsigned short am_get_port(const sockaddr_storage* addr)
|
|
{
|
|
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
|
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
|
|
|
|
if(addr->ss_family == AF_INET) {
|
|
return ntohs(sin->sin_port);
|
|
}
|
|
|
|
return ntohs(sin6->sin6_port);
|
|
}
|
|
|
|
|