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

Last change on this file since 4237 was 4237, checked in by sam, 5 years ago

File descriptors 0 to 2 may be network sockets, don’t rule them out.

  • Property svn:keywords set to Id
File size: 4.6 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 4237 2010-01-08 00:48:12Z 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(allow)
118        watch = host_in_list(ip, allow);
119    else if(deny && host_in_list(ip, deny))
120        watch = 0;
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    char buf[BUFSIZ];
135    struct in_addr addr;
136    char const *parser;
137    unsigned int i, chunks, *iplist;
138    int ret;
139
140    /* Count commas */
141    for(parser = list, chunks = 1; *parser; parser++)
142        if(*parser == ',')
143            chunks++;
144
145    if(chunks >= 512)
146        iplist = malloc((chunks + 1) * sizeof(unsigned int));
147    else
148        iplist = static_list;
149
150    for(i = 0, parser = list; *parser; )
151    {
152        char *comma = strchr(parser, ',');
153
154        if (comma && (comma - parser) < BUFSIZ - 1)
155        {
156            memcpy(buf, parser, comma - parser);
157            buf[comma - parser] = '\0';
158            parser = comma + 1;
159        }
160        else if (strlen(parser) < BUFSIZ - 1)
161        {
162            strcpy(buf, parser);
163            parser += strlen(parser);
164        }
165        else
166        {
167            buf[0] = '\0';
168            parser++;
169        }
170
171        ret = inet_aton(buf, &addr);
172        if (ret)
173            iplist[i++] = addr.s_addr;
174        else
175        {
176            chunks--;
177            debug("create_host_list: skipping invalid address '%s'", parser);
178        }
179    }
180
181    iplist[i] = 0;
182
183    return iplist;
184}
185
186static int host_in_list(unsigned int value, unsigned int const *list)
187{
188    unsigned int i;
189
190    if (!value || !list)
191        return 0;
192
193    for (i = 0; list[i]; i++)
194        if (value == list[i])
195            return 1;
196
197    return 0;
198}
199
200static unsigned int get_socket_ip(int sock)
201{
202    struct sockaddr s;
203    struct sockaddr_in sin;
204    socklen_t len = sizeof(sin);
205    int ret;
206
207    /* Use a sockaddr instead of sockaddr_in because we don't know whether
208     * their alignments are compatible. So, no cast. */
209    memset(&s, 0, sizeof(sin));
210    ret = getsockname(sock, &s, &len);
211    if (ret)
212        return 0; // TODO: error handling
213
214    memcpy(&sin, &s, sizeof(sin));
215    return sin.sin_addr.s_addr;
216}
217#endif /* HAVE_SYS_SOCKET_H */
Note: See TracBrowser for help on using the repository browser.