1 /*
2 * Copyright (c) 2008-2020, OARC, Inc.
3 * Copyright (c) 2007-2008, Internet Systems Consortium, Inc.
4 * Copyright (c) 2003-2007, The Measurement Factory, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. Neither the name of the copyright holder nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #include "config.h"
38
39 #include "ip_direction_index.h"
40 #include "xmalloc.h"
41 #include "inX_addr.h"
42 #include "syslog_debug.h"
43
44 #include <stdlib.h>
45 #include <string.h>
46
47 #define LARGEST 2
48
49 struct _foo {
50 inX_addr addr;
51 inX_addr mask;
52 struct _foo* next;
53 };
54
55 static struct _foo* local_addrs = NULL;
56
57 #ifndef DROP_RECV_RESPONSE
58 static
59 #endif
60 int
ip_is_local(const inX_addr * a)61 ip_is_local(const inX_addr* a)
62 {
63 struct _foo* t;
64 for (t = local_addrs; t; t = t->next) {
65 inX_addr m = inXaddr_mask(a, &(t->mask));
66 if (!inXaddr_cmp(&(t->addr), &m)) {
67 return 1;
68 }
69 }
70 return 0;
71 }
72
ip_direction_indexer(const dns_message * m)73 int ip_direction_indexer(const dns_message* m)
74 {
75 const transport_message* tm = m->tm;
76 if (ip_is_local(&tm->src_ip_addr))
77 return 0;
78 if (ip_is_local(&tm->dst_ip_addr))
79 return 1;
80 return LARGEST;
81 }
82
ip_local_address(const char * presentation,const char * mask)83 int ip_local_address(const char* presentation, const char* mask)
84 {
85 struct _foo* n = xcalloc(1, sizeof(*n));
86 if (NULL == n)
87 return 0;
88 if (inXaddr_pton(presentation, &n->addr) != 1) {
89 dfprintf(0, "yucky IP address %s", presentation);
90 xfree(n);
91 return 0;
92 }
93 memset(&(n->mask), 255, sizeof(n->mask));
94 if (mask) {
95 if (!strchr(mask, '.') && !strchr(mask, ':')) {
96 in_addr_t bit_mask = -1;
97 int bits = atoi(mask);
98
99 if (strchr(presentation, ':')) {
100 if (bits < 0 || bits > 128) {
101 dfprintf(0, "yucky IP mask bits %s", mask);
102 xfree(n);
103 return 0;
104 }
105
106 if (bits > 96) {
107 bit_mask <<= 128 - bits;
108 n->mask._.in4.s_addr = htonl(bit_mask);
109 } else {
110 n->mask._.in4.s_addr = 0;
111 if (bits > 64) {
112 bit_mask <<= 96 - bits;
113 n->mask._.pad2.s_addr = htonl(bit_mask);
114 } else {
115 n->mask._.pad2.s_addr = 0;
116 if (bits > 32) {
117 bit_mask <<= 64 - bits;
118 n->mask._.pad1.s_addr = htonl(bit_mask);
119 } else {
120 n->mask._.pad1.s_addr = 0;
121 if (bits) {
122 bit_mask <<= 32 - bits;
123 n->mask._.pad0.s_addr = htonl(bit_mask);
124 } else {
125 n->mask._.pad0.s_addr = 0;
126 }
127 }
128 }
129 }
130 } else {
131 if (bits < 0 || bits > 32) {
132 dfprintf(0, "yucky IP mask bits %s", mask);
133 xfree(n);
134 return 0;
135 }
136
137 if (bits) {
138 bit_mask <<= 32 - bits;
139 n->mask._.in4.s_addr = htonl(bit_mask);
140 } else {
141 n->mask._.in4.s_addr = 0;
142 }
143 }
144 } else if (inXaddr_pton(mask, &n->mask) != 1) {
145 dfprintf(0, "yucky IP mask %s", mask);
146 xfree(n);
147 return 0;
148 }
149 }
150 n->next = local_addrs;
151 local_addrs = n;
152 return 1;
153 }
154
ip_direction_iterator(const char ** label)155 int ip_direction_iterator(const char** label)
156 {
157 static int next_iter = 0;
158 if (NULL == label) {
159 next_iter = 0;
160 return LARGEST + 1;
161 }
162 if (0 == next_iter)
163 *label = "sent";
164 else if (1 == next_iter)
165 *label = "recv";
166 else if (LARGEST == next_iter)
167 *label = "else";
168 else
169 return -1;
170 return next_iter++;
171 }
172