"Fossies" - the Fresh Open Source Software Archive

Member "socat-1.7.3.2/xio-ip4.c" (6 Jan 2017, 4699 Bytes) of package /linux/privat/socat-1.7.3.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "xio-ip4.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.7.3.1_vs_1.7.3.2.

    1 /* source: xio-ip4.c */
    2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
    3 /* Published under the GNU General Public License V.2, see file COPYING */
    4 
    5 /* this file contains the source for IP4 related functions */
    6 
    7 #include "xiosysincludes.h"
    8 
    9 #if WITH_IP4
   10 
   11 #include "xioopen.h"
   12 #include "xio-socket.h"
   13 #include "xio-ip.h"
   14 #include "xio-ip4.h"
   15 
   16 
   17 int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) {
   18    struct hostent *maskaddr;
   19    struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
   20    struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
   21    char *rangename1;    /* a copy of rangename with writing allowed */
   22    char *delimpos;  /* absolute address of delimiter */
   23    unsigned int bits;   /* netmask bits */
   24 
   25    if ((rangename1 = strdup(rangename)) == NULL) {
   26       Error1("strdup(\"%s\"): out of memory", rangename);
   27       return STAT_RETRYLATER;
   28    }
   29 
   30    if (delimpos = strchr(rangename1, '/')) {
   31       char *endptr;
   32       bits = strtoul(delimpos+1, &endptr, 10);
   33       if (! ((*(delimpos+1) != '\0') && (*endptr == '\0'))) {
   34      Error1("not a valid netmask in \"%s\"", rangename);
   35      bits = 32; /* most secure selection */
   36       } else if (bits > 32) {
   37      Error1("netmask \"%s\" is too large", rangename);
   38      bits = 32;
   39       }
   40       if (bits <= 0) {
   41      netmask_in->s_addr = 0;
   42       } else {
   43      netmask_in->s_addr = htonl((0xffffffff << (32-bits)));
   44       }
   45    } else if (delimpos = strchr(rangename1, ':')) {
   46       if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) {
   47      /* note: cast is req on AIX: */
   48      Error2("gethostbyname(\"%s\"): %s", delimpos+1,
   49         h_errno == NETDB_INTERNAL ? strerror(errno) :
   50         (char *)hstrerror(h_errno));
   51      return STAT_NORETRY;
   52       }
   53       netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0];
   54    } else {
   55       Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename);
   56       free(rangename1);
   57       return STAT_NORETRY;
   58    }
   59    {
   60       struct hostent *nameaddr;
   61       *delimpos = 0;
   62       if ((nameaddr = Gethostbyname(rangename1)) == NULL) {
   63      /* note: cast is req on AIX: */
   64      Error2("gethostbyname(\"%s\"): %s", rangename1,
   65         h_errno == NETDB_INTERNAL ? strerror(errno) :
   66         (char *)hstrerror(h_errno));
   67         free(rangename1);
   68      return STAT_NORETRY;
   69       }
   70       netaddr_in->s_addr = *(uint32_t *)nameaddr->h_addr_list[0];
   71    }
   72    free(rangename1);
   73    return STAT_OK;
   74 }
   75 
   76 /* check if peer address is within permitted range.
   77    return >= 0 if so. */
   78 int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range) {
   79    struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
   80    struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
   81    char addrbuf[256], maskbuf[256];
   82    char peername[256];
   83 
   84    /* is provided client address valid? */
   85    if (pa->sin_addr.s_addr == 0) {
   86       Warn("invalid client address 0.0.0.0");
   87       return -1;
   88    }
   89    /* client address restriction */
   90    Debug2("permitted client subnet: %s:%s",
   91       inet4addr_info(ntohl(netaddr_in->s_addr), addrbuf, sizeof(addrbuf)),
   92       inet4addr_info(ntohl(netmask_in->s_addr), maskbuf, sizeof(maskbuf)));
   93    Debug1("client address is 0x%08x",
   94       ntohl(pa->sin_addr.s_addr));
   95    Debug1("masked address is 0x%08x",
   96       ntohl(pa->sin_addr.s_addr & netmask_in->s_addr));
   97    if ((pa->sin_addr.s_addr & netmask_in->s_addr)
   98        != netaddr_in->s_addr) {
   99       Debug1("client address %s is not permitted",
  100          sockaddr_inet4_info(pa, peername, sizeof(peername)));
  101       return -1;
  102    }
  103    return 0;
  104 }
  105 
  106 /* returns information that can be used for constructing an environment
  107    variable describing the socket address.
  108    if idx is 0, this function writes "ADDR" into namebuff and the IP address
  109    into valuebuff, and returns 1 (which means that one more info is there).
  110    if idx is 1, it writes "PORT" into namebuff and the port number into
  111    valuebuff, and returns 0 (no more info)
  112    namelen and valuelen contain the max. allowed length of output chars in the
  113    respective buffer.
  114    on error this function returns -1.
  115 */
  116 int
  117 xiosetsockaddrenv_ip4(int idx, char *namebuff, size_t namelen,
  118               char *valuebuff, size_t valuelen,
  119               struct sockaddr_in *sa, int ipproto) {
  120    switch (idx) {
  121    case 0:
  122       strcpy(namebuff, "ADDR");
  123       inet4addr_info(ntohl(sa->sin_addr.s_addr), valuebuff, valuelen);
  124       switch (ipproto) {
  125       case IPPROTO_TCP:
  126       case IPPROTO_UDP:
  127 #ifdef IPPROTO_SCTP
  128       case IPPROTO_SCTP:
  129 #endif
  130      return 1;  /* there is port information to also be retrieved */
  131       default:
  132      return 0;  /* no port info coming */
  133       }
  134    case 1:
  135       strcpy(namebuff, "PORT");
  136       snprintf(valuebuff, valuelen, "%u", ntohs(sa->sin_port));
  137       return 0;
  138    }
  139    return -1;
  140 }
  141 
  142 #endif /* WITH_IP4 */