forked from firehol/iprange
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiprange.h
184 lines (148 loc) · 5.36 KB
/
iprange.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#ifndef IPRANGE_IPRANGE_H
#define IPRANGE_IPRANGE_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined(HAVE_INTTYPES_H)
#include <inttypes.h>
#elif defined(HAVE_STDINT_H)
#include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>
extern int cidr_use_network;
extern int default_prefix;
extern char *PROG;
extern int debug;
/*---------------------------------------------------------------------*/
/* network address type: one field for the net address, one for prefix */
/*---------------------------------------------------------------------*/
typedef struct network_addr {
in_addr_t addr;
in_addr_t broadcast;
} network_addr_t;
/*------------------------------------------------------------------*/
/* Set a bit to a given value (0 or 1); MSB is bit 1, LSB is bit 32 */
/*------------------------------------------------------------------*/
static inline in_addr_t set_bit(in_addr_t addr, int bitno, int val) {
if (val)
return (addr | (1 << (32 - bitno)));
else
return (addr & ~(1 << (32 - bitno)));
} /* set_bit() */
/*--------------------------------------*/
/* Compute netmask address given prefix */
/*--------------------------------------*/
static inline in_addr_t netmask(int prefix) {
if (prefix == 0)
return (~((in_addr_t) - 1));
else
return (in_addr_t)(~((1 << (32 - prefix)) - 1));
} /* netmask() */
/*----------------------------------------------------*/
/* Compute broadcast address given address and prefix */
/*----------------------------------------------------*/
static inline in_addr_t broadcast(in_addr_t addr, int prefix) {
return (addr | ~netmask(prefix));
} /* broadcast() */
/*--------------------------------------------------*/
/* Compute network address given address and prefix */
/*--------------------------------------------------*/
static inline in_addr_t network(in_addr_t addr, int prefix) {
return (addr & netmask(prefix));
} /* network() */
/*-----------------------------------------------------------*/
/* Convert an A.B.C.D address into a 32-bit host-order value */
/*-----------------------------------------------------------*/
static inline in_addr_t a_to_hl(char *ipstr, int *err) {
struct in_addr in;
if (unlikely(!inet_aton(ipstr, &in))) {
fprintf(stderr, "%s: Invalid address %s.\n", PROG, ipstr);
in.s_addr = 0;
if(err) (*err)++;
return (ntohl(in.s_addr));
}
return (ntohl(in.s_addr));
} /* a_to_hl() */
/*-----------------------------------------------------------------*/
/* convert a network address char string into a host-order network */
/* address and an integer prefix value */
/*-----------------------------------------------------------------*/
static inline network_addr_t str2netaddr(char *ipstr, int *err) {
int prefix = default_prefix;
char *prefixstr;
network_addr_t netaddr;
if ((prefixstr = strchr(ipstr, '/'))) {
*prefixstr = '\0';
prefixstr++;
errno = 0;
prefix = atoi(prefixstr);
if (unlikely(errno || (*prefixstr == '\0') || (prefix < 0) || (prefix > 32))) {
/* try the netmask format */
in_addr_t mask = ~a_to_hl(prefixstr, err);
/*fprintf(stderr, "mask is %u (0x%08x)\n", mask, mask);*/
prefix = 32;
while((likely(mask & 0x00000001))) {
mask >>= 1;
prefix--;
}
if(unlikely(mask)) {
if(err) (*err)++;
fprintf(stderr, "%s: Invalid netmask %s\n", PROG, prefixstr);
netaddr.addr = 0;
netaddr.broadcast = 0;
return (netaddr);
}
}
}
if(likely(cidr_use_network))
netaddr.addr = network(a_to_hl(ipstr, err), prefix);
else
netaddr.addr = a_to_hl(ipstr, err);
netaddr.broadcast = broadcast(netaddr.addr, prefix);
return (netaddr);
}
// ----------------------------------------------------------------------------
// Print out a 32-bit address in A.B.C.D/M format
//
// very fast implementation of IP address printing
// this is 30% faster than the system default (inet_ntoa() based)
// http://stackoverflow.com/questions/1680365/integer-to-ip-address-c
static inline char *ip2str_r(char *buf, in_addr_t IP) {
int i, k;
for(i = 0, k = 0; i < 4; i++) {
char c0 = (char)(((((IP & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8))) / 100) + 0x30);
if(c0 != '0') *(buf + k++) = c0;
char c1 = (char)((((((IP & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8))) % 100) / 10) + 0x30);
if(!(c1 == '0' && c0 == '0')) *(buf + k++) = c1;
*(buf + k) = (char)((((((IP & (0xff << ((3 - i) * 8)))) >> ((3 - i) * 8))) % 10) + 0x30);
k++;
if(i < 3) *(buf + k++) = '.';
}
*(buf + k) = 0;
return buf;
}
#define IP2STR_MAX_LEN 20
#include "ipset.h"
#include "ipset_binary.h"
#include "ipset_combine.h"
#include "ipset_common.h"
#include "ipset_copy.h"
#include "ipset_diff.h"
#include "ipset_exclude.h"
#include "ipset_load.h"
#include "ipset_merge.h"
#include "ipset_optimize.h"
#include "ipset_print.h"
#include "ipset_reduce.h"
#endif //IPRANGE_IPRANGE_H