source: zzuf/trunk/src/network.c @ 3635

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

Allow remote network host filtering, courtesy of Corentin Delorme.

  • Property svn:keywords set to Id
File size: 4.0 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 3635 2009-08-06 21:17:00Z 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#include <sys/socket.h>
30#include <netinet/in.h>
31#include <arpa/inet.h>
32
33#include "libzzuf.h"
34#include "debug.h"
35#include "ranges.h"
36#include "network.h"
37
38static unsigned int get_socket_ip(int);
39static int host_in_list(unsigned int, unsigned int const *);
40static unsigned int *create_host_list(char const *, unsigned int *);
41
42/* Network IP cherry picking */
43static unsigned int *allow = NULL;
44static unsigned int static_allow[512];
45static unsigned int *deny = NULL;
46static unsigned int static_deny[512];
47
48/* Network port cherry picking */
49static int *ports = NULL;
50static int static_ports[512];
51
52void _zz_network_init(void)
53{
54    ;
55}
56
57void _zz_network_fini(void)
58{
59    if(ports != static_ports)
60        free(ports);
61    if(allow != static_allow)
62        free(allow);
63    if(deny != static_deny)
64        free(deny);
65}
66
67void _zz_allow(char const *allowlist)
68{
69    allow = create_host_list(allowlist, static_allow);
70}
71
72void _zz_deny(char const *denylist)
73{
74    deny = create_host_list(denylist, static_deny);
75}
76
77void _zz_ports(char const *portlist)
78{
79    ports = _zz_allocrange(portlist, static_ports);
80}
81
82int _zz_portwatched(int port)
83{
84    if(!ports)
85        return 1;
86
87    return _zz_isinrange(port, ports);
88}
89
90int _zz_hostwatched(int sock)
91{
92    int watch = 1;
93    unsigned int ip;
94
95    if(!allow && !deny)
96        return 1;
97
98    ip = get_socket_ip(sock);
99
100    if(deny && host_in_list(ip, deny))
101        watch = 0;
102    if(allow)
103        watch = host_in_list(ip, allow);
104
105    return watch;
106}
107
108/* XXX: the following functions are local */
109
110static unsigned int *create_host_list(char const *list,
111                                      unsigned int *static_list)
112{
113    int ret;
114    char *copy;
115    char *parser;
116    struct in_addr addr;
117    unsigned int i, chunks, len, *iplist;
118
119    len = strlen(list);
120    copy = malloc(len + 1);
121    if (!copy) {
122        // TODO better error handling
123        perror("malloc");
124        exit(EXIT_FAILURE);
125    }
126    strncpy(copy, list, len);
127    copy[len] = 0;
128
129    /* Count commas */
130    for(parser = copy, chunks = 1; *parser; parser++)
131        if(*parser == ',')
132            chunks++;
133
134    if(chunks >= 512)
135        iplist = malloc((chunks + 1) * sizeof(unsigned int));
136    else
137        iplist = static_list;
138
139    for(parser = copy, i = 0; i < chunks; i++)
140    {
141        char *comma = strchr(parser, ',');
142        if (comma)
143            *comma = 0;
144
145        ret = inet_aton(parser, &addr);
146        if (ret)
147            iplist[i] = addr.s_addr;
148        else {
149            i--;
150            chunks--;
151            debug("create_host_list: Invalid IP address '%s'. Skipping it.", parser);
152        }
153        parser = comma + 1;
154    }
155
156    iplist[i] = 0;
157    free(copy);
158
159    return iplist;
160}
161
162static int host_in_list(unsigned int value, unsigned int const *list)
163{
164    unsigned int i;
165
166    if (!value || !list)
167        return 0;
168
169    for (i = 0; list[i]; i++)
170        if (value == list[i])
171            return 1;
172
173    return 0;
174}
175
176static unsigned int get_socket_ip(int sock)
177{
178    int ret;
179    struct sockaddr_in sin;
180    socklen_t len = sizeof(sin);
181
182    // Probably not a socket descriptor
183    if (sock < 3)
184        return 0;
185
186    memset(&sin, 0, sizeof(sin));
187    ret = getsockname(sock, &sin, &len);
188    if (ret) {
189        // TODO error handling
190        return 0;
191    }
192
193    return sin.sin_addr.s_addr;
194}
195
Note: See TracBrowser for help on using the repository browser.