"Fossies" - the Fresh Open Source Software Archive

Member "tcpproxy-2.0.0-beta15/ip-lib.c" (30 Aug 2007, 8563 Bytes) of package /linux/privat/old/tcpproxy-2.0.0-beta15.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 "ip-lib.c" see the Fossies "Dox" file reference documentation.

    1 
    2 /*
    3 
    4     File: ip-lib.c
    5 
    6     Copyright (C) 1999,2004-2007  Wolfgang Zekoll  <wzk@quietsche-entchen.de>
    7   
    8     This software is free software; you can redistribute it and/or modify
    9     it under the terms of the GNU General Public License as published by
   10     the Free Software Foundation; either version 2 of the License, or
   11     (at your option) any later version.
   12   
   13     This program is distributed in the hope that it will be useful,
   14     but WITHOUT ANY WARRANTY; without even the implied warranty of
   15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16     GNU General Public License for more details.
   17   
   18     You should have received a copy of the GNU General Public License
   19     along with this program; if not, write to the Free Software
   20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   21 
   22  */
   23  
   24 #include <stdlib.h>
   25 #include <stdio.h>
   26 #include <string.h>
   27 #include <ctype.h>
   28 
   29 #include <signal.h>
   30 #include <syslog.h>
   31 
   32 #include <unistd.h>
   33 #include <sys/types.h>
   34 #include <sys/socket.h>
   35 #include <sys/wait.h>
   36 #include <netinet/in.h>
   37 #include <arpa/inet.h>
   38 #include <net/if.h>
   39 #include <sys/ioctl.h>
   40 #include <netdb.h>
   41 #include <errno.h>
   42 
   43 #include "lib.h"
   44 #include "ip-lib.h"
   45 #include "tcpproxy.h"
   46 
   47 
   48 int issock(int pfd)
   49 {
   50     unsigned int size;
   51     struct sockaddr_in saddr;
   52 
   53     size = sizeof(saddr);
   54     if (getsockname(pfd, (struct sockaddr *) &saddr, &size) < 0)
   55         return (1);
   56 
   57     return (0);
   58 }
   59 
   60 unsigned int get_interface_info(int pfd, peer_t *sock)
   61 {
   62     unsigned int size;
   63     struct sockaddr_in saddr;
   64 
   65     size = sizeof(saddr);
   66     if (getsockname(pfd, (struct sockaddr *) &saddr, &size) < 0)
   67         printerror(1, "-ERR", "can't get sockname, error= %s", strerror(errno));
   68 
   69     copy_string(sock->ipnum, (char *) inet_ntoa(saddr.sin_addr), sizeof(sock->ipnum));
   70     sock->port = ntohs(saddr.sin_port);
   71     copy_string(sock->name, sock->ipnum, sizeof(sock->name));
   72 
   73     return (sock->port);
   74 }
   75 
   76 int get_client_info(int pfd, peer_t *peer, int ipnumonly)
   77 {
   78     unsigned int port;
   79     unsigned int size;
   80     struct sockaddr_in saddr;
   81 
   82     *peer->ipnum = 0;
   83     *peer->name  = 0;
   84     size = sizeof(saddr);
   85     if (getpeername(pfd, (struct sockaddr *) &saddr, &size) < 0)
   86         printerror(1, "-ERR", "can't get peername, error= %s", strerror(errno));
   87 
   88     copy_string(peer->ipnum, (char *) inet_ntoa(saddr.sin_addr), sizeof(peer->ipnum));
   89     peer->port = ntohs(saddr.sin_port);
   90     copy_string(peer->name, peer->ipnum, sizeof(peer->name));
   91 
   92     if (ipnumonly == 0) {
   93         struct in_addr *addr;
   94         struct hostent *hostp = NULL;
   95 
   96         addr = &saddr.sin_addr;
   97         hostp = gethostbyaddr((char *) addr,
   98                 sizeof (saddr.sin_addr.s_addr), AF_INET);
   99 
  100         if (hostp != NULL) {
  101             copy_string(peer->name, hostp->h_name, sizeof(peer->name));
  102             strlwr(peer->name);
  103             }
  104         }
  105 
  106     port = ntohs(saddr.sin_port);
  107     return (port);
  108 }
  109 
  110 
  111 int openip(char *host, unsigned int port, char *srcip, unsigned int srcport,
  112             peer_t *peer)
  113 {
  114     int socketd;
  115     char    *p;
  116     struct sockaddr_in server;
  117     struct hostent *hostp, *gethostbyname();
  118 
  119     socketd = socket(AF_INET, SOCK_STREAM, 0);
  120     if (socketd < 0)
  121         return (-1);
  122   
  123     if (srcip != NULL  &&  *srcip != 0) {
  124         struct sockaddr_in laddr;
  125 
  126         if (srcport != 0) {
  127             int one;
  128 
  129             one = 1;
  130             setsockopt (socketd, SOL_SOCKET, SO_REUSEADDR, (int *) &one, sizeof(one));
  131             }
  132  
  133         /*
  134              * Bind local socket to srcport and srcip
  135              */
  136 
  137         memset(&laddr, 0, sizeof(laddr));
  138         laddr.sin_family = AF_INET;
  139         laddr.sin_port   = htons(srcport);
  140 
  141         if (srcip == NULL  ||  *srcip == 0)
  142             srcip = "0.0.0.0";
  143         else {
  144             struct hostent *ifp;
  145  
  146             ifp = gethostbyname(srcip);
  147             if (ifp == NULL) {
  148                 close (socketd);
  149                 return (-1);
  150                 }
  151  
  152             memcpy(&laddr.sin_addr, ifp->h_addr, ifp->h_length);
  153             }
  154  
  155         if (bind(socketd, (struct sockaddr *) &laddr, sizeof(laddr))) {
  156             close (socketd);
  157             return (-2);
  158             }
  159         }
  160 
  161 
  162     server.sin_family = AF_INET;
  163     p = host;
  164     while (*(p = skip_ws(p)) != 0) {
  165         get_quoted(&p, ',', peer->name, sizeof(peer->name));
  166         noctrl(peer->name);
  167         if (*peer->name == 0)
  168             continue;
  169 
  170         peer->port = get_port(peer->name, port);
  171         
  172         hostp = gethostbyname(peer->name);
  173         if (hostp == NULL) {
  174             printerror(0 | ERR_INFO, "-INFO", "can't lookup server %s:%u, error= %s",
  175                     peer->name, peer->port, strerror(errno));
  176             continue;
  177             }
  178 
  179         memcpy(&server.sin_addr, hostp->h_addr, hostp->h_length);
  180         server.sin_port = htons(peer->port);
  181         copy_string(peer->ipnum, (char *) inet_ntoa(server.sin_addr), sizeof(peer->ipnum));
  182 
  183         if (connect(socketd, (struct sockaddr *) &server, sizeof(server)) >= 0)
  184             return (socketd);
  185         else {
  186             printerror(0 | ERR_INFO, "-INFO", "can't connect to server %s:%u, error= %s",
  187                     peer->name, peer->port, strerror(errno));
  188             }
  189         }
  190 
  191     close (socketd);
  192     return (-1);
  193 }   
  194 
  195 unsigned int getportnum(char *name)
  196 {
  197     unsigned int port;
  198     struct servent *portdesc;
  199     
  200     if (isdigit(*name) != 0)
  201         port = atol(name);
  202     else {
  203         portdesc = getservbyname(name, "tcp");
  204         if (portdesc == NULL) {
  205             fprintf (stderr, "%s: service not found: %s\n", program, name);
  206             exit (1);
  207             }
  208 
  209         port = ntohs(portdesc->s_port);
  210         if (port == 0) {
  211             fprintf (stderr, "%s: port error: %s\n", program, name);
  212             exit (1);
  213             }
  214         }
  215     
  216     return (port);
  217 }
  218 
  219 unsigned int get_port(char *server, unsigned int def_port)
  220 {
  221     unsigned int port;
  222     char    *p;
  223 
  224     if ((p = strchr(server, ':')) == NULL)
  225         return (def_port);
  226 
  227     *p++ = 0;
  228     port = getportnum(p);
  229 
  230     return (port);
  231 }
  232 
  233 int bind_to_port(char *interface, unsigned int port)
  234 {
  235     struct sockaddr_in saddr;
  236     int sock;
  237     char    *ipnum;
  238 
  239     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  240         fprintf (stderr, "%s: can't create socket\n", program);
  241         exit (1);
  242         }
  243     else {
  244         int opt;
  245 
  246         opt = 1;
  247         setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  248         }
  249 
  250 
  251     memset(&saddr, 0, sizeof(saddr));
  252     saddr.sin_family = AF_INET;
  253     saddr.sin_port   = htons(port);
  254 
  255     ipnum = interface;
  256     if (ipnum == NULL  ||  *ipnum == 0)
  257         ipnum = "0.0.0.0";
  258     else {
  259         struct hostent *ifp;
  260 
  261         ifp = gethostbyname(ipnum);
  262         if (ifp == NULL)
  263             printerror(1, "-ERR", "can't resolve name: %s, error= %s", ipnum, strerror(errno));
  264 
  265         memcpy(&saddr.sin_addr, ifp->h_addr, ifp->h_length);
  266         }
  267         
  268         
  269     if (bind(sock, (struct sockaddr *) &saddr, sizeof(saddr)))
  270         printerror(1, "-ERR", "can't bind to %s:%u, error= %s", ipnum, port, strerror(errno));
  271 
  272     if (listen(sock, 5) < 0)
  273         printerror(1, "-ERR", "can't listen on %s:%u, error= %s", ipnum, port, strerror(errno));
  274 
  275     return (sock);
  276 }
  277 
  278 
  279 int get_phyint_addr(char *interface, char *ipnum, int size)
  280 {
  281     int sock;
  282     struct ifreq ifrr;
  283 
  284     ifrr.ifr_addr.sa_family = AF_INET;
  285     copy_string(ifrr.ifr_name, interface, sizeof(ifrr.ifr_name));
  286 
  287     if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
  288         printerror(1, "", "can't allocate socket, error= %s", strerror(errno));
  289 
  290     if (ioctl(sock, SIOCGIFADDR, &ifrr) < 0) {
  291         close (sock);
  292         return (-1);
  293         }
  294 
  295     close (sock);
  296     copy_string(ipnum, (char *) inet_ntoa(((struct sockaddr_in *) &ifrr.ifr_addr)->sin_addr), size - 2);
  297 
  298     return (0);
  299 }
  300 
  301 
  302 
  303 unsigned long atoip(char *string, char **r, int *error)
  304 {
  305     int i, k;
  306     unsigned long num;
  307     char    *p;
  308 
  309     *error = 0;
  310     num    = 0;
  311 
  312     p = string;
  313     for (i=0; i < 4  &&  *p != 0; i++) {
  314         k = (unsigned) strtol(p, &p, 10);
  315         if (k < 0  ||  k > 255) {
  316             *error = 1;
  317             return (1);
  318             }
  319 
  320         num = (num << 8) + k;
  321         if (*p == '.') {
  322             p++;
  323             if (isdigit(*p) == 0) {
  324                 *error = 1;
  325                 return (1);
  326                 }
  327             }
  328         else if (i != 3) {
  329             *error = 1;
  330             return (1);
  331             }
  332         }
  333 
  334     if (r != NULL)
  335         *r = p;
  336 
  337     return (num);
  338 }
  339 
  340 int checkacl(char *acl, char *ipnum, int rc)
  341 {
  342     unsigned long ip, adr, mask, weight;
  343     int allowdeny, error, len;
  344     char    *r, *p, word[80];
  345 
  346 /* printerror(0, "+DEBUG", "acl= %s", acl); */
  347     if (*acl == 0)
  348         return (rc);
  349 
  350     weight = 0;
  351     ip = atoip(ipnum, &p, &error);
  352     r = acl;
  353     while (*get_word(&r, word, sizeof(word)) != 0) {
  354         p = word;
  355         if (*p == '+') {
  356             allowdeny = ACL_ALLOW;
  357             p++;
  358             }
  359         else if (*p == '-') {
  360             allowdeny = ACL_DENY;
  361             p++;
  362             }
  363         else
  364             allowdeny = ACL_ALLOW;
  365 
  366         adr = atoip(p, &p, &error);
  367 /* printerror(0, "+DEBUG", "word= %s, adr= %08X, p= %s",
  368  *              word, adr, p);
  369  */
  370         if (error != 0)
  371             return (ACL_DENY);
  372 
  373         mask = 0xFFFFFFFF;
  374         if (*p == '/') {
  375             p++;
  376             if (strchr(p, '.') != NULL)
  377                 mask = atoip(p, &p, &error);
  378             else {
  379                 len = strtoul(p, &p, 10);
  380                 mask = 0xFFFFFFFF << (32 - len);
  381                 }
  382 
  383 /* printerror(0, "+DEBUG", "word= %s, adr= %08X, mask= %08X, ip= %08X, weight= %08X",
  384  *              word, adr, mask, ip, weight);
  385  */
  386 
  387             if (*p != 0  ||  error != 0)
  388                 return (ACL_DENY);
  389             }
  390 
  391         if (mask > weight) {
  392             if ((ip & mask) == (adr & mask))
  393                 rc = allowdeny;
  394             }
  395         }
  396 
  397     return (rc);
  398 }
  399