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