|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2018 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/** Rationale:
|
|
Packit Service |
c5cf8c |
* MPL wrap for handling IPv4 and IPv6.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Applications: pm, pmi, ch3.
|
|
Packit Service |
c5cf8c |
* ch4 supports tcp sockets indirectly through ucx and ofi.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/** Design considerations:
|
|
Packit Service |
c5cf8c |
* Either IPv4 or IPv6, globally set as defalt or with command line option, to
|
|
Packit Service |
c5cf8c |
* simplify logic.
|
|
Packit Service |
c5cf8c |
* TCP only, no UDP or unix domain sockets.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Application use MPL_sockaddr_t exclusively.
|
|
Packit Service |
c5cf8c |
* MPL_get_sockaddr for hostname
|
|
Packit Service |
c5cf8c |
* MPL_get_sockaddr_iface for network interface
|
|
Packit Service |
c5cf8c |
* MPL_get_sockaddr_direct for listening socket on ANY or LOOPBACK
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Simplified MPL_connect and MPL_listen interface.
|
|
Packit Service |
c5cf8c |
* Both have a port parameter.
|
|
Packit Service |
c5cf8c |
* MPL_listen combines bind with listen.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/** Portability:
|
|
Packit Service |
c5cf8c |
* MPL_sockaddr_t:
|
|
Packit Service |
c5cf8c |
* In case this struct is not available (in sys/socket.h), it can be
|
|
Packit Service |
c5cf8c |
* circumvented by declare following (in mpl_sockaddr.h):
|
|
Packit Service |
c5cf8c |
* MPL_sockaddr_t {
|
|
Packit Service |
c5cf8c |
* unsigend short ss_family;
|
|
Packit Service |
c5cf8c |
* char padding[126];
|
|
Packit Service |
c5cf8c |
* };
|
|
Packit Service |
c5cf8c |
* Only the ss_family field is directly accessed. All the other fields are
|
|
Packit Service |
c5cf8c |
* always accessed by casting to either struct sockaddr_in or struct
|
|
Packit Service |
c5cf8c |
* sockaddr_in6.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* The implementation uses getaddrinfo and getifaddrs. The former, as with
|
|
Packit Service |
c5cf8c |
* sockaddr_storage and sockaddr_in6, are documented in RFC 2553, 1999, and are
|
|
Packit Service |
c5cf8c |
* expected to be supported on most supported platforms. getifaddrs is not in
|
|
Packit Service |
c5cf8c |
* POSIX.1, but it is present on Linux since glibc 2.3.3, and available on BSD
|
|
Packit Service |
c5cf8c |
* systems even earlier.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mplconfig.h"
|
|
Packit Service |
c5cf8c |
#include <assert.h>
|
|
Packit Service |
c5cf8c |
#include <sys/types.h>
|
|
Packit Service |
c5cf8c |
#include <sys/socket.h>
|
|
Packit Service |
c5cf8c |
#include <netdb.h>
|
|
Packit Service |
c5cf8c |
#include <netinet/in.h>
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
#include <ifaddrs.h>
|
|
Packit Service |
c5cf8c |
#include <errno.h>
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpl_sockaddr.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int is_localhost(struct sockaddr *p_addr);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int af_type = AF_INET;
|
|
Packit Service |
c5cf8c |
static int _use_loopback = 0;
|
|
Packit Service |
c5cf8c |
static int _max_conn = SOMAXCONN;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void MPL_sockaddr_set_aftype(int type)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
af_type = type;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_get_sockaddr(const char *s_hostname, MPL_sockaddr_t * p_addr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
struct addrinfo ai_hint;
|
|
Packit Service |
c5cf8c |
struct addrinfo *ai_list;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
edf0b4 |
#ifdef __APPLE__
|
|
Packit Service |
c5cf8c |
/* Macos adds .local to hostname when network is unavailable or limited.
|
|
Packit Service |
c5cf8c |
* This will result in long timeout in getaddrinfo below.
|
|
Packit Service |
c5cf8c |
* Bypass it by resetting the hostname to "localhost"
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int n = strlen(s_hostname);
|
|
Packit Service |
c5cf8c |
if (n > 6 && strcmp(s_hostname + n - 6, ".local") == 0) {
|
|
Packit Service |
c5cf8c |
s_hostname = "localhost";
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
edf0b4 |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* NOTE: there is report that getaddrinfo implementations will call kernel
|
|
Packit Service |
c5cf8c |
* even when s_hostname is entirely numerical string and it may cause
|
|
Packit Service |
c5cf8c |
* problems when host is configured with thousands of ip addresses.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/* TODO: detect the cases when s_hostname is entirely numerical string and
|
|
Packit Service |
c5cf8c |
* call inet_pton directly (-- do this on first bug report).
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
memset(p_addr, 0, sizeof(*p_addr));
|
|
Packit Service |
c5cf8c |
memset(&ai_hint, 0, sizeof(ai_hint));
|
|
Packit Service |
c5cf8c |
ai_hint.ai_family = af_type;
|
|
Packit Service |
c5cf8c |
ai_hint.ai_socktype = SOCK_STREAM;
|
|
Packit Service |
c5cf8c |
ai_hint.ai_protocol = IPPROTO_TCP;
|
|
Packit Service |
d30357 |
ai_hint.ai_flags = AI_V4MAPPED;
|
|
Packit Service |
c5cf8c |
ret = getaddrinfo(s_hostname, NULL, &ai_hint, &ai_list);
|
|
Packit Service |
c5cf8c |
if (ret) {
|
|
Packit Service |
c5cf8c |
return ret;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (af_type == AF_INET) {
|
|
Packit Service |
c5cf8c |
memcpy(p_addr, ai_list->ai_addr, sizeof(struct sockaddr_in));
|
|
Packit Service |
c5cf8c |
} else if (af_type == AF_INET6) {
|
|
Packit Service |
c5cf8c |
memcpy(p_addr, ai_list->ai_addr, sizeof(struct sockaddr_in6));
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
assert(0);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
freeaddrinfo(ai_list);
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_get_sockaddr_direct(int type, MPL_sockaddr_t * p_addr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
memset(p_addr, 0, sizeof(*p_addr));
|
|
Packit Service |
c5cf8c |
assert(type == MPL_SOCKADDR_ANY || type == MPL_SOCKADDR_LOOPBACK);
|
|
Packit Service |
c5cf8c |
if (af_type == AF_INET) {
|
|
Packit Service |
c5cf8c |
struct sockaddr_in *p_addr4 = (struct sockaddr_in *) p_addr;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p_addr4->sin_family = AF_INET;
|
|
Packit Service |
c5cf8c |
if (type == MPL_SOCKADDR_LOOPBACK) {
|
|
Packit Service |
c5cf8c |
p_addr4->sin_addr.s_addr = htonl(0x7f000001);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
p_addr4->sin_addr.s_addr = htonl(INADDR_ANY);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
} else if (af_type == AF_INET6) {
|
|
Packit Service |
c5cf8c |
struct sockaddr_in6 *p_addr6 = (struct sockaddr_in6 *) p_addr;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p_addr6->sin6_family = AF_INET6;
|
|
Packit Service |
c5cf8c |
if (type == MPL_SOCKADDR_LOOPBACK) {
|
|
Packit Service |
c5cf8c |
p_addr6->sin6_addr = in6addr_loopback;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
p_addr6->sin6_addr = in6addr_any;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
assert(0);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_get_sockaddr_iface(const char *s_iface, MPL_sockaddr_t * p_addr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
struct ifaddrs *ifaddr;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
struct ifaddrs *ifa;
|
|
Packit Service |
c5cf8c |
int found = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
memset(p_addr, 0, sizeof(*p_addr));
|
|
Packit Service |
c5cf8c |
ret = getifaddrs(&ifaddr);
|
|
Packit Service |
c5cf8c |
if (ret) {
|
|
Packit Service |
c5cf8c |
return ret;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
ifa = ifaddr;
|
|
Packit Service |
c5cf8c |
while (ifa) {
|
|
Packit Service |
c5cf8c |
if (s_iface && ifa->ifa_name && strcmp(s_iface, ifa->ifa_name) != 0) {
|
|
Packit Service |
c5cf8c |
ifa = ifa->ifa_next;
|
|
Packit Service |
c5cf8c |
continue;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == af_type) {
|
|
Packit Service |
c5cf8c |
found++;
|
|
Packit Service |
c5cf8c |
if (af_type == AF_INET) {
|
|
Packit Service |
c5cf8c |
memcpy(p_addr, ifa->ifa_addr, sizeof(struct sockaddr_in));
|
|
Packit Service |
c5cf8c |
} else if (af_type == AF_INET6) {
|
|
Packit Service |
c5cf8c |
memcpy(p_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6));
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (!is_localhost((struct sockaddr *) ifa->ifa_addr)) {
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
ifa = ifa->ifa_next;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
freeifaddrs(ifaddr);
|
|
Packit Service |
c5cf8c |
if (!found) {
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_socket()
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
return socket(af_type, SOCK_STREAM, IPPROTO_TCP);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_connect(int socket, MPL_sockaddr_t * p_addr, unsigned short port)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (af_type == AF_INET) {
|
|
Packit Service |
c5cf8c |
((struct sockaddr_in *) p_addr)->sin_port = htons(port);
|
|
Packit Service |
c5cf8c |
return connect(socket, (const struct sockaddr *) p_addr, sizeof(struct sockaddr_in));
|
|
Packit Service |
c5cf8c |
} else if (af_type == AF_INET6) {
|
|
Packit Service |
c5cf8c |
((struct sockaddr_in6 *) p_addr)->sin6_port = htons(port);
|
|
Packit Service |
c5cf8c |
return connect(socket, (const struct sockaddr *) p_addr, sizeof(struct sockaddr_in6));
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void MPL_set_listen_attr(int use_loopback, int max_conn)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
_use_loopback = use_loopback;
|
|
Packit Service |
c5cf8c |
_max_conn = max_conn;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_listen(int socket, unsigned short port)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPL_sockaddr_t addr;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (_use_loopback) {
|
|
Packit Service |
c5cf8c |
MPL_get_sockaddr_direct(MPL_SOCKADDR_LOOPBACK, &addr);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPL_get_sockaddr_direct(MPL_SOCKADDR_ANY, &addr);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (af_type == AF_INET) {
|
|
Packit Service |
c5cf8c |
((struct sockaddr_in *) &addr)->sin_port = htons(port);
|
|
Packit Service |
c5cf8c |
ret = bind(socket, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in));
|
|
Packit Service |
c5cf8c |
} else if (af_type == AF_INET6) {
|
|
Packit Service |
c5cf8c |
((struct sockaddr_in6 *) &addr)->sin6_port = htons(port);
|
|
Packit Service |
c5cf8c |
ret = bind(socket, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in6));
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
assert(0);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (ret) {
|
|
Packit Service |
c5cf8c |
return ret;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return listen(socket, _max_conn);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_listen_anyport(int socket, unsigned short *p_port)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPL_sockaddr_t addr;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
socklen_t n;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (_use_loopback) {
|
|
Packit Service |
c5cf8c |
MPL_get_sockaddr_direct(MPL_SOCKADDR_LOOPBACK, &addr);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPL_get_sockaddr_direct(MPL_SOCKADDR_ANY, &addr);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (af_type == AF_INET) {
|
|
Packit Service |
c5cf8c |
((struct sockaddr_in *) &addr)->sin_port = 0;
|
|
Packit Service |
c5cf8c |
ret = bind(socket, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in));
|
|
Packit Service |
c5cf8c |
} else if (af_type == AF_INET6) {
|
|
Packit Service |
c5cf8c |
((struct sockaddr_in6 *) &addr)->sin6_port = 0;
|
|
Packit Service |
c5cf8c |
ret = bind(socket, (const struct sockaddr *) &addr, sizeof(struct sockaddr_in6));
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
assert(0);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (ret) {
|
|
Packit Service |
c5cf8c |
return ret;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
n = sizeof(addr);
|
|
Packit Service |
c5cf8c |
ret = getsockname(socket, (struct sockaddr *) &addr, &n);
|
|
Packit Service |
c5cf8c |
if (ret) {
|
|
Packit Service |
c5cf8c |
return ret;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (af_type == AF_INET) {
|
|
Packit Service |
c5cf8c |
*p_port = ntohs(((struct sockaddr_in *) &addr)->sin_port);
|
|
Packit Service |
c5cf8c |
} else if (af_type == AF_INET6) {
|
|
Packit Service |
c5cf8c |
*p_port = ntohs(((struct sockaddr_in6 *) &addr)->sin6_port);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return listen(socket, _max_conn);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_listen_portrange(int socket, unsigned short *p_port, int low_port, int high_port)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPL_sockaddr_t addr;
|
|
Packit Service |
c5cf8c |
int i;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (_use_loopback) {
|
|
Packit Service |
c5cf8c |
MPL_get_sockaddr_direct(MPL_SOCKADDR_LOOPBACK, &addr);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPL_get_sockaddr_direct(MPL_SOCKADDR_ANY, &addr);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
for (i = low_port; i <= high_port; i++) {
|
|
Packit Service |
c5cf8c |
ret = MPL_listen(socket, i);
|
|
Packit Service |
c5cf8c |
if (ret == 0) {
|
|
Packit Service |
c5cf8c |
*p_port = i;
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
} else if (errno == EADDRINUSE) {
|
|
Packit Service |
c5cf8c |
continue;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (i > high_port) {
|
|
Packit Service |
c5cf8c |
return -2;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return listen(socket, _max_conn);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_sockaddr_to_str(MPL_sockaddr_t * p_addr, char *str, int maxlen)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
unsigned char *p;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* TODO: consider inet_ntop */
|
|
Packit Service |
c5cf8c |
if (p_addr->ss_family == AF_INET) {
|
|
Packit Service |
c5cf8c |
p = (void *) &((struct sockaddr_in *) p_addr)->sin_addr;
|
|
Packit Service |
c5cf8c |
snprintf(str, maxlen, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
|
Packit Service |
c5cf8c |
} else if (p_addr->ss_family == AF_INET6) {
|
|
Packit Service |
c5cf8c |
p = (void *) &((struct sockaddr_in6 *) p_addr)->sin6_addr;
|
|
Packit Service |
c5cf8c |
snprintf(str, maxlen,
|
|
Packit Service |
c5cf8c |
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
|
|
Packit Service |
c5cf8c |
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
|
|
Packit Service |
c5cf8c |
p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPL_sockaddr_port(MPL_sockaddr_t * p_addr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (p_addr->ss_family == AF_INET) {
|
|
Packit Service |
c5cf8c |
return ntohs(((struct sockaddr_in *) p_addr)->sin_port);
|
|
Packit Service |
c5cf8c |
} else if (p_addr->ss_family == AF_INET6) {
|
|
Packit Service |
c5cf8c |
return ntohs(((struct sockaddr_in6 *) p_addr)->sin6_port);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int is_localhost(struct sockaddr *p_addr)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char *p;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (p_addr->sa_family == AF_INET) {
|
|
Packit Service |
c5cf8c |
p = (void *) &((struct sockaddr_in *) p_addr)->sin_addr;
|
|
Packit Service |
c5cf8c |
return strncmp(p, "\x7f\x00\x00\x01", 4) == 0;
|
|
Packit Service |
c5cf8c |
} else if (p_addr->sa_family == AF_INET6) {
|
|
Packit Service |
c5cf8c |
p = (void *) &((struct sockaddr_in6 *) p_addr)->sin6_addr;
|
|
Packit Service |
c5cf8c |
return strncmp(p, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01", 16) == 0 ||
|
|
Packit Service |
c5cf8c |
strncmp(p, "\xfe\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\x01", 16) == 0;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|