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

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

Fix copyright information and remove Id tag everywhere.

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