source: zzuf/trunk/src/libzzuf/network.c @ 4112

Last change on this file since 4112 was 4112, checked in by Sam Hocevar, 11 years ago

Reorganise source code to better separate zzuf and libzzuf. Note: the Win32
build is now broken.

  • Property svn:keywords set to Id
File size: 4.5 KB
Line 
1/*
2 *  zzuf - general purpose fuzzer
3 *  Copyright (c) 2006-2009 Sam Hocevar <sam@hocevar.net>
4 *                All Rights Reserved
5 *
6 *  $Id: network.c 4112 2009-12-12 22:19:47Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15/*
16 *  network.c: network connection helper functions
17 */
18
19#include "config.h"
20
21#if defined HAVE_STDINT_H
22#   include <stdint.h>
23#elif defined HAVE_INTTYPES_H
24#   include <inttypes.h>
25#endif
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#if defined HAVE_SYS_SOCKET_H
30#   include <sys/socket.h>
31#   include <netinet/in.h>
32#   include <arpa/inet.h>
33#endif
34
35#include "libzzuf.h"
36#include "debug.h"
37#include "ranges.h"
38#include "network.h"
39
40#if defined HAVE_SYS_SOCKET_H
41static unsigned int get_socket_ip(int);
42static int host_in_list(unsigned int, unsigned int const *);
43static unsigned int *create_host_list(char const *, unsigned int *);
44
45/* Network IP cherry picking */
46static unsigned int *allow = NULL;
47static unsigned int static_allow[512];
48static unsigned int *deny = NULL;
49static unsigned int static_deny[512];
50
51/* Network port cherry picking */
52static int *ports = NULL;
53static int static_ports[512];
54#endif
55
56void _zz_network_init(void)
57{
58    ;
59}
60
61void _zz_network_fini(void)
62{
63#if defined HAVE_SYS_SOCKET_H
64    if(ports != static_ports)
65        free(ports);
66    if(allow != static_allow)
67        free(allow);
68    if(deny != static_deny)
69        free(deny);
70#endif
71}
72
73void _zz_allow(char const *allowlist)
74{
75#if defined HAVE_SYS_SOCKET_H
76    allow = create_host_list(allowlist, static_allow);
77#endif
78}
79
80void _zz_deny(char const *denylist)
81{
82#if defined HAVE_SYS_SOCKET_H
83    deny = create_host_list(denylist, static_deny);
84#endif
85}
86
87void _zz_ports(char const *portlist)
88{
89#if defined HAVE_SYS_SOCKET_H
90    ports = _zz_allocrange(portlist, static_ports);
91#endif
92}
93
94int _zz_portwatched(int port)
95{
96#if defined HAVE_SYS_SOCKET_H
97    if(!ports)
98        return 1;
99
100    return _zz_isinrange(port, ports);
101#else
102    return 0;
103#endif
104}
105
106int _zz_hostwatched(int sock)
107{
108#if defined HAVE_SYS_SOCKET_H
109    int watch = 1;
110    unsigned int ip;
111
112    if(!allow && !deny)
113        return 1;
114
115    ip = get_socket_ip(sock);
116
117    if(deny && host_in_list(ip, deny))
118        watch = 0;
119    if(allow)
120        watch = host_in_list(ip, allow);
121
122    return watch;
123#else
124    return 0;
125#endif
126}
127
128/* XXX: the following functions are local */
129
130#if defined HAVE_SYS_SOCKET_H
131static unsigned int *create_host_list(char const *list,
132                                      unsigned int *static_list)
133{
134    int ret;
135    char *copy;
136    char *parser;
137    struct in_addr addr;
138    unsigned int i, chunks, len, *iplist;
139
140    len = strlen(list);
141    copy = malloc(len + 1);
142    if (!copy) {
143        // TODO better error handling
144        perror("malloc");
145        exit(EXIT_FAILURE);
146    }
147    strncpy(copy, list, len);
148    copy[len] = 0;
149
150    /* Count commas */
151    for(parser = copy, chunks = 1; *parser; parser++)
152        if(*parser == ',')
153            chunks++;
154
155    if(chunks >= 512)
156        iplist = malloc((chunks + 1) * sizeof(unsigned int));
157    else
158        iplist = static_list;
159
160    for(parser = copy, i = 0; i < chunks; i++)
161    {
162        char *comma = strchr(parser, ',');
163        if (comma)
164            *comma = 0;
165
166        ret = inet_aton(parser, &addr);
167        if (ret)
168            iplist[i] = addr.s_addr;
169        else {
170            i--;
171            chunks--;
172            debug("create_host_list: Invalid IP address '%s'. Skipping it.", parser);
173        }
174        parser = comma + 1;
175    }
176
177    iplist[i] = 0;
178    free(copy);
179
180    return iplist;
181}
182
183static int host_in_list(unsigned int value, unsigned int const *list)
184{
185    unsigned int i;
186
187    if (!value || !list)
188        return 0;
189
190    for (i = 0; list[i]; i++)
191        if (value == list[i])
192            return 1;
193
194    return 0;
195}
196
197static unsigned int get_socket_ip(int sock)
198{
199    struct sockaddr s;
200    struct sockaddr_in sin;
201    socklen_t len = sizeof(sin);
202    int ret;
203
204    // Probably not a socket descriptor
205    if (sock < 3)
206        return 0;
207
208    /* Use a sockaddr instead of sockaddr_in because we don't know whether
209     * their alignments are compatible. So, no cast. */
210    memset(&s, 0, sizeof(sin));
211    ret = getsockname(sock, &s, &len);
212    if (ret)
213        return 0; // TODO: error handling
214
215    memcpy(&sin, &s, sizeof(sin));
216    return sin.sin_addr.s_addr;
217}
218#endif /* HAVE_SYS_SOCKET_H */
Note: See TracBrowser for help on using the repository browser.