*** /dev/null Sat Nov 23 01:15:56 2024
--- - Sat Nov 23 01:16:01 2024
***************
*** 0 ****
--- 1,212 ----
+ /*
+ ** L2 - OSSP Logging Library
+ ** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
+ ** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
+ **
+ ** This file is part of OSSP L2, a flexible logging library which
+ ** can be found at http://www.ossp.org/pkg/l2/.
+ **
+ ** Permission to use, copy, modify, and distribute this software for
+ ** any purpose with or without fee is hereby granted, provided that
+ ** the above copyright notice and this permission notice appear in all
+ ** copies.
+ **
+ ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+ ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ ** SUCH DAMAGE.
+ **
+ ** l2_ut_sa.c: utility library for socket address handling
+ */
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <ctype.h>
+ #include <errno.h>
+ #include <netdb.h>
+ #include <sys/types.h>
+ #include <sys/un.h>
+ #include <netinet/in.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+
+ #include "l2_config.h"
+ #include "l2_ut_sa.h"
+
+ #if !defined(AF_LOCAL) && defined(AF_UNIX)
+ #define AF_LOCAL AF_UNIX
+ #endif
+
+ #ifndef HAVE_INET_PTON
+ #ifdef HAVE_INET_ATON
+ static int inet_pton(int family, const char *strptr, void *addrptr)
+ {
+ struct in_addr in_val;
+
+ if (family == AF_INET) {
+ if (inet_aton(strptr, &in_val)) {
+ memcpy(addrptr, &in_val, sizeof(struct in_addr));
+ return 1;
+ }
+ return 0;
+ }
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+ #else
+ #error "neither inet_pton nor inet_aton available"
+ #endif
+ #endif
+
+ #ifndef NUL
+ #define NUL '\0'
+ #endif
+
+ l2_util_sa_t *l2_util_sa_create(int sa_type, ...)
+ {
+ va_list ap;
+ l2_util_sa_t *rc;
+ int nPort;
+ socklen_t sl;
+ struct sockaddr *sa;
+ struct sockaddr_in sa4;
+ #ifdef AF_INET6
+ struct sockaddr_in6 sa6;
+ #endif
+ struct sockaddr_un sau;
+ struct hostent *he;
+ struct servent *se;
+ struct protoent *pe;
+ int bNumeric;
+ int i;
+ char *cpPath;
+ int nPath;
+ char *cpProto;
+ int nProto;
+ char *cpHost;
+ char *cpPort;
+
+ va_start(ap, sa_type);
+ sa = NULL;
+ sl = 0;
+ if (sa_type == SA_UNIX) {
+ #if defined(AF_LOCAL)
+ if ((cpPath = va_arg(ap, char *)) == NULL)
+ return NULL;
+ if ((nPath = strlen(cpPath)) >= (sizeof(sau.sun_path)-1))
+ return NULL;
+ nProto = 0;
+ sau.sun_family = AF_LOCAL;
+ memcpy(sau.sun_path, cpPath, nPath + 1);
+ sa = (struct sockaddr *)&sau;
+ sl = sizeof(sau);
+ #else
+ return NULL;
+ #endif
+ }
+ else if (sa_type == SA_IP) {
+ if ((cpProto = va_arg(ap, char *)) == NULL)
+ return NULL;
+ if ((cpHost = va_arg(ap, char *)) == NULL)
+ return NULL;
+ if ((cpPort = va_arg(ap, char *)) == NULL)
+ return NULL;
+
+ /* resolve protocol */
+ if ((pe = getprotobyname(cpProto)) == NULL)
+ return NULL;
+ nProto = pe->p_proto;
+
+ /* resolve port */
+ bNumeric = 1;
+ for (i = 0; cpPort[i] != NUL; i++) {
+ if (!isdigit((int)cpPort[i])) {
+ bNumeric = 0;
+ break;
+ }
+ }
+ if (bNumeric)
+ nPort = atoi(cpPort);
+ else {
+ if ((se = getservbyname(cpPort, cpProto)) == NULL)
+ return NULL;
+ nPort = ntohs(se->s_port);
+ }
+
+ /* resolve host */
+ if (inet_pton(AF_INET, cpHost, &sa4.sin_addr.s_addr) == 1) {
+ sa4.sin_family = AF_INET;
+ sa4.sin_port = htons(nPort);
+ sa = (struct sockaddr *)&sa4;
+ sl = sizeof(sa4);
+ }
+ #ifdef AF_INET6
+ else if (inet_pton(AF_INET6, cpHost, &sa6.sin6_addr.s6_addr) == 1) {
+ sa6.sin6_family = AF_INET6;
+ sa6.sin6_port = htons(nPort);
+ sa = (struct sockaddr *)&sa6;
+ sl = sizeof(sa6);
+ }
+ #endif
+ else if ((he = gethostbyname(cpHost)) != NULL) {
+ if (he->h_addrtype == AF_INET) {
+ sa4.sin_family = AF_INET;
+ sa4.sin_port = htons(nPort);
+ memcpy(&sa4.sin_addr.s_addr, he->h_addr_list[0], sizeof(sa4.sin_addr.s_addr));
+ sa = (struct sockaddr *)&sa4;
+ sl = sizeof(sa4);
+ }
+ #ifdef AF_INET6
+ else if (he->h_addrtype == AF_INET6) {
+ sa6.sin6_family = AF_INET6;
+ sa6.sin6_port = htons(nPort);
+ memcpy(&sa6.sin6_addr.s6_addr, he->h_addr_list[0], sizeof(sa6.sin6_addr.s6_addr));
+ sa = (struct sockaddr *)&sa6;
+ sl = sizeof(sa6);
+ }
+ #endif
+ }
+ }
+ else
+ return NULL;
+ va_end(ap);
+
+ if (sa == NULL)
+ return NULL;
+
+ if ((rc = (l2_util_sa_t *)malloc(sizeof(l2_util_sa_t))) == NULL)
+ return NULL;
+ if ((rc->sa_buf = (struct sockaddr *)malloc(sl)) == NULL) {
+ free(rc);
+ return NULL;
+ }
+ memcpy(rc->sa_buf, sa, sl);
+ rc->sa_len = sl;
+ rc->sa_proto = nProto;
+
+ return rc;
+ }
+
+ void l2_ut_sa_destroy(l2_util_sa_t *sa)
+ {
+ if (sa == NULL)
+ return;
+
+ if (sa->sa_buf != NULL)
+ free(sa->sa_buf);
+ free(sa);
+
+ return;
+ }
+
|