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
|