PageRenderTime 32ms CodeModel.GetById 24ms app.highlight 5ms RepoModel.GetById 0ms app.codeStats 0ms

/boa-0.94.14rc21/src/ip.c

#
C | 139 lines | 80 code | 7 blank | 52 comment | 9 complexity | d2177b7571f0975ffc85a6e8dd3826c7 MD5 | raw file
Possible License(s): GPL-2.0
  1/*
  2 *  Boa, an http server
  3 *  Copyright (C) 1999 Larry Doolittle <ldoolitt@boa.org>
  4 *  Copyright (C) 2000-2003 Jon Nelson <jnelson@boa.org>
  5 *
  6 *  This program is free software; you can redistribute it and/or modify
  7 *  it under the terms of the GNU General Public License as published by
  8 *  the Free Software Foundation; either version 1, or (at your option)
  9 *  any later version.
 10 *
 11 *  This program is distributed in the hope that it will be useful,
 12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 *  GNU General Public License for more details.
 15 *
 16 *  You should have received a copy of the GNU General Public License
 17 *  along with this program; if not, write to the Free Software
 18 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 19 *
 20 *
 21
 22  Encapsulation of ipv4 and ipv6 stuff, try to get rid of the ifdef's
 23  elsewhere in the code.
 24
 25  The IPv6 code here is based on contributions from Martin Hinner <martin@tdp.cz>
 26  and Arkadiusz Miskiewicz <misiek@misiek.eu.org>.  This incarnation of that
 27  code is untested.  The original IPv4 code is based on original Boa code
 28  from Paul Phillips <paulp@go2net.com>.
 29
 30  A goal is to compile in as many families as are supported, and
 31  make the final choice at runtime.
 32
 33globals.h:
 34#ifdef INET6
 35	char remote_ip_addr[BOA_NI_MAXHOST];
 36#else
 37	char remote_ip_addr[20];        after inet_ntoa
 38#endif
 39
 40    None of this code interacts with the rest of Boa except through
 41    the parameter lists and return values.
 42
 43    Consider making these functions __inline__ and using this as a .h file
 44    */
 45
 46#include "boa.h"
 47#include <arpa/inet.h>          /* inet_ntoa */
 48
 49/* Binds to the existing server_s, based on the configuration string
 50   in server_ip.  IPv6 version doesn't pay attention to server_ip yet.  */
 51int bind_server(int sock, char *ip, unsigned int port)
 52{
 53#ifdef INET6
 54    struct sockaddr_in6 server_sockaddr;
 55    server_sockaddr.sin6_family = PF_INET6;
 56    memcpy(&server_sockaddr.sin6_addr, &in6addr_any, sizeof (in6addr_any));
 57    server_sockaddr.sin6_port = htons(server_port);
 58#else
 59    struct sockaddr_in server_sockaddr;
 60    memset(&server_sockaddr, 0, sizeof server_sockaddr);
 61#ifdef HAVE_SIN_LEN             /* uncomment for BSDs */
 62    server_sockaddr.sin_len = sizeof server_sockaddr;
 63#endif
 64    server_sockaddr.sin_family = PF_INET;
 65    if (ip != NULL) {
 66#ifdef HAVE_INET_ATON
 67        inet_aton(ip, &server_sockaddr.sin_addr);
 68#elif defined HAVE_INET_ADDR
 69        server_sockaddr.sin_addr.s_addr = inet_addr(ip);
 70#else
 71#error "Neither inet_aton nor inet_addr exist!"
 72#endif
 73    } else {
 74        server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 75    }
 76    server_sockaddr.sin_port = htons(port);
 77#endif
 78
 79    return bind(sock, (struct sockaddr *) &server_sockaddr,
 80                sizeof (server_sockaddr));
 81}
 82
 83char *ascii_sockaddr(struct SOCKADDR *s, char *dest, unsigned int len)
 84{
 85#ifdef INET6
 86    if (getnameinfo((struct sockaddr *) s,
 87                    sizeof (struct SOCKADDR),
 88                    dest, len, NULL, 0, NI_NUMERICHOST)) {
 89        fprintf(stderr, "[IPv6] getnameinfo failed\n");
 90        *dest = '\0';
 91    }
 92#ifdef WHEN_DOES_THIS_APPLY
 93#error Dont use memmove
 94    if ((s->__ss_family == PF_INET6) &&
 95        IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *) s)->sin6_addr))) {
 96#error The following two lines are broken
 97        memmove(dest, dest + 7, BOA_NI_MAXHOST);
 98        dest[BOA_NI_MAXHOST] = '\0';
 99    }
100#endif /* ifdef WHEN_DOES_THIS_APPLY */
101#else  /* ifdef INET6 */
102    unsigned int newlen;
103    char *buf;
104
105    /*    memmove(dest, inet_ntoa(s->sin_addr), len); */
106    buf = inet_ntoa(s->sin_addr);
107    newlen = strlen(buf);
108    /* we need newlen + 1 byte to be <= len, thus
109     * newlen <= len - 1 is good
110     * and newlen > len -1 is bad thus
111     *     newlen + 1 > len ==== newlen >= len
112     */
113    if (newlen + 1 > len) { /* too many bytes incl. the NUL */
114        return NULL;
115    }
116    memcpy(dest, buf, newlen);
117    dest[newlen] = '\0';
118#endif /* ifdef INET6 */
119    return dest;
120}
121
122int net_port(struct SOCKADDR *s)
123{
124    int p = -1;
125#ifdef INET6
126    char serv[NI_MAXSERV];
127
128    if (getnameinfo((struct sockaddr *) s,
129                    sizeof (struct SOCKADDR),
130                    NULL, 0, serv, sizeof (serv), NI_NUMERICSERV)) {
131        fprintf(stderr, "[IPv6] getnameinfo failed\n");
132    } else {
133        p = atoi(serv);
134    }
135#else
136    p = ntohs(s->sin_port);
137#endif
138    return p;
139}