ripcalc 0.3.0

ripcalc, format and lookup IP addresses
Documentation
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# ripcalc

Calculate or lookup network addresses.

# install

```
$ git clone 'https://gitlab.com/edneville/ripcalc.git'
$ cd ripcalc \
  && cargo build --release \
  && please install -m 0755 -s target/release/ripcalc /usr/local/bin
```

or

```
please snap install ripcalc
```

# usage

Ripcalc allows networks to be provided by argument

```
$ ripcalc 127.0.0.1/8
IP is: 127.0.0.1/8
Broadcast is: 127.255.255.255
Network is: 127.0.0.0
Subnet is: 255.0.0.0
Wildcard is: 0.255.255.255
Network size: 16777216
```

The same output is visible with stdin:

```
echo '127.0.0.1/8' | ripcalc
...
```

The output format can be customised:

```
$ ripcalc 2001:ba8:1f1:f1cb::4/64 --format "select * from IP6 where (ip >= %ln and ip <= %lb) and active = 1;\nupdate IP6 set active = 0 where (ip >= %ln and ip <= %lb) and active = 1;"
select * from IP6 where (ip >= 42540724579414763292693624807812497408 and ip <= 42540724579414763311140368881522049023) and active = 1;
update IP6 set active = 0 where (ip >= 42540724579414763292693624807812497408 and ip <= 42540724579414763311140368881522049023) and active = 1;
```

# pipes

Sometimes if you want to quickly see if an address is part of a group of networks you can set something like this in your `.bash_aliases`:

```
alias is_our_networks='ripcalc --inside 192.168.0.0/16 --format short'
```

With this alias it would then be possible to do something like this to quickly see if the domain uses your infrastructure:

```
dig +short domain.com | is_our_networks
```

# formatting

*%* denotes a format control character, followed by one of the following:

| placeholder | effect |
|-------------|--------|
| %a          | IP address string |
| %n          | Network address string |
| %s          | Subnet address string |
| %w          | Wildcard address string |
| %b          | Broadcast address string |

Additional characters prefixing the above placeholder can control the representation:

| placeholder | effect |
|-------------|--------|
| %B          | Binary address string |
| %S          | Split binary at network boundary string |
| %l          | Unsigned integer string |
| %L          | Signed integer string |
| %x          | Hex address string |

Other format characters:

| placeholder | effect |
|-------------|--------|
| %c          | CIDR mask |
| %C          | In encapsulated context, used address count |
| %t          | Network size |
| %r          | Network reservation information (if available) |
| %d          | Matching device interface by IP |
| %m          | Matching media link interface by network |
| %p          | PTR record |
| %k          | RBL/reverse DNS-style format |
| %D          | Network size (--networks) |
| %N          | Number of subnets (--networks) |
| %%          | % |
| \n          | Line break |
| \t          | Tab character |

For example:

```
$ ripcalc --format '%k.all.s5h.net\n' 192.168.1.2
2.1.168.192.all.s5h.net
```


With a csv it can find networks that an IP address is within, use `%{field}` to print matches:

```
$ cat nets.csv
network,range,owner
rfc1918,192.168.0.0/16,bob
rfc1918,172.16.0.0/12,cliff
rfc1918,10.0.0.0/8,mr nobody
$ ripcalc --csv nets.csv -i range --format '%{owner}\n' 192.168.0.0
bob
```

Addresses can be read via file or from stdin (-):

```
$ cat list
127.0.0.1/28
10.0.0.1/28
192.168.1.1/30
172.18.1.1/30
10.0.0.0/30
$ ripcalc --csv nets.csv -i range --format '%{range} %{owner}\n' -s list
10.0.0.0/8 mr nobody
192.168.0.0/16 bob
172.16.0.0/12 cliff
10.0.0.0/8 mr nobody
```

When `-a` is used, addresses read from `-s` will not be shown when listing `-l` a network, showing only available addresses.

When `-e` is used with `-s` the smallest encapsulating network will be returned.

Given a list of IP addresses, print only those that match the network. When `s` and `inside` are used, only addresses from `-s` are printed if they are that are inside of the IP source network on the command line. This can be inverted with `--outside:

```
$ echo -e '192.168.0.0\n192.167.255.255\n' | ripcalc -s - --inside 192.168.0.0/16 --format short
192.168.0.0
$ echo -e '192.168.0.0\n192.167.255.255\n' | ripcalc -s - --outside 192.168.0.0/16 --format short
192.167.255.255
```

IP addresses can be treated as reversed, if `/proc/net/route` holds addresses in reversed format, `--reverse inputs` and `--base 16` could be used together to convert to dotted-quad.

# integer inputs

To process addresses in signed integer form, use `--base -10` which will do the conversion.

To quickly format human-readable IP addresses to a database that stores addresses as integers, assuming addreses are in a table called IP4 and are signed integers:

```
printf '10.0.0.0/8\n192.168.0.0/16\n172.16.0.0/12\n127.0.0.0/8\n1.0.0.0/8\n' \
| ripcalc --format 'select ip from IP4 where active = 1 and (ip > %Ln and ip < %Lb);\n' \
| mysql -urip -pcalc ipdata \
| ripcalc -q --base 10 --format short
```

# within networks

Is a domain wihtin a list of subnets? For example, in this part of the globe cloudflare.com was being served from their published list of networks:

```
echo http://cloudflare.com | ripcalc --inside 173.245.48.0/20 103.21.244.0/22 \
    103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 \
    190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 \
    162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 \
    131.0.72.0/22 --format short
104.16.133.229
```

How many addresses is all that in total?

```
ripcalc 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 \
    141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 \
    197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 \
    104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 --format '%t\n' \
    | paste -sd+ \
    | bc -l
1524736
```

If you need to manage a lot of IP addresses this could be helpful to you.

# divide

Networks can be divided into subnets:

```
$ ripcalc 192.168.1.10/24 --divide 26 --format cidr
192.168.1.0/26
192.168.1.64/26
192.168.1.128/26
192.168.1.192/26
```

# quickly block the encapsulating network

Suppose a large flood of requests are from a network pattern, to preserve service you may want to block the whole network that encapsulates a list:

```
please ip route add blackhole `ripcalc -e 192.168.56.10 192.168.57.1 192.168.44.47`
```

Networks can be grouped, in a scenario where you have a list of unwanted traffic, you can turn this into a list of small networks to block, supposing you don't want to block anything that covers more than a /19:

```
cat bad_traffic | ripcalc --encapsulating --group 19 --format cidr
```

This might be of help to you, assuming you can select a chunk of bad traffic via a `grep`:

```
grep -h scams log/* | awk '{print $1}' | ripcalc --encapsulating --group 24 --format '%C %a/%c\n'
15 192.168.1.0/25
12 172.16.80.0/24
1 172.16.209.9/32
```

Grouping with a limit helps show spread, without expanding beyond sensible limits. Setting a very large `group` mask would of course return very large results, using a smaller `group` can limit this so the probability of including legitimate traffic is reduced dramatically.

IP address counts can be shown with `countseen` and `group`:

```
cat log | ripcalc --countseen --quiet --format '%C %a/%c\n'
```

# cdb

CDB databases are fast and if you have a large list of networks they offer a good way to lookup addresses without parsing CSV. CDB lookups can be performed using IP/cidr keys and the returned values should be stored as a NULL joined key=value string, e.g.:

```
192.168.1.0/24 name=lan\0owner=build\0service=web
```

The `--makethymecdb` argument will download ASN information from thyme.apnic.net and build that into a `cdb` file, or you can make your own. I find the data from thyme perfect for my needs, but this is the internet and geo-IP, please don't rely on geo-IP being accurate.

Obviously, if you have a fleet of computers using this data, it is best to download and build in one location then fan it out using `rsync` to your other computers to save resources and processing power.

Files can also be made using `--makecdb`, the stdin should be in the format of:

```
2600:3c0f:25::/48,ASNDESC=AKAMAI-LINODE-AP Akamai Connected Cloud,ASNCC=SG,ASN=2600:3c0f:25::/48,NET=63949
```

See cdb_maker.pl for a helper script which builds this. An example for making these can be seen in the Makefile in the ipdb target, it download ASN data and builds that using cdb_maker.pl, and this can be used like this:

```
ripcalc --cdb ipdb.cdb --format '%{ASNDESC} %{ASNCC} %a/%c\n' 1.1.1.1
CLOUDFLARENET US 1.1.1.1/24
```

# filter

Input can be filtered using `--filter` which can be helpful as an accompaniment for `grep`-like workflows.

```
cat /var/log/apache/access.log | ripcalc --filter 1.2.3.0/24
```

Or inverted with `--outside`.

```
cat /var/log/apache/access.log | ripcalc --filter 1.1.1.0/24 --outside
```

`--filter` will use the first word in the inputline and try to parse that for an IP address, if the IP address is not the first word in the input, then `--filternum` can be used to indicate which word number holds the IP.

If you'd like to see the country code that the requests in your log are from:

```
cat /var/log/apache/access.log | ripcalc --filter --outside --cdb ipdb.cdb --format '%{ASNCC} %{line}\n'
```

# abuseipdb

If `--abuseipdb [key]` is used then a successful lookup will populate `%{abuseipdb_var}` (where `var` is the lookup result data field) for use in a `--format` string.

Replace `[key]` with your abuseipdb API key.

If only the country code or ISP is needed, then using a locally generated `cdb` is more efficient, see the CDB section above as that can be much faster if you don't require an external abuse score.

# maxmind geolite

MaxMind's geolite database files can be read using `--mmasn`, `--mmcountry` and `--mmcity` options. The text language can be defined with `--mmlang`.

In normal context the following are returned:

mmcity: %{mmcity_city}, %{mmcity_continent}, %{mmcity_country}, %{mmcity_code}, %{mmcity_latitude}, %{mmcity_longitude}

mmcountry: %{mmcountry_continent}, %{mmcountry_country}, %{mmcountry_registered_country}

mmasn: %{mmasn_autonomous_system_number}, %{mmasn_autonomous_system_organization
}

Less information is returned in `--top` context:

```
ripcalc --top --allowemptyrow \
    --mmcity GeoLite2-City.mmdb \
    --mmcountry GeoLite2-Country.mmdb \
    --mmasn GeoLite2-ASN.mmdb 
```

Without needing to add a `--format` string, in `--top` context, this will display `%{mmcity_code}` and `%{mmcity_country}` for `--mmcity`, `%{mmasn_autonomous_system_organization}` for `--mmasn`, and `%{mmcountry_registered_country}` for `--mmcountry`.

# top

Basic report of IP frequency, as read from `stdin`. Can be used with `--group`, `--group[46]`, `--filter`, `--filterany`, `--filternum` or `--inside` to show which networks appear most frequently.

```
ripcalc --allowemptyrow --top --inside 10.0.0.0/8 --group 24 --delay 1

                                                   10.12.0.0/14 4800 ##
                                                   10.16.0.0/14 4075 ##
                                                    10.8.0.0/14 3740 #
                                                    10.4.0.0/14 3200 #
                                                    10.0.0.0/14 2400 #
                                                   10.20.0.0/14  800 

```

A cdb IP database can be used in conjunction, which defaults to `%{ASNCC} %{ASNDESC}`:

```
ripcalc --top --inside 10.0.0.0/8 --group 14 --delay 1 --allowemptyrow --cdb ipdb.cdb
XX PRIVATE                                          10.8.0.0/14 3200 ##
XX PRIVATE                                          10.4.0.0/14 3200 ##
XX PRIVATE                                         10.12.0.0/14 3200 ##
XX PRIVATE                                         10.16.0.0/14 3200 ##
XX PRIVATE                                          10.0.0.0/14 2400 #
XX PRIVATE                                         10.20.0.0/14  800 
```

If you want to show the abuse score from AbuseIPDB at the same time you can use a format string or allow the default to be used which shows the abuse score.

`--iterations [num]` can set the number of display iterations. If you wish to run a number of displays for an email report, use with `--noclear`:

```
( printf 'To: you\nFrom: me\nSubject: IP report\n\n';
tail -Fq /var/log/apache2/*log
| ripcalc --top --cdb ipdb.cdb --group4 24 --group6 64 --allowemptyrow --iterations 3 --noclear )
| /usr/sbin/sendmail -fme@example you@example
```

# help

```
ripcalc version 0.2.7

Options:
    -4, --ipv4          treat inputs as ipv4 address
    -6, --ipv6          treat inputs as ipv6 address
    -a, --available     display unused addresses
        --abuseipdb KEY abuseipdb API
        --allowemptyrow 
                        when no matching cdb/csv network, use empty fields
    -b, --base INTEGER  ipv4 base format, default to oct
        --cdb PATH      cdb reference file
        --countseen     count times an ip is seen
    -c, --csv PATH      csv reference file
    -d, --divide CIDR   divide network into chunks
        --noexpand      do not expand networks in list
    -e, --encapsulating 
                        display encapsulating network from arguments or lookup
                        list
    -f, --format STRING format output
                        'cidr' expands to %a/%c\n
                        'short' expands to %a\n
                        See manual for more options
        --filter        print STDIN line if field parses as an IP and matches,
                        defaults to 1, use filternum to adjust
        --filterany     print STDIN line if any IP on STDIN matches
        --filternum NUMBER
                        change position NUMBER for IP filter, enables --filter
        --group CIDR    maximum network group size for encapsulation
        --group4 CIDR   v4 specific group, overrides group in top mode
        --group6 CIDR   v6 specific group, overrides group in top mode
    -h, --help          display help
    -i, --field FIELD   csv/db/json field
    -l, --list          list all addresses in network
        --outside       display when extremities are outside network
        --inside        display when extremities are inside network
        --makecdb PATH  build a cdb file from STDIN
        --makethymecdb PATH
                        download and build a cdb file, defaults to
                        thyme.apnic.net data
        --data-raw-table URL or PATH
                        URL/path of raw data
        --ipv6-raw-table URL or PATH
                        URL/path of ipv6 data
        --data-used-autnums URL or PATH
                        URL/path of ASN data
        --top           show IP frequency like top
        --delay SECONDS top update delay in seconds
        --iterations NUMBER
                        top iterations
        --noclear       don't print clear screen codes
        --mmlang LANG   the lang to use in results, defaults to en
        --mmasn PATH    path to maxmind geoip asn file
        --mmcity PATH   path to maxmind geoip city file
        --mmcountry PATH
                        path to maxmind geoip country file
    -m, --mask CIDR     cidr mask
    -n, --networks CIDR instead of hosts, display number of subnets of this
                        size
        --json PATH     json prefix file
    -q, --quiet         don't report errors
    -r, --reverse       (none, inputs, sources or both) v4 octets, v6 hex
    -s, --file PATH     lookup addresses from, - for stdin
    -v, --version       print version
```