You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+154-5Lines changed: 154 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,6 +31,10 @@ Table of Contents
31
31
-[Get Tranco Ranking](#get-tranco-ranking)
32
32
-[IP Address Functions](#ip-address-functions)
33
33
-[IP Calculator](#ip-calculator)
34
+
-[Validate IP Address](#validate-ip-address)
35
+
-[Check Private IP](#check-private-ip)
36
+
-[IP Version](#ip-version)
37
+
-[IP to Integer / Integer to IP](#ip-to-integer--integer-to-ip)
34
38
-[Get Extension Version](#get-extension-version)
35
39
-[Build Requirements](#build-requirements)
36
40
-[Debugging](#debugging)
@@ -427,6 +431,155 @@ D SELECT i.IP,
427
431
└────────────────┴───────┘
428
432
```
429
433
434
+
#### Validate IP Address
435
+
436
+
The `is_valid_ip` function checks whether a string is a valid IPv4 or IPv6 address. Returns a `BOOLEAN`.
437
+
438
+
```sql
439
+
D SELECT is_valid_ip('192.168.1.1');
440
+
┌────────────────────────────┐
441
+
│ is_valid_ip('192.168.1.1') │
442
+
│ boolean │
443
+
├────────────────────────────┤
444
+
│ true │
445
+
└────────────────────────────┘
446
+
447
+
D SELECT is_valid_ip('2001:db8::1');
448
+
┌────────────────────────────┐
449
+
│ is_valid_ip('2001:db8::1') │
450
+
│ boolean │
451
+
├────────────────────────────┤
452
+
│ true │
453
+
└────────────────────────────┘
454
+
455
+
D SELECT is_valid_ip('not-an-ip');
456
+
┌──────────────────────────┐
457
+
│ is_valid_ip('not-an-ip') │
458
+
│ boolean │
459
+
├──────────────────────────┤
460
+
│ false │
461
+
└──────────────────────────┘
462
+
```
463
+
464
+
#### Check Private IP
465
+
466
+
The `is_private_ip` function checks whether an IP address belongs to a private or reserved range. Supports both IPv4 and IPv6. Returns `NULL` for invalid addresses.
467
+
468
+
IPv4 ranges covered:
469
+
470
+
- RFC 1918 (10/8, 172.16/12, 192.168/16)
471
+
- loopback (127/8)
472
+
- link-local (169.254/16)
473
+
- carrier-grade NAT (100.64/10)
474
+
- documentation (TEST-NET)
475
+
- benchmarking (198.18/15)
476
+
- multicast (224/4)
477
+
- reserved (240/4)
478
+
479
+
IPv6 ranges covered:
480
+
481
+
- loopback (::1)
482
+
- unspecified (::)
483
+
- link-local (fe80::/10)
484
+
- ULA (fc00::/7)
485
+
- multicast (ff00::/8)
486
+
- documentation (2001:db8::/32)
487
+
- discard (100::/64)
488
+
489
+
```sql
490
+
D SELECT is_private_ip('192.168.1.1');
491
+
┌──────────────────────────────┐
492
+
│ is_private_ip('192.168.1.1') │
493
+
│ boolean │
494
+
├──────────────────────────────┤
495
+
│ true │
496
+
└──────────────────────────────┘
497
+
498
+
D SELECT is_private_ip('8.8.8.8');
499
+
┌──────────────────────────┐
500
+
│ is_private_ip('8.8.8.8') │
501
+
│ boolean │
502
+
├──────────────────────────┤
503
+
│ false │
504
+
└──────────────────────────┘
505
+
506
+
D SELECT is_private_ip('fe80::c028:8eff:fe34:6e5f');
507
+
┌────────────────────────────────────────────┐
508
+
│ is_private_ip('fe80::c028:8eff:fe34:6e5f') │
509
+
│ boolean │
510
+
├────────────────────────────────────────────┤
511
+
│ true │
512
+
└────────────────────────────────────────────┘
513
+
```
514
+
515
+
#### IP Version
516
+
517
+
The `ip_version` function returns `4` for IPv4, `6` for IPv6, or `NULL` for invalid addresses.
518
+
519
+
```sql
520
+
D SELECT ip_version('192.168.1.1');
521
+
┌───────────────────────────┐
522
+
│ ip_version('192.168.1.1') │
523
+
│ int8 │
524
+
├───────────────────────────┤
525
+
│ 4 │
526
+
└───────────────────────────┘
527
+
528
+
D SELECT ip_version('::1');
529
+
┌───────────────────┐
530
+
│ ip_version('::1') │
531
+
│ int8 │
532
+
├───────────────────┤
533
+
│ 6 │
534
+
└───────────────────┘
535
+
```
536
+
537
+
#### IP to Integer / Integer to IP
538
+
539
+
The `ip_to_int` function converts an IPv4 address to its 32-bit unsigned integer representation. The `int_to_ip` function converts back. Returns `NULL` for invalid or IPv6 input (IPv6 requires 128-bit support).
540
+
541
+
```sql
542
+
D SELECT ip_to_int('192.168.1.1');
543
+
┌──────────────────────────┐
544
+
│ ip_to_int('192.168.1.1') │
545
+
│ uint64 │
546
+
├──────────────────────────┤
547
+
│ 3232235777 │
548
+
│ (3.23 billion) │
549
+
└──────────────────────────┘
550
+
551
+
D SELECT int_to_ip(3232235777::UBIGINT);
552
+
┌────────────────────────────────────────┐
553
+
│ int_to_ip(CAST(3232235777AS UBIGINT)) │
554
+
│ varchar │
555
+
├────────────────────────────────────────┤
556
+
│ 192.168.1.1 │
557
+
└────────────────────────────────────────┘
558
+
559
+
D SELECT int_to_ip('3232235777');
560
+
┌─────────────────────────┐
561
+
│ int_to_ip('3232235777') │
562
+
│ varchar │
563
+
├─────────────────────────┤
564
+
│ 192.168.1.1 │
565
+
└─────────────────────────┘
566
+
```
567
+
568
+
These functions are useful for sorting IPs numerically or performing range comparisons:
569
+
570
+
```sql
571
+
D SELECT ip, ip_to_int(ip) FROM ipv4_ips ORDER BY ip_to_int(ip);
572
+
┌─────────────┬───────────────┐
573
+
│ ip │ ip_to_int(ip) │
574
+
│ varchar │ uint64 │
575
+
├─────────────┼───────────────┤
576
+
│ 8.8.8.8 │ 134744072 │
577
+
│ 10.0.0.1 │ 167772161 │
578
+
│ 172.16.0.1 │ 2886729729 │
579
+
│ 192.168.1.1 │ 3232235777 │
580
+
└─────────────┴───────────────┘
581
+
```
582
+
430
583
### Get Extension Version
431
584
432
585
You can use the `netquack_version` function to get the extension version.
@@ -437,7 +590,7 @@ D SELECT * FROM netquack_version();
437
590
│ version │
438
591
│ varchar │
439
592
├─────────┤
440
-
│ v1.8.1 │
593
+
│ v1.9.0 │
441
594
└─────────┘
442
595
```
443
596
@@ -473,11 +626,7 @@ Also, there will be stdout errors for background tasks like CURL.
Two functions for converting between IPv4 addresses and their 32-bit unsigned integer representation.
18
+
19
+
## ip\_to\_int
20
+
21
+
Converts an IPv4 address string to a `UBIGINT` (unsigned 64-bit integer, but the value will always fit in 32 bits). Returns `NULL` for invalid or IPv6 input.
22
+
23
+
```sql
24
+
D SELECT ip_to_int('192.168.1.1');
25
+
┌───────────────────────────┐
26
+
│ ip_to_int('192.168.1.1') │
27
+
│ uint64 │
28
+
├───────────────────────────┤
29
+
│ 3232235777 │
30
+
└───────────────────────────┘
31
+
32
+
D SELECT ip_to_int('10.0.0.1');
33
+
┌───────────────────────┐
34
+
│ ip_to_int('10.0.0.1') │
35
+
│ uint64 │
36
+
├───────────────────────┤
37
+
│ 167772161 │
38
+
└───────────────────────┘
39
+
40
+
D SELECT ip_to_int('255.255.255.255');
41
+
┌───────────────────────────────────┐
42
+
│ ip_to_int('255.255.255.255') │
43
+
│ uint64 │
44
+
├───────────────────────────────────┤
45
+
│ 4294967295 │
46
+
└───────────────────────────────────┘
47
+
```
48
+
49
+
## int\_to\_ip
50
+
51
+
Converts a `UBIGINT` integer back to an IPv4 dotted-quad string. Returns `NULL` if the value exceeds the IPv4 range (`> 4294967295`).
52
+
53
+
```sql
54
+
D SELECT int_to_ip(3232235777::UBIGINT);
55
+
┌──────────────────────────────────┐
56
+
│ int_to_ip(3232235777::UBIGINT) │
57
+
│ varchar │
58
+
├──────────────────────────────────┤
59
+
│ 192.168.1.1 │
60
+
└──────────────────────────────────┘
61
+
62
+
D SELECT int_to_ip(0::UBIGINT);
63
+
┌──────────────────────┐
64
+
│ int_to_ip(0::UBIGINT)│
65
+
│ varchar │
66
+
├──────────────────────┤
67
+
│ 0.0.0.0 │
68
+
└──────────────────────┘
69
+
```
70
+
71
+
## Roundtrip
72
+
73
+
The two functions are inverses of each other:
74
+
75
+
```sql
76
+
D SELECT int_to_ip(ip_to_int('192.168.1.1'));
77
+
┌─────────────┐
78
+
│ result │
79
+
│ varchar │
80
+
├─────────────┤
81
+
│ 192.168.1.1 │
82
+
└─────────────┘
83
+
```
84
+
85
+
## Use Cases
86
+
87
+
**Sort IPs numerically** instead of lexicographically:
88
+
89
+
```sql
90
+
D SELECT ip FROM ips ORDER BY ip_to_int(ip);
91
+
┌─────────────┐
92
+
│ ip │
93
+
│ varchar │
94
+
├─────────────┤
95
+
│ 8.8.8.8 │
96
+
│ 10.0.0.1 │
97
+
│ 172.16.0.1 │
98
+
│ 192.168.1.1 │
99
+
└─────────────┘
100
+
```
101
+
102
+
**Range queries** using integer comparison:
103
+
104
+
```sql
105
+
D SELECT ip FROM ips
106
+
WHERE ip_to_int(ip) BETWEEN ip_to_int('10.0.0.0') AND ip_to_int('10.255.255.255');
0 commit comments