int acl_getsockname(ACL_SOCKET sockfd, char *buf, size_t size) { struct SOCK_ADDR addr; struct sockaddr *sa = (struct sockaddr*) &addr; socklen_t len = sizeof(addr); char ip[32]; int port; if (sockfd == ACL_SOCKET_INVALID || buf == NULL || size <= 0) return -1; memset(&addr, 0, sizeof(addr)); if (getsockname(sockfd, sa, &len) == -1) return -1; #ifndef WIN32 if (sa->sa_family == AF_UNIX) { snprintf(buf, size, "%s", addr.sa.un.sun_path); return 0; } else #endif if (sa->sa_family != AF_INET) return -1; if (acl_inet_ntoa(addr.sa.in.sin_addr, ip, sizeof(ip)) == NULL) return -1; port = ntohs(addr.sa.in.sin_port); snprintf(buf, size, "%s:%d", ip, port); return 0; }
ACL_SOCKET acl_accept(ACL_SOCKET sock, char *buf, size_t size, int* sock_type) { #ifdef ACL_WINDOWS struct { union { struct sockaddr_in in; } sa; } addr; #else struct { union { struct sockaddr_in in; struct sockaddr_un un; struct sockaddr sa; } sa; } addr; #endif socklen_t len = sizeof(addr); struct sockaddr *sa = (struct sockaddr*) &addr; ACL_SOCKET fd; memset(&addr, 0, sizeof(addr)); fd = acl_sane_accept(sock, sa, &len); if (fd == ACL_SOCKET_INVALID) return fd; if (sock_type != NULL) *sock_type = sa->sa_family; if (buf != NULL && size > 0) { size_t n; #ifndef ACL_WINDOWS if (sa->sa_family == AF_UNIX) snprintf(buf, size, "%s", addr.sa.un.sun_path); #endif if (sa->sa_family != AF_INET) return fd; if (acl_inet_ntoa(addr.sa.in.sin_addr, buf, size) == NULL) return fd; n = strlen(buf); if (n >= size) return fd; snprintf(buf + n, size - n, ":%u", (unsigned short) ntohs(addr.sa.in.sin_port)); buf[size - 1] = 0; } return fd; }
ACL_VSTREAM *acl_vstream_listen_ex(const char *addr, int qlen, int block_mode, int io_bufsize, int io_timeout) { const char *myname = "acl_vstream_listen_ex"; ACL_SOCKET listenfd; struct sockaddr_in local; ACL_VSTREAM *listen_stream; int len; if (addr == 0 || *addr == 0 || qlen <= 0) { acl_msg_error("%s: input invalid", myname); return NULL; } #ifdef ACL_UNIX /* this maybe unix addr, such as '/home/test/listen.sock' */ if (strchr(addr, '/') != NULL) { listenfd = acl_unix_listen(addr, qlen, 0); if (listenfd == ACL_SOCKET_INVALID) return NULL; acl_non_blocking(listenfd, block_mode); listen_stream = acl_vstream_fdopen(listenfd, ACL_VSTREAM_FLAG_RW, io_bufsize, io_timeout, ACL_VSTREAM_TYPE_LISTEN_UNIX); if (listen_stream == NULL) { acl_socket_close(listenfd); acl_msg_error("%s: open vstream error, addr(%s)", myname, addr); return NULL; } acl_vstream_set_local(listen_stream, addr); sprintf(listen_stream->errbuf, "+OK"); return (listen_stream); } #endif /* addr such as '192.168.0.1:80' */ listenfd = acl_inet_listen(addr, qlen, block_mode); if (listenfd == ACL_SOCKET_INVALID) { acl_msg_error("%s: listen addr(%s) error(%s)", myname, addr, acl_last_serror()); return NULL; } listen_stream = acl_vstream_fdopen(listenfd, ACL_VSTREAM_FLAG_RW, io_bufsize, io_timeout, ACL_VSTREAM_TYPE_LISTEN_INET); if (listen_stream == NULL) { acl_socket_close(listenfd); acl_msg_error("%s: open vstream error addr(%s)", myname, addr); return NULL; } memset(&local, 0, sizeof(local)); len = (int) sizeof(struct sockaddr); if (getsockname(listenfd, (struct sockaddr*) &local, (socklen_t *) &len) < 0) { acl_msg_warn("%s: getsockname error(%s) for sock(%d)", myname, acl_last_serror(), listenfd); acl_vstream_set_local(listen_stream, addr); } else { char ip[32], buf[64]; int port; acl_inet_ntoa(local.sin_addr, ip, sizeof(ip)); port = ntohs(local.sin_port); snprintf(buf, sizeof(buf), "%s:%d", ip, port); acl_vstream_set_local(listen_stream, buf); } sprintf(listen_stream->errbuf, "+OK"); return listen_stream; }
ACL_DNS_DB *acl_gethostbyname(const char *name, int *h_error) { char myname[] = "acl_gethostbyname"; ACL_DNS_DB *h_dns_db = NULL; ACL_HOSTNAME *h_host; /* #ifndef SUNOS5 */ struct hostent *h_addrp = NULL; /* #endif */ #ifdef ACL_UNIX # ifndef ACL_MACOSX struct hostent h_buf; int errnum = 0; # endif #endif char **pptr, buf[4096]; int n; #undef ERETURN #define ERETURN(_x_) do { \ if (h_dns_db) \ acl_netdb_free(h_dns_db); \ return (_x_); \ } while (0) if (name == NULL) { acl_msg_error("%s, %s(%d): input error", __FILE__, myname, __LINE__); ERETURN (NULL); } if (h_error) *h_error = 0; /* lookup the local dns cache first */ h_dns_db = acl_netdb_cache_lookup(name); if (h_dns_db) return (h_dns_db); h_dns_db = acl_netdb_new(name); if (h_dns_db == NULL) { acl_msg_error("%s, %s(%d): acl_netdb_new error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); return (NULL); } if (acl_is_ip(name) == 0) { h_host = acl_mycalloc(1, sizeof(ACL_HOSTNAME)); if (h_host == NULL) { acl_msg_error("%s, %s(%d): calloc error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } h_host->saddr.sin_addr.s_addr = inet_addr(name); ACL_SAFE_STRNCPY(h_host->ip, name, sizeof(h_host->ip)); if (acl_array_append(h_dns_db->h_db, h_host) < 0) { acl_msg_error("%s, %s(%d): array append error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } h_dns_db->size++; return (h_dns_db); } memset(buf, 0, sizeof(buf)); h_addrp = NULL; #if defined(ACL_MS_WINDOWS) || defined(ACL_MACOSX) h_addrp = gethostbyname(name); if (h_addrp == NULL) { acl_msg_error("%s, %s(%d): gethostbyname error(%s), addr=%s", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf)), name); ERETURN (NULL); } #elif defined(ACL_UNIX) memset(&h_buf, 0, sizeof(h_buf)); # if defined(LINUX2) || defined(ACL_FREEBSD) n = gethostbyname_r(name, &h_buf, buf, sizeof(buf), &h_addrp, &errnum); if (n) { if (h_error) *h_error = errnum; ERETURN (NULL); } # elif defined(SUNOS5) h_addrp = gethostbyname_r(name, &h_buf, buf, sizeof(buf), &errnum); if (h_addrp == NULL) { if (h_error) *h_error = errnum; ERETURN (NULL); } # else # error "unknown OS type" # endif #else # error "unknown OS type" #endif if (h_addrp == NULL || h_addrp->h_addr_list == NULL) { acl_msg_error("%s, %s(%d): null result return(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } for (pptr = h_addrp->h_addr_list; *pptr != NULL; pptr++) { h_host = acl_mycalloc(1, sizeof(ACL_HOSTNAME)); if (h_host == NULL) { acl_msg_error("%s, %s(%d): calloc error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } memset(&h_host->saddr, 0, sizeof(h_host->saddr)); n = (int) sizeof(h_host->saddr.sin_addr) > h_addrp->h_length ? h_addrp->h_length : (int) sizeof(h_host->saddr.sin_addr); memcpy(&h_host->saddr.sin_addr, *pptr, n); /* bugifx: 2009.12.8 * this is not thread safe * ACL_SAFE_STRNCPY(h_host->ip, inet_ntoa(h_host->saddr.sin_addr), sizeof(h_host->ip)); */ acl_inet_ntoa(h_host->saddr.sin_addr, h_host->ip, sizeof(h_host->ip)); if (acl_array_append(h_dns_db->h_db, h_host) < 0) { acl_msg_error("%s, %s(%d): array append error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } h_dns_db->size++; } acl_netdb_cache_push(h_dns_db, 0); return (h_dns_db); }
ACL_IFCONF *acl_get_ifaddrs() { const char *myname = "acl_get_ifaddrs"; ACL_IFCONF *ifconf; struct ifreq *ifaces; int ifaces_size = 8 * sizeof(struct ifreq); struct ifconf param; int sock; int i, j; sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock <= 0) { acl_msg_error("%s(%d): create socket error(%s)", myname, __LINE__, acl_last_serror()); return (NULL); } ifaces = acl_mymalloc(ifaces_size); for (;;) { param.ifc_len = ifaces_size; param.ifc_req = ifaces; if (ioctl(sock, SIOCGIFCONF, ¶m)) { acl_msg_error("%s(%d): ioctl error(%s)", myname, __LINE__, acl_last_serror()); close(sock); acl_myfree(ifaces); return (NULL); } if (param.ifc_len < ifaces_size) break; acl_myfree(ifaces); ifaces_size *= 2; ifaces = acl_mymalloc(ifaces_size); } close(sock); ifconf = (ACL_IFCONF*) acl_mymalloc(sizeof(ACL_IFCONF)); ifconf->length = param.ifc_len / sizeof(struct ifreq); ifconf->addrs = (ACL_IFADDR*) acl_mycalloc(ifconf->length, sizeof(ACL_IFADDR)); for (i = 0, j = 0; i < ifconf->length; i++) { if (ifaces[i].ifr_addr.sa_family != AF_INET #ifdef ACL_MACOSX && ifaces[i].ifr_addr.sa_family != AF_LINK #endif ) continue; ifconf->addrs[j].name = acl_mystrdup(ifaces[i].ifr_name); ifconf->addrs[j].addr = ((struct sockaddr_in *) &(ifaces[i].ifr_addr))->sin_addr.s_addr; acl_inet_ntoa(((struct sockaddr_in *) &ifaces[i].ifr_addr)->sin_addr, ifconf->addrs[j].ip, sizeof(ifconf->addrs[j].ip)); j++; } if (j == 0) { acl_myfree(ifconf->addrs); acl_myfree(ifconf); return (NULL); } ifconf->length = j; /* reset the ifconf->length */ /* set the iterator callback */ ifconf->iter_head = ifaddrs_iter_head; ifconf->iter_next = ifaddrs_iter_next; ifconf->iter_tail = ifaddrs_iter_tail; ifconf->iter_prev = ifaddrs_iter_prev; acl_myfree(ifaces); return (ifconf); }
#include "lib_acl.h" #include <stdio.h> #include <stdlib.h> #include "test_net.h" int test_mask_addr(AUT_LINE *test_line, void *arg acl_unused) { const char *ip; int bits; unsigned int addr; struct in_addr in; char buf[32]; AUT_SET_STR(test_line, "ip", ip); AUT_SET_INT(test_line, "bits", bits); /* addr = ntohl(inet_addr(ip)); */ addr = inet_addr(ip); acl_mask_addr((unsigned char *) &addr, sizeof(addr), bits); in.s_addr = addr; printf("i: %s, addr: %s\n", ip, acl_inet_ntoa(in, buf, sizeof(buf))); return (0); }