CIDR from ip range

2,409 views
Skip to first unread message

Victor

unread,
Mar 15, 2015, 10:01:43 PM3/15/15
to golan...@googlegroups.com
I'm looking for a Go lib, code snippet or an advice on "calculating" one or more CIDR from two ip addresses.
Something that would work similar to the service provided here:
Thanks a lot in advance :-)
v

Sven Engelhardt

unread,
Mar 16, 2015, 9:23:38 AM3/16/15
to Victor, golang-nuts
This will work for v4 only.


-Sven

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Victor

unread,
Mar 16, 2015, 11:38:04 AM3/16/15
to golan...@googlegroups.com, dsgnv...@gmail.com
Thank you very much, v4 only is just fine.
I would like to use it with data from whois.
Your code works in most cases, but the online CIDR utility gives me different results for some ip ranges:

https://play.golang.org/p/YlJsUCMm1w   61.32.0.0 -  61.43.255.255

http://www.ipaddressguide.com/cidr#range  61.32.0.0 -  61.43.255.255

v

Jakob Borg

unread,
Mar 16, 2015, 5:46:57 PM3/16/15
to Victor, golan...@googlegroups.com
Both are correct, answering different questions. 61.32.0.0/12 is the smallest *single* network to contain your two endpoints. The /13 and /14 combination is more specific.

Btw the code posted should work equally well for IPv6, with the loop starting at 64 (or 128, if you accept the existence of networks smaller than /64).

//jb

Bakul Shah

unread,
Mar 16, 2015, 9:21:31 PM3/16/15
to Victor, golan...@googlegroups.com
On Sun, 15 Mar 2015 19:01:43 PDT Victor <dsgnv...@gmail.com> wrote:
>
> I'm looking for a Go lib, code snippet or an advice on "calculating" one or
> more CIDR from two ip addresses.

Here's some old C code that may help. Can't be bothered to
reimplement in Go but the key idea is to use a progressively
shorter mask, as long as the masked range starts with a1 and
doesn't go past a2. Print this range & set a1 to an address
just past the range. Repeat until a2 is covered.

#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int c, char** v) {
char* addr1 = c > 1? v[1] : "0.0.0.1";
char* addr2 = c > 2? v[2] : "255.255.255.254";
in_addr_t a1 = ntohl(inet_addr(addr1));
in_addr_t a2 = ntohl(inet_addr(addr2));

while (a2 >= a1) {
struct in_addr a;
in_addr_t m = ~0;
int l = 32;
while (m > 0) {
in_addr_t m1 = m << 1;
if ((a1&m1) != a1 || (a1|~m1) > a2)
break;
m = m1;
l--;
}
a.s_addr = htonl(a1);
printf("%s/%d\n", inet_ntoa(a), l);
a1 |= ~m;
if (a1 + 1 < a1)
break;
a1 += 1;
}
return 0;
}

Victor

unread,
Mar 16, 2015, 10:20:13 PM3/16/15
to golan...@googlegroups.com, dsgnv...@gmail.com
Works great! Thank you so much.
I won't be reimplementing in Go, just not yet :-)
But will try to "embed" with cgo - seems easier to me for now :-)
Thanks again,
w

Konstantin Khomoutov

unread,
Mar 17, 2015, 8:10:04 AM3/17/15
to Victor, golan...@googlegroups.com
On Mon, 16 Mar 2015 19:20:13 -0700 (PDT)
Victor <dsgnv...@gmail.com> wrote:

> Works great! Thank you so much.
> I won't be reimplementing in Go, just not yet :-)
> But will try to "embed" with cgo - seems easier to me for now :-)

Bring libc in just to not rewrite 20 lines of simple code?
Larry Wall touted laziness as one of the programmer's virtues but I'm
not sure he meant this level of it ;-)

Victor

unread,
Mar 17, 2015, 11:00:14 AM3/17/15
to golan...@googlegroups.com, dsgnv...@gmail.com
Hi Konstantin,
I'm not that lazy :-) Just not familiar with Go network packages yet. Started learning the lang a few days ago, already got a running web socket  and needed badly that "to-CIDR" thing.
Thank you all for the help.
Victor




Bakul Shah

unread,
Mar 18, 2015, 2:33:54 AM3/18/15
to Konstantin Khomoutov, Victor, golan...@googlegroups.com
On Tue, 17 Mar 2015 15:09:47 +0300 Konstantin Khomoutov <flat...@users.sourceforge.net> wrote:
> On Mon, 16 Mar 2015 19:20:13 -0700 (PDT)
> Victor <dsgnv...@gmail.com> wrote:
>
> > Works great! Thank you so much.
> > I won't be reimplementing in Go, just not yet :-)
> > But will try to "embed" with cgo - seems easier to me for now :-)
>
> Bring libc in just to not rewrite 20 lines of simple code?

Rewriting this in Go is not difficult but you have to add some
support functions so it's more like 80 lines! See

http://play.golang.org/p/nJE2EPx88-

Due to some simplifying assumptions the above is not
bulletproof but should serve Victor's needs.

Victor

unread,
Mar 22, 2015, 12:48:25 AM3/22/15
to golan...@googlegroups.com, flat...@users.sourceforge.net, dsgnv...@gmail.com
On Wednesday, March 18, 2015 at 7:33:54 AM UTC+1, Bakul Shah wrote:
Rewriting this in Go is not difficult but you have to add some
support functions so it's more like 80 lines!  See

http://play.golang.org/p/nJE2EPx88- 

Just to say thank you! I'm a designer mainly so if you will need a "80-1000 lines" logo or something contact me and I will try to help :-)
best,
Victor

bar jan (janbar)

unread,
Nov 8, 2022, 10:47:13 PM11/8/22
to golang-nuts

I used the new feature netip of Go1.18 to write code that applies both ipv4 and ipv6

https://go.dev/play/p/Ynx1liLAGs2
Reply all
Reply to author
Forward
0 new messages