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

Last change on this file since 4834 was 4834, checked in by wisk, 8 years ago

add new hook for windows (CreateFileMapping?(A|W), MapViewOfFile?, ReadFileEx?), re-enable option -U, start to port network on windows

  • Property svn:keywords set to Id
File size: 5.0 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#elif defined HAVE_WINSOCK2_H
32#   include <WinSock2.h>
33#   include <WS2tcpip.h>
34#endif
35
36#include "libzzuf.h"
37#include "debug.h"
38#include "ranges.h"
39#include "network.h"
40
41#if defined HAVE_SYS_SOCKET_H || defined (HAVE_WINDOWS_H)
42static unsigned int get_socket_ip(int);
43static int host_in_list(unsigned int, unsigned int const *);
44static unsigned int *create_host_list(char const *, unsigned int *);
45
46/* Network IP cherry picking */
47static unsigned int *allow = NULL;
48static unsigned int static_allow[512];
49static unsigned int *deny = NULL;
50static unsigned int static_deny[512];
51
52/* Network port cherry picking */
53static int64_t *ports = NULL;
54static int64_t static_ports[512];
55#endif
56
57void _zz_network_init(void)
58{
59#ifdef HAVE_WINSOCK2_H
60    WSADATA wsa_data;
61    WSAStartup(MAKEWORD(2,2), &wsa_data); /* LATER: handle error */
62#endif
63}
64
65void _zz_network_fini(void)
66{
67#if defined HAVE_SYS_SOCKET_H || defined (HAVE_WINDOWS_H)
68    if(ports != static_ports)
69        free(ports);
70    if(allow != static_allow)
71        free(allow);
72    if(deny != static_deny)
73        free(deny);
74#endif
75
76#if defined HAVE_WINSOCK2_H
77    WSACleanup(); /* LATER: handle error */
78#endif
79}
80
81void _zz_allow(char const *allowlist)
82{
83#if defined HAVE_SYS_SOCKET_H || defined (HAVE_WINDOWS_H)
84    allow = create_host_list(allowlist, static_allow);
85#endif
86}
87
88void _zz_deny(char const *denylist)
89{
90#if defined HAVE_SYS_SOCKET_H || defined (HAVE_WINDOWS_H)
91    deny = create_host_list(denylist, static_deny);
92#endif
93}
94
95void _zz_ports(char const *portlist)
96{
97#if defined HAVE_SYS_SOCKET_H || defined (HAVE_WINDOWS_H)
98    ports = _zz_allocrange(portlist, static_ports);
99#endif
100}
101
102int _zz_portwatched(int port)
103{
104#if defined HAVE_SYS_SOCKET_H || defined (HAVE_WINDOWS_H)
105    if(!ports)
106        return 1;
107
108    return _zz_isinrange(port, ports);
109#else
110    return 0;
111#endif
112}
113
114int _zz_hostwatched(int sock)
115{
116#if defined HAVE_SYS_SOCKET_H || defined (HAVE_WINDOWS_H)
117    int watch = 1;
118    unsigned int ip;
119
120    if(!allow && !deny)
121        return 1;
122
123    ip = get_socket_ip(sock);
124
125    if(allow)
126        watch = host_in_list(ip, allow);
127    else if(deny && host_in_list(ip, deny))
128        watch = 0;
129
130    return watch;
131#else
132    return 0;
133#endif
134}
135
136/* XXX: the following functions are local */
137
138#if defined HAVE_SYS_SOCKET_H || defined HAVE_WINSOCK2_H
139static unsigned int *create_host_list(char const *list,
140                                      unsigned int *static_list)
141{
142    char buf[BUFSIZ];
143    struct in_addr addr;
144    char const *parser;
145    unsigned int i, chunks, *iplist;
146    int ret;
147
148    /* Count commas */
149    for(parser = list, chunks = 1; *parser; parser++)
150        if(*parser == ',')
151            chunks++;
152
153    if(chunks >= 512)
154        iplist = malloc((chunks + 1) * sizeof(unsigned int));
155    else
156        iplist = static_list;
157
158    for(i = 0, parser = list; *parser; )
159    {
160        char *comma = strchr(parser, ',');
161
162        if (comma && (comma - parser) < BUFSIZ - 1)
163        {
164            memcpy(buf, parser, comma - parser);
165            buf[comma - parser] = '\0';
166            parser = comma + 1;
167        }
168        else if (strlen(parser) < BUFSIZ - 1)
169        {
170            strcpy(buf, parser);
171            parser += strlen(parser);
172        }
173        else
174        {
175            buf[0] = '\0';
176            parser++;
177        }
178
179        ret = inet_pton(AF_INET, buf, &addr);
180        if (ret)
181            iplist[i++] = addr.s_addr;
182        else
183        {
184            chunks--;
185            debug("create_host_list: skipping invalid address '%s'", parser);
186        }
187    }
188
189    iplist[i] = 0;
190
191    return iplist;
192}
193
194static int host_in_list(unsigned int value, unsigned int const *list)
195{
196    unsigned int i;
197
198    if (!value || !list)
199        return 0;
200
201    for (i = 0; list[i]; i++)
202        if (value == list[i])
203            return 1;
204
205    return 0;
206}
207
208static unsigned int get_socket_ip(int sock)
209{
210    struct sockaddr s;
211    struct sockaddr_in sin;
212    socklen_t len = sizeof(sin);
213    int ret;
214
215    /* Use a sockaddr instead of sockaddr_in because we don't know whether
216     * their alignments are compatible. So, no cast. */
217    memset(&s, 0, sizeof(sin));
218    ret = getsockname(sock, &s, &len);
219    if (ret)
220        return 0; // TODO: error handling
221
222    memcpy(&sin, &s, sizeof(sin));
223    return sin.sin_addr.s_addr;
224}
225#endif /* HAVE_SYS_SOCKET_H */
Note: See TracBrowser for help on using the repository browser.