Ignore:
Timestamp:
Oct 31, 2010, 10:36:04 AM (14 years ago)
Author:
katerina
Message:

Support for IPv6 (ticket #222).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_portcheck.c

    r290 r295  
    7474/* TIME_WAIT ? 60-240 seconds */
    7575
    76 /* the size of an interface string
    77  */
    78 #define SH_INTERFACE_SIZE 16
    79 
    80 #define SH_PORT_NOT 0
    81 #define SH_PORT_REQ 1
    82 #define SH_PORT_OPT 2
    83 #define SH_PORT_IGN 3
    84 #define SH_PORT_BLACKLIST 4
    85 
    86 #define SH_PORT_MISS 0
    87 #define SH_PORT_ISOK 1
    88 #define SH_PORT_UNKN 2
    89 
    90 #define SH_PORT_NOREPT 0
    91 #define SH_PORT_REPORT 1
    92 
    93 #define SH_PROTO_TCP 0
    94 #define SH_PROTO_UDP 1
    95 #define SH_PROTO_STR(a) (((a) == IPPROTO_TCP) ? _("tcp") : _("udp"))
    96 
    97 struct sh_portentry {
    98   int  port;
    99   char interface[SH_INTERFACE_SIZE];
    100   char * service;
    101   char * error;
    102   int  flag;    /* required or not */
    103   int  status;  /* missing or not  */
    104   struct sh_portentry * next;
    105 };
    106 
    107 static struct sh_portentry * portlist_tcp = NULL;
    108 static struct sh_portentry * portlist_udp = NULL;
    109 
    110 struct sh_port {
    111   int              port;
    112   struct in_addr   haddr;
    113   struct sh_port * next;
    114 };
    115 
    116 static struct sh_port * blacklist_tcp = NULL;
    117 static struct sh_port * blacklist_udp = NULL;
    118 
    119 #define SH_PORTCHK_INTERVAL 300
    120 
    121 static int sh_portchk_check_udp = 1;
    122 static int sh_portchk_active    = 1;
    123 static int sh_portchk_interval  = SH_PORTCHK_INTERVAL;
    12476#if !defined(TEST_ONLY)
    12577
     
    13486#include "sh_static.h"
    13587#include "sh_pthread.h"
     88#include "sh_ipvx.h"
     89
     90/* the size of an interface string
     91 */
     92#define SH_INTERFACE_SIZE SH_IP_BUF
     93
     94#define SH_PORT_NOT 0
     95#define SH_PORT_REQ 1
     96#define SH_PORT_OPT 2
     97#define SH_PORT_IGN 3
     98#define SH_PORT_BLACKLIST 4
     99
     100#define SH_PORT_MISS 0
     101#define SH_PORT_ISOK 1
     102#define SH_PORT_UNKN 2
     103
     104#define SH_PORT_NOREPT 0
     105#define SH_PORT_REPORT 1
     106
     107#define SH_PROTO_TCP 0
     108#define SH_PROTO_UDP 1
     109#define SH_PROTO_STR(a) (((a) == IPPROTO_TCP) ? _("tcp") : _("udp"))
     110
     111struct sh_portentry {
     112  int  port;
     113  char interface[SH_INTERFACE_SIZE];
     114  char * service;
     115  char * error;
     116  int  flag;    /* required or not */
     117  int  status;  /* missing or not  */
     118  struct sh_portentry * next;
     119};
     120
     121static struct sh_portentry * portlist_tcp = NULL;
     122static struct sh_portentry * portlist_udp = NULL;
     123
     124
     125#define SH_PORTCHK_INTERVAL 300
     126
     127static int sh_portchk_check_udp = 1;
     128static int sh_portchk_active    = 1;
     129static int sh_portchk_interval  = SH_PORTCHK_INTERVAL;
     130
     131struct sh_port {
     132  int                  port;
     133  struct sh_sockaddr * paddr;
     134  struct sh_port     * next;
     135};
     136
     137static struct sh_port * blacklist_tcp = NULL;
     138static struct sh_port * blacklist_udp = NULL;
    136139
    137140SH_MUTEX_STATIC(mutex_port_check, PTHREAD_MUTEX_INITIALIZER);
     
    139142static int sh_portchk_severity  = SH_ERR_SEVERE;
    140143
    141 extern char * sh_port2proc_query(int proto, struct in_addr * saddr, int sport,
     144extern char * sh_port2proc_query(int proto, struct sh_sockaddr * saddr, int sport,
    142145                                 unsigned long * pid, char * user, size_t userlen);
    143146extern int sh_port2proc_prepare();
     
    168171/* verify whether port/interface is blacklisted (do not check)
    169172 */
    170 static int sh_portchk_is_blacklisted(int port, struct in_addr haddr, int proto);
     173static int sh_portchk_is_blacklisted(int port, struct sh_sockaddr * haddr, int proto);
    171174
    172175#ifndef TEST_ONLY
     
    379382
    380383static void sh_portchk_add_to_list (int proto,
    381                                     int port, struct in_addr haddr,
     384                                    int port, struct sh_sockaddr * paddr,
    382385                                    char * service,
    383386                                    int flag, int status)
     
    390393
    391394  new->port = port;
    392   sl_strlcpy (new->interface, inet_ntoa(haddr), SH_INTERFACE_SIZE);
     395  sh_ipvx_ntoa(new->interface, SH_INTERFACE_SIZE, paddr);
    393396  new->status = status;
    394397  new->flag   = flag;
     
    459462        sh_portchk_kill_blacklist (head->next);
    460463
     464      SH_FREE(head->paddr);
    461465      SH_FREE(head);
    462466    }
     
    560564
    561565static struct sh_portentry * sh_portchk_get_from_list (int proto, int port,
    562                                                        struct in_addr haddr, char * service)
     566                                                       struct sh_sockaddr * paddr, char * service)
    563567{
    564568  struct sh_portentry * portlist;
    565   char iface_all[8];
    566 
    567   sl_strlcpy (iface_all, _("0.0.0.0"), sizeof(iface_all));
    568  
     569  char str_addr[SH_IP_BUF];
     570
    569571  if (proto == IPPROTO_TCP)
    570572    portlist = portlist_tcp;
     
    572574    portlist = portlist_udp;
    573575
     576  sh_ipvx_ntoa(str_addr, sizeof(str_addr), paddr);
     577
    574578  if (service)
    575579    {
     
    578582          if (portlist->service &&
    579583              0 == strcmp(service, portlist->service) &&
    580               (0 == strcmp(portlist->interface, inet_ntoa(haddr)) ||
    581                0 == strcmp(portlist->interface, iface_all)))
     584              ( 0 == strcmp(portlist->interface, str_addr) ||
     585                sh_ipvx_isany(paddr) ))
    582586            return portlist;
    583587          portlist = portlist->next;
     
    589593        {
    590594          if (port == portlist->port &&
    591               (0 == strcmp(portlist->interface, inet_ntoa(haddr)) ||
    592                0 == strcmp(portlist->interface, iface_all)))
     595              (0 == strcmp(portlist->interface, str_addr) ||
     596               sh_ipvx_isany(paddr) ))
    593597            return portlist;
    594598          portlist = portlist->next;
     
    599603     
    600604
    601 static void sh_portchk_cmp_to_list (int proto, int port, struct in_addr haddr, char * service)
     605static void sh_portchk_cmp_to_list (int proto, int port, struct sh_sockaddr * paddr, char * service)
    602606{
    603607  struct sh_portentry * portent;
     
    605609
    606610 
    607   portent = sh_portchk_get_from_list (proto, port, haddr, service);
     611  portent = sh_portchk_get_from_list (proto, port, paddr, service);
    608612
    609613  if (service)
     
    614618          unsigned long qpid;
    615619          char   user[USER_MAX];
     620          char   saddr[SH_IP_BUF];
     621
     622          sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
    616623
    617624          snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"),
    618                     inet_ntoa(haddr), port, SH_PROTO_STR(proto), service);
     625                    saddr, port, SH_PROTO_STR(proto), service);
    619626#ifdef TEST_ONLY
    620627          fprintf(stderr, _("open port: %s:%d/%s (%s)\n"),
    621                   inet_ntoa(haddr), port, SH_PROTO_STR(proto), service);
    622 #else
    623           path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
     628                  saddr, port, SH_PROTO_STR(proto), service);
     629#else
     630          path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
    624631          SH_MUTEX_LOCK(mutex_thread_nolog);
    625632          sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
     
    631638           * was not there, thus it is not in 'required' or 'optional' list
    632639           */
    633           sh_portchk_add_to_list (proto, port, haddr, service, SH_PORT_NOT, SH_PORT_ISOK);
     640          sh_portchk_add_to_list (proto, port, paddr, service, SH_PORT_NOT, SH_PORT_ISOK);
    634641        }
    635642      else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN)
     
    638645          unsigned long qpid;
    639646          char   user[USER_MAX];
     647          char   saddr[SH_IP_BUF];
     648
     649          sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
    640650
    641651          snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"),
    642                     inet_ntoa(haddr), port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
     652                    saddr, port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
    643653#ifdef TEST_ONLY
    644654          fprintf(stderr, _("service: %s\n"), errbuf);
    645655#else
    646           path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
     656          path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
    647657          SH_MUTEX_LOCK(mutex_thread_nolog);
    648658          sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
     
    659669          unsigned long qpid;
    660670          char   user[USER_MAX];
     671          char   saddr[SH_IP_BUF];
     672
     673          sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
    661674
    662675          snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"),
    663                     inet_ntoa(haddr), port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
     676                    saddr, port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
    664677#ifdef TEST_ONLY
    665678          fprintf(stderr, _("service: %s\n"), errbuf);
    666679#else
    667           path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
     680          path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
    668681          SH_MUTEX_LOCK(mutex_thread_nolog);
    669682          sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
     
    687700          unsigned long qpid;
    688701          char   user[USER_MAX];
     702          char   saddr[SH_IP_BUF];
     703
     704          sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
    689705
    690706          snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"),
    691                     inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto));
     707                    saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
    692708#ifdef TEST_ONLY
    693709          fprintf(stderr, _("open port: %s:%d/%s (%s)\n"),
    694                   inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto));
    695 #else
    696           path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
     710                  saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
     711#else
     712          path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
    697713          SH_MUTEX_LOCK(mutex_thread_nolog);
    698714          sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
     
    704720          /* was not there, thus it is not in 'required' or 'optional' list
    705721           */
    706           sh_portchk_add_to_list (proto, port, haddr, service, SH_PORT_NOT, SH_PORT_ISOK);
     722          sh_portchk_add_to_list (proto, port, paddr, service, SH_PORT_NOT, SH_PORT_ISOK);
    707723        }
    708724      else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN)
     
    711727          unsigned long qpid;
    712728          char   user[USER_MAX];
     729          char   saddr[SH_IP_BUF];
     730
     731          sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
    713732
    714733          snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"),
    715                     inet_ntoa(haddr), port, SH_PROTO_STR(proto), check_services(port, proto));
     734                    saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
    716735#ifdef TEST_ONLY
    717736          fprintf(stderr, _("port   : %s\n"), errbuf);
    718737#else
    719           path = sh_port2proc_query(proto, &haddr, port, &qpid, user, sizeof(user));
     738          path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
    720739          SH_MUTEX_LOCK(mutex_thread_nolog);
    721740          sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
     
    799818}
    800819
    801 static int check_port_udp_internal (int fd, int port, struct in_addr haddr)
    802 {
    803   struct sockaddr_in sinr;
    804   /* struct in_addr     haddr; */
     820static int check_port_udp_internal (int fd, int port, struct sh_sockaddr * paddr)
     821{
    805822  int                retval;
    806   char             * p;
     823  char             * p = NULL;
    807824  char               buf[8];
    808825#ifndef TEST_ONLY
     
    811828#endif
    812829  char errbuf[SH_ERRBUF_SIZE];
    813 
    814   /* inet_aton(interface, &haddr); */
    815 
    816   sinr.sin_family = AF_INET;
    817   sinr.sin_port   = htons (port);
    818   sinr.sin_addr   = haddr;
     830  char ipbuf[SH_IP_BUF];
     831
     832  sh_ipvx_set_port(paddr, port);
    819833
    820834  do {
    821     retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
     835    retval = connect(fd, sh_ipvx_sockaddr_cast(paddr), SH_SSP_LEN(paddr));
    822836  } while (retval < 0 && (errno == EINTR || errno == EINPROGRESS));
    823837
     
    828842        perror(_("connect"));
    829843#else
     844      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     845
    830846      nerr = errno;
    831847      sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/udp on %15s: %s"),
    832                   port, inet_ntoa(haddr), sh_error_message(errno, errbuf, sizeof(errbuf)));
     848                  port, ipbuf, sh_error_message(errno, errbuf, sizeof(errbuf)));
    833849      SH_MUTEX_LOCK(mutex_thread_nolog);
    834850      sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN,
     
    845861      if (retval == -1 && errno == ECONNREFUSED)
    846862        {
     863          sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    847864          if (portchk_debug)
    848865            fprintf(stderr, _("check port: %5d/udp on %15s established/time_wait\n"),
    849                     port, inet_ntoa(haddr));
     866                    port, ipbuf);
    850867        }
    851868      else
     
    859876          if (retval == -1 && errno == ECONNREFUSED)
    860877            {
     878              sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    861879              if (portchk_debug)
    862880                fprintf(stderr, _("check port: %5d/udp on %15s established/time_wait\n"),
    863                         port, inet_ntoa(haddr));
     881                        port, ipbuf);
    864882            }
    865883          else if (retval != -1)
     
    867885              /* Try to get service name from portmap
    868886               */
    869               p = check_rpc_list (port, &sinr, IPPROTO_UDP);
     887              if (paddr->ss_family == AF_INET)
     888                {
     889                  p = check_rpc_list (port, (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr), IPPROTO_UDP);
     890                }
    870891             
    871               sh_portchk_cmp_to_list (IPPROTO_UDP, port, haddr, p ? p : NULL);
     892              sh_portchk_cmp_to_list (IPPROTO_UDP, port, paddr, p ? p : NULL);
    872893             
    873894              /* If not an RPC service, try to get name from /etc/services
     
    877898             
    878899              if (portchk_debug)
    879                 fprintf(stderr, _("check port: %5d/udp on %15s open %s\n"),
    880                         port, inet_ntoa(haddr), p);
     900                {
     901                  sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     902                  fprintf(stderr, _("check port: %5d/udp on %15s open %s\n"),
     903                          port, ipbuf, p);
     904                }
    881905             
    882906            }
     
    887911}
    888912
    889 static int check_port_tcp_internal (int fd, int port, struct in_addr haddr)
    890 {
    891   struct sockaddr_in sinr;
    892   /* struct in_addr     haddr; */
     913static int check_port_tcp_internal (int fd, int port, struct sh_sockaddr * paddr)
     914{
    893915  int                retval;
    894916  int                flags;
    895   char             * p;
     917  char             * p = NULL;
    896918#ifndef TEST_ONLY
    897919  char               errmsg[256];
     
    899921#endif
    900922  char errbuf[SH_ERRBUF_SIZE];
    901 
    902   /* inet_aton(interface, &haddr); */
    903 
    904   sinr.sin_family = AF_INET;
    905   sinr.sin_port   = htons (port);
    906   sinr.sin_addr   = haddr;
     923  char ipbuf[SH_IP_BUF];
     924
     925  sh_ipvx_set_port(paddr, port);
    907926
    908927  do {
    909     retval = connect(fd, (struct sockaddr *) &sinr, sizeof(sinr));
     928    retval = connect(fd, sh_ipvx_sockaddr_cast(paddr), SH_SSP_LEN(paddr));
    910929  } while (retval < 0 && (errno == EINTR || errno == EINPROGRESS));
    911930
     
    913932    {
    914933      if (portchk_debug)
    915         fprintf(stderr, _("check port: %5d on %15s established/time_wait\n"),
    916                 port, inet_ntoa(haddr));
     934        {
     935          sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     936          fprintf(stderr, _("check port: %5d on %15s established/time_wait\n"),
     937                  port, ipbuf);
     938        }
    917939    }
    918940  else if (retval == -1)
     
    922944        perror(_("connect"));
    923945#else
     946      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
    924947      nerr = errno;
    925948      sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/tcp on %15s: %s"),
    926                   port, inet_ntoa(haddr), sh_error_message(errno, errbuf, sizeof(errbuf)));
     949                  port, ipbuf, sh_error_message(errno, errbuf, sizeof(errbuf)));
    927950      SH_MUTEX_LOCK(mutex_thread_nolog);
    928951      sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN,
     
    935958      /* Try to get service name from portmap
    936959       */
    937       p = check_rpc_list (port, &sinr, IPPROTO_TCP);
    938 
    939       sh_portchk_cmp_to_list (IPPROTO_TCP, port, haddr, p ? p : NULL);
     960      if (paddr->ss_family == AF_INET)
     961        {
     962          p = check_rpc_list (port, (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr), IPPROTO_TCP);
     963        }
     964
     965      sh_portchk_cmp_to_list (IPPROTO_TCP, port, paddr, p ? p : NULL);
    940966
    941967      /* If not an RPC service, try to get name from /etc/services
     
    945971
    946972      if (portchk_debug)
    947         fprintf(stderr, _("check port: %5d on %15s open %s\n"),
    948                 port, inet_ntoa(haddr), p);
     973        {
     974          sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
     975          fprintf(stderr, _("check port: %5d on %15s open %s\n"),
     976                  port, ipbuf, p);
     977        }
    949978
    950979#if !defined(O_NONBLOCK)
     
    10111040
    10121041struct portchk_interfaces {
    1013   struct in_addr iface[SH_IFACE_MAX];
     1042  struct sh_sockaddr iface[SH_IFACE_MAX];
    10141043  int            used;
    10151044};
     
    10261055static int sh_portchk_init_internal (void)
    10271056{
    1028   struct hostent * hent;
    10291057  volatile int     i; /* might be clobbered by ‘longjmp’ or ‘vfork’*/
    10301058  char errbuf[256];
     1059#if defined(USE_IPVX)
     1060  struct addrinfo hints;
     1061  struct addrinfo *res;
     1062#else
     1063  struct hostent * hent;
     1064#endif
     1065  char ipbuf[SH_IP_BUF];
    10311066
    10321067  if (portchk_debug)
     
    10451080      iface_initialized = 1;
    10461081    }
    1047            
     1082
     1083#if !defined(USE_IPVX)
    10481084  SH_MUTEX_LOCK(mutex_resolv);
    10491085  hent = sh_gethostbyname(portchk_hostname);
     
    10511087  while (hent && hent->h_addr_list[i] && (iface_list.used < SH_IFACE_MAX))
    10521088    {
    1053       memcpy (&(iface_list.iface[iface_list.used].s_addr), hent->h_addr_list[i], sizeof(in_addr_t));
     1089      struct sockaddr_in sin;
     1090
     1091      memcpy(&(sin.sin_addr.s_addr), hent->h_addr_list[i], sizeof(in_addr_t));
     1092      sh_ipvx_save(&(iface_list.iface[iface_list.used]),
     1093                   AF_INET, (struct sockaddr *)&sin);
    10541094      ++iface_list.used;
    10551095      ++i;
    10561096    }
    10571097  SH_MUTEX_UNLOCK(mutex_resolv);
     1098#else
     1099  memset(&hints, '\0', sizeof(hints));
     1100  hints.ai_family = PF_UNSPEC;
     1101  hints.ai_flags  = AI_ADDRCONFIG;
     1102
     1103  if (0 == getaddrinfo(portchk_hostname, NULL, &hints, &res))
     1104    {
     1105      struct addrinfo *p = res;
     1106
     1107      while ((p != NULL) && (iface_list.used < SH_IFACE_MAX))
     1108        {
     1109          sh_ipvx_save(&(iface_list.iface[iface_list.used]),
     1110                       p->ai_family, p->ai_addr);
     1111          ++iface_list.used;
     1112          p = p->ai_next;
     1113        }
     1114      freeaddrinfo(res);
     1115    }
     1116#endif
    10581117
    10591118  for (i = 0; i < iface_list.used; ++i)
    10601119    {
    1061       sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"),
    1062                   inet_ntoa(iface_list.iface[i]));
     1120      sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), &(iface_list.iface[i]));
     1121      sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), ipbuf);
     1122
    10631123      SH_MUTEX_LOCK(mutex_thread_nolog);
    10641124      sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN,
     
    11361196#endif
    11371197
    1138 static int check_port_generic (int port, int type, int protocol)
     1198static int check_port_generic (int port, int domain, int type, int protocol)
    11391199{
    11401200  volatile int     i    =  0;
    11411201  int              sock = -1;
    11421202  int              flag =  1; /* non-zero to enable an option */
    1143   struct in_addr   haddr;
     1203  struct sh_sockaddr   paddr;
    11441204  char errbuf[SH_ERRBUF_SIZE];
    11451205
     
    11481208  while (i < iface_list.used)
    11491209    {
    1150       haddr.s_addr = iface_list.iface[i].s_addr;
    1151 
    1152       if (0 != sh_portchk_is_blacklisted(port, haddr, protocol))
    1153         {
    1154           ++i; continue;
    1155         }
    1156 
    1157       if ((sock = socket(AF_INET, type, protocol)) < 0 )
     1210      memcpy(&paddr, &(iface_list.iface[i]), sizeof(paddr));
     1211
     1212      if (paddr.ss_family != domain)
     1213        {
     1214          ++i;
     1215          continue;
     1216        }
     1217
     1218      if (0 != sh_portchk_is_blacklisted(port, &paddr, protocol))
     1219        {
     1220          ++i;
     1221          continue;
     1222        }
     1223
     1224      if ((sock = socket(paddr.ss_family, type, protocol)) < 0 )
    11581225        {
    11591226          ++i;
     
    11871254
    11881255      if (protocol == IPPROTO_TCP)
    1189         check_port_tcp_internal(sock, port, haddr);
     1256        check_port_tcp_internal(sock, port, &paddr);
    11901257      else
    1191         check_port_udp_internal(sock, port, haddr);
     1258        check_port_udp_internal(sock, port, &paddr);
    11921259
    11931260      ++i;
     
    11991266
    12001267
    1201 static int check_port_udp (int port)
    1202 {
    1203   return check_port_generic(port, SOCK_DGRAM, IPPROTO_UDP);
    1204 }
    1205 
    1206 static int check_port_tcp (int port)
    1207 {
    1208   return check_port_generic(port, SOCK_STREAM, IPPROTO_TCP);
    1209 }
    1210 
    1211 
    1212 
    1213 static int sh_portchk_scan_ports_generic (int min_port, int max_port_arg, int type, int protocol)
     1268static int check_port_udp (int port, int domain)
     1269{
     1270  return check_port_generic(port, domain, SOCK_DGRAM, IPPROTO_UDP);
     1271}
     1272
     1273static int check_port_tcp (int port, int domain)
     1274{
     1275  return check_port_generic(port, domain, SOCK_STREAM, IPPROTO_TCP);
     1276}
     1277
     1278
     1279static int sh_portchk_scan_ports_generic (int min_port, int max_port_arg,
     1280                                          int domain, int type, int protocol)
    12141281{
    12151282  /*
     
    12241291  int flag   = 1; /* non-zero to enable an option */
    12251292
    1226   struct sockaddr_in addr;
    1227   int addrlen      = sizeof(addr);
     1293  struct sockaddr_in  addr4;
     1294  struct sockaddr_in6 addr6;
     1295
     1296  int addrlen4      = sizeof(addr4);
     1297  int addrlen6      = sizeof(addr6);
     1298
     1299  struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
     1300
    12281301  char errbuf[SH_ERRBUF_SIZE];
    12291302
     
    12351308  for (port = min_port; port <= max_port; ++port)
    12361309    {
    1237       if ((sock = socket(AF_INET, type, protocol)) < 0 )
     1310      if ((sock = socket(domain, type, protocol)) < 0 )
    12381311        {
    12391312#ifdef TEST_ONLY
     
    12631336        }
    12641337
    1265       addr.sin_family      = AF_INET;
    1266       addr.sin_port        = htons(port);
    1267       addr.sin_addr.s_addr = INADDR_ANY;
    1268 
    1269       retval = bind (sock, (struct sockaddr *) &addr, addrlen);
     1338      if (domain == AF_INET)
     1339        {
     1340          addr4.sin_family      = AF_INET;
     1341          addr4.sin_port        = htons(port);
     1342          addr4.sin_addr.s_addr = INADDR_ANY;
     1343          retval = bind (sock, (struct sockaddr *) &addr4, addrlen4);
     1344        }
     1345      else
     1346        {
     1347          addr6.sin6_family       = AF_INET6;
     1348          addr6.sin6_port         = htons(port);
     1349          memcpy(&(addr6.sin6_addr.s6_addr), &anyaddr, sizeof(anyaddr));
     1350          retval = bind (sock, (struct sockaddr *) &addr6, addrlen6);
     1351        }
    12701352
    12711353      if (retval == 0)
     
    12821364               */
    12831365              if (protocol == IPPROTO_TCP)
    1284                 check_port_tcp(port);
     1366                check_port_tcp(port, domain);
    12851367              else
    1286                 check_port_udp(port);
     1368                check_port_udp(port, domain);
    12871369            }
    12881370          else
     
    13061388static int sh_portchk_scan_ports_tcp (int min_port, int max_port)
    13071389{
    1308   return sh_portchk_scan_ports_generic (min_port, max_port, SOCK_STREAM, IPPROTO_TCP);
     1390#if defined(USE_IPVX)
     1391  sh_portchk_scan_ports_generic (min_port, max_port, AF_INET6,
     1392                                 SOCK_STREAM, IPPROTO_TCP);
     1393#endif
     1394  return sh_portchk_scan_ports_generic (min_port, max_port, AF_INET,
     1395                                        SOCK_STREAM, IPPROTO_TCP);
    13091396}
    13101397 
    13111398static int sh_portchk_scan_ports_udp (int min_port, int max_port)
    13121399{
    1313   return sh_portchk_scan_ports_generic (min_port, max_port, SOCK_DGRAM, IPPROTO_UDP);
     1400#if defined(USE_IPVX)
     1401  sh_portchk_scan_ports_generic (min_port, max_port, AF_INET6,
     1402                                 SOCK_DGRAM, IPPROTO_UDP);
     1403#endif
     1404  return sh_portchk_scan_ports_generic (min_port, max_port, AF_INET,
     1405                                        SOCK_DGRAM, IPPROTO_UDP);
    13141406}
    13151407
     
    13201412static int sh_portchk_add_interface (const char * str)
    13211413{
    1322   struct in_addr   haddr;
     1414  struct sh_sockaddr saddr;
    13231415  char errbuf[256];
    13241416  char buf[64];
     
    13381430    if (*str)
    13391431      {
     1432        char ipbuf[SH_IP_BUF];
    13401433        unsigned int i = 0;
    1341         while (*str && i < (sizeof(buf)-1) && *str != ',' && *str != ' ' && *str != '\t')
     1434        while (*str && i < (sizeof(buf)-1) &&
     1435               *str != ',' && *str != ' ' && *str != '\t')
    13421436          {
    13431437            buf[i] = *str; ++str; ++i;
     
    13451439        buf[i] = '\0';
    13461440
    1347         if (0 == inet_aton(buf, &haddr))
     1441        if (0 == sh_ipvx_aton(buf, &saddr))
    13481442          return -1;
    13491443
     
    13511445          return -1;
    13521446
    1353         sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), inet_ntoa(haddr));
     1447        sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), &saddr);
     1448        sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), ipbuf);
    13541449        SH_MUTEX_LOCK(mutex_thread_nolog);
    13551450        sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN,
     
    13571452        SH_MUTEX_UNLOCK(mutex_thread_nolog);
    13581453       
    1359         memcpy (&(iface_list.iface[iface_list.used].s_addr), &(haddr.s_addr), sizeof(in_addr_t));
     1454        memcpy (&(iface_list.iface[iface_list.used]), &(saddr), sizeof(saddr));
    13601455        ++iface_list.used;
    13611456      }
     
    13671462/* verify whether port/interface is blacklisted (do not check)
    13681463 */
    1369 static int sh_portchk_is_blacklisted(int port, struct in_addr haddr, int proto)
     1464static int sh_portchk_is_blacklisted(int port, struct sh_sockaddr * saddr,
     1465                                     int proto)
    13701466{
    13711467  struct sh_port * head;
     
    13801476      if (head->port == port)
    13811477        {
    1382           if ((head->haddr.s_addr == 0) || (head->haddr.s_addr == haddr.s_addr))
     1478          if (sh_ipvx_isany(head->paddr) ||
     1479              0 == sh_ipvx_cmp(head->paddr, saddr))
    13831480            return 1;
    13841481          else
     
    13911488
    13921489
    1393 static int sh_portchk_blacklist(int port, struct in_addr haddr, int proto)
     1490static int sh_portchk_blacklist(int port, struct sh_sockaddr * saddr, int proto)
    13941491{
    13951492  struct sh_port * black;
     
    14051502  while (black)
    14061503    {
    1407       if (black->port == port && head->haddr.s_addr == haddr.s_addr)
     1504      if (black->port == port &&
     1505          0 == sh_ipvx_cmp(head->paddr, saddr))
    14081506        return -1;
    14091507      black = black->next;
    14101508    }
     1509
    14111510  black = SH_ALLOC (sizeof(struct sh_port));
     1511  black->paddr = SH_ALLOC (sizeof(struct sh_sockaddr));
    14121512  black->port  = port;
    1413   black->haddr.s_addr = haddr.s_addr;
     1513  memcpy(black->paddr, saddr, sizeof(struct sh_sockaddr));
    14141514  black->next  = head;
    14151515
     
    14241524/* Subroutine to add a required or optional port/service
    14251525 */
    1426 static int sh_portchk_add_required_port_generic (char * service, char * interface, int type)
     1526static int sh_portchk_add_required_port_generic (char * service,
     1527                                                 char * interface, int type)
    14271528{
    14281529  char buf[256];
     
    14311532  char * endptr;
    14321533  unsigned long int  port;
    1433   struct in_addr   haddr;
     1534  struct sh_sockaddr   saddr;
    14341535  struct sh_portentry * portent;
    14351536
    1436   if (0 == inet_aton(interface, &haddr))
     1537  if (0 == sh_ipvx_aton(interface, &saddr))
    14371538    return -1;
    14381539
     
    14551556   */
    14561557  if (*endptr == '\0' && port <= 65535 && type == SH_PORT_BLACKLIST)
    1457     return (sh_portchk_blacklist(port, haddr, proto));
     1558    return (sh_portchk_blacklist(port, &saddr, proto));
    14581559
    14591560  if (*endptr != '\0')
    14601561    { 
    1461       portent = sh_portchk_get_from_list (proto, -1, haddr, buf);
     1562      portent = sh_portchk_get_from_list (proto, -1, &saddr, buf);
    14621563      if (!portent)
    1463         sh_portchk_add_to_list (proto,   -1, haddr,  buf, type, SH_PORT_UNKN);
     1564        sh_portchk_add_to_list (proto,   -1, &saddr,  buf, type, SH_PORT_UNKN);
    14641565      else
    14651566        {
     
    14771578  else if (port <= 65535)
    14781579    {
    1479       portent = sh_portchk_get_from_list (proto, port, haddr, NULL);
     1580      portent = sh_portchk_get_from_list (proto, port, &saddr, NULL);
    14801581      if (!portent)
    1481         sh_portchk_add_to_list (proto, port, haddr, NULL, type, SH_PORT_UNKN);
     1582        sh_portchk_add_to_list (proto, port, &saddr, NULL, type, SH_PORT_UNKN);
    14821583      else
    14831584        {
     
    16691770{
    16701771#if defined(SH_USE_PORTCHECK) && (defined(SH_WITH_CLIENT) || defined(SH_STANDALONE))
    1671   struct in_addr   haddr_local;
     1772  struct sh_sockaddr    haddr_local;
    16721773  struct sh_portentry * portent;
    16731774  char   buf[256];
     
    17041805  CuAssertTrue(tc, 0 == strcmp(buf, "daytime"));
    17051806
    1706   CuAssertTrue(tc, 0 != inet_aton("127.0.0.1", &haddr_local));
    1707 
    1708   sh_portchk_add_to_list (IPPROTO_TCP,  8000, haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
    1709 
    1710   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, NULL);
     1807  CuAssertTrue(tc, 0 != sh_ipvx_aton("127.0.0.1", &haddr_local));
     1808
     1809  sh_portchk_add_to_list (IPPROTO_TCP,  8000, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
     1810
     1811  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, NULL);
    17111812  CuAssertPtrNotNull(tc, portent);
    17121813
     
    17201821  CuAssertTrue(tc, NULL == portlist_tcp);
    17211822
    1722   sh_portchk_add_to_list (IPPROTO_TCP,  8000, haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
    1723   sh_portchk_add_to_list (IPPROTO_TCP,  8001, haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
    1724   sh_portchk_add_to_list (IPPROTO_TCP,  8002, haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
    1725   sh_portchk_add_to_list (IPPROTO_TCP,  8003, haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
    1726   sh_portchk_add_to_list (IPPROTO_TCP,  8004, haddr_local, NULL, SH_PORT_IGN, SH_PORT_UNKN);
    1727   sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo1", SH_PORT_NOT, SH_PORT_UNKN);
    1728   sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo2", SH_PORT_REQ, SH_PORT_UNKN);
    1729   sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo3", SH_PORT_NOT, SH_PORT_UNKN);
    1730   sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo4", SH_PORT_REQ, SH_PORT_UNKN);
    1731   sh_portchk_add_to_list (IPPROTO_TCP,    -1, haddr_local, "foo5", SH_PORT_IGN, SH_PORT_UNKN);
     1823  sh_portchk_add_to_list (IPPROTO_TCP,  8000, &haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
     1824  sh_portchk_add_to_list (IPPROTO_TCP,  8001, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
     1825  sh_portchk_add_to_list (IPPROTO_TCP,  8002, &haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
     1826  sh_portchk_add_to_list (IPPROTO_TCP,  8003, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
     1827  sh_portchk_add_to_list (IPPROTO_TCP,  8004, &haddr_local, NULL, SH_PORT_IGN, SH_PORT_UNKN);
     1828  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo1", SH_PORT_NOT, SH_PORT_UNKN);
     1829  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo2", SH_PORT_REQ, SH_PORT_UNKN);
     1830  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo3", SH_PORT_NOT, SH_PORT_UNKN);
     1831  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo4", SH_PORT_REQ, SH_PORT_UNKN);
     1832  sh_portchk_add_to_list (IPPROTO_TCP,    -1, &haddr_local, "foo5", SH_PORT_IGN, SH_PORT_UNKN);
    17321833
    17331834  sh_portchk_check_list (&portlist_tcp, IPPROTO_TCP, SH_PORT_NOREPT);
     
    17351836  CuAssertPtrNotNull(tc, portlist_tcp);
    17361837
    1737   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, NULL);
     1838  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, NULL);
    17381839  CuAssertPtrNotNull(tc, portent);
    17391840
    1740   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8001, haddr_local, NULL);
     1841  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8001, &haddr_local, NULL);
    17411842  CuAssertTrue(tc, NULL == portent);
    17421843
    1743   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8002, haddr_local, NULL);
     1844  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8002, &haddr_local, NULL);
    17441845  CuAssertPtrNotNull(tc, portent);
    17451846
    1746   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8003, haddr_local, NULL);
     1847  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8003, &haddr_local, NULL);
    17471848  CuAssertTrue(tc, NULL == portent);
    17481849
    1749   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8004, haddr_local, NULL);
     1850  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8004, &haddr_local, NULL);
    17501851  CuAssertPtrNotNull(tc, portent);
    17511852
    1752   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo1");
     1853  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo1");
    17531854  CuAssertTrue(tc, NULL == portent);
    17541855
    1755   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo2");
     1856  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo2");
    17561857  CuAssertPtrNotNull(tc, portent);
    17571858  CuAssertTrue(tc, 0 == strcmp(portent->service, "foo2"));
    17581859
    1759   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo3");
     1860  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo3");
    17601861  CuAssertTrue(tc, NULL == portent);
    17611862
    1762   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo4");
     1863  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo4");
    17631864  CuAssertPtrNotNull(tc, portent);
    17641865  CuAssertTrue(tc, 0 == strcmp(portent->service, "foo4"));
    17651866
    1766   portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, haddr_local, "foo5");
     1867  portent = sh_portchk_get_from_list(IPPROTO_TCP,  8000, &haddr_local, "foo5");
    17671868  CuAssertPtrNotNull(tc, portent);
    17681869  CuAssertTrue(tc, 0 == strcmp(portent->service, "foo5"));
    17691870
    1770   CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, haddr_local, IPPROTO_TCP));
    1771   CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, haddr_local, IPPROTO_TCP));
    1772   CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, haddr_local, IPPROTO_TCP));
    1773   CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, haddr_local, IPPROTO_TCP));
    1774   CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, haddr_local, IPPROTO_UDP));
    1775   CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, haddr_local, IPPROTO_UDP));
    1776   CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, haddr_local, IPPROTO_UDP));
    1777   CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, haddr_local, IPPROTO_UDP));
    1778 
    1779   CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, haddr_local, IPPROTO_UDP));
    1780   CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, haddr_local, IPPROTO_UDP));
    1781   CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, haddr_local, IPPROTO_UDP));
    1782   CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, haddr_local, IPPROTO_UDP));
    1783 
    1784   CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, haddr_local, IPPROTO_TCP));
    1785   CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, haddr_local, IPPROTO_TCP));
    1786   CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, haddr_local, IPPROTO_TCP));
    1787   CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, haddr_local, IPPROTO_TCP));
     1871  CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, &haddr_local, IPPROTO_TCP));
     1872  CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, &haddr_local, IPPROTO_TCP));
     1873  CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, &haddr_local, IPPROTO_TCP));
     1874  CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, &haddr_local, IPPROTO_TCP));
     1875  CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, &haddr_local, IPPROTO_UDP));
     1876  CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, &haddr_local, IPPROTO_UDP));
     1877  CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, &haddr_local, IPPROTO_UDP));
     1878  CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, &haddr_local, IPPROTO_UDP));
     1879
     1880  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, &haddr_local, IPPROTO_UDP));
     1881  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, &haddr_local, IPPROTO_UDP));
     1882  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, &haddr_local, IPPROTO_UDP));
     1883  CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, &haddr_local, IPPROTO_UDP));
     1884
     1885  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, &haddr_local, IPPROTO_TCP));
     1886  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, &haddr_local, IPPROTO_TCP));
     1887  CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, &haddr_local, IPPROTO_TCP));
     1888  CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, &haddr_local, IPPROTO_TCP));
    17881889#else
    17891890  (void) tc; /* fix compiler warning */
Note: See TracChangeset for help on using the changeset viewer.