Class: Subnets::Net6
Class Method Summary collapse
- .new(hextets, prefixlen) ⇒ Object
-
.parse(s) ⇒ Net6
Parse
sas an IPv6 network in CIDR notation. -
.random(rand = Random.new, opts = {}) ⇒ Net6
A random Net6.
-
.summarize(nets) ⇒ Subnets::Net6
the subnets in
nets.
Instance Method Summary collapse
- #==(other) ⇒ Boolean (also: #eql?)
- #address ⇒ Object
- #hash ⇒ Integer
-
#hextets ⇒ Array<Fixnum>
16-bit hextets, most significant first.
-
#include?(v) ⇒ Boolean
(also: #===)
Test if this network includes
v. - #mask ⇒ Object
-
#prefixlen ⇒ Fixnum
The prefix length of this network, or number of leading ones in the netmask.
-
#to_s ⇒ String
Return a String in CIDR notation.
Methods inherited from Net
Class Method Details
.new(hextets, prefixlen) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'ext/subnets/ext.c', line 113
VALUE
method_net6_new(VALUE class, VALUE hextets, VALUE prefixlen) {
net6_t net;
if (RARRAY_LEN(hextets) != 8) {
rb_raise(rb_eArgError, "hextets must be size=8, was %ld", RARRAY_LEN(hextets));
}
for (ssize_t i = 0; i < RARRAY_LEN(hextets); i++) {
net.address.x[i] = NUM2INT(RARRAY_AREF(hextets, i)) & 0xffff;
}
net.prefixlen = NUM2INT(prefixlen);
if (!(net.prefixlen >= 0 && net.prefixlen <= 128)) {
rb_raise(rb_eArgError, "prefixlen must be in range [0,128], was %d", net.prefixlen);
}
net.mask = mk_mask6(net.prefixlen);
return net6_new(class, net);
}
|
.parse(s) ⇒ Net6
Parse s as an IPv6 network in CIDR notation. Handles the following formats:
-
x:x:x:x:x:x:x:x consisting of eight hexadecimal numbers of one to four digits (16 bits) separated by colons
-
x:x:x::x:x:x as above, but a single double-colon replaces two or more repeated zeros
-
x:x:x:x:x:x:d.d.d.d consisting of a colon-separated hexadecimal portion as above defining up to six hextets, followed by dot-separated decimal numbers 0-255 in typical IPv4 format.
171 172 173 174 175 176 177 178 179 180 |
# File 'ext/subnets/ext.c', line 171
VALUE
method_net6_parse(VALUE class, VALUE s) {
const char *buf = StringValueCStr(s);
net6_t net;
if (!read_net6_strict(buf, &net)) {
raise_parse_error("net6", buf);
}
return net6_new(class, net);
}
|
.random(rand = Random.new, opts = {}) ⇒ Net6
Returns a random Net6.
283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'ext/subnets/ext.c', line 283
VALUE
method_net6_random(int argc, VALUE *argv, VALUE class) {
net6_t net;
VALUE rng;
VALUE opts;
rb_scan_args(argc, argv, "01:", &rng, &opts);
ip6_fill_random(&net.address, rng, opts);
net.prefixlen = FIX2INT(rb_funcall(rng, rb_intern("rand"), 1, INT2FIX(128+1)));
net.mask = mk_mask6(net.prefixlen);
return net6_new(class, net);
}
|
.summarize(nets) ⇒ Subnets::Net6
the subnets in nets
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 |
# File 'ext/subnets/ext.c', line 865
VALUE
method_net6_summarize(VALUE class, VALUE nets) {
net6_t result;
for (ssize_t i = 0; i < RARRAY_LEN(nets); i++) {
net6_t *net;
VALUE rbnet = RARRAY_AREF(nets, i);
assert_kind_of(rbnet, Net6);
Data_Get_Struct(rbnet, net6_t, net);
if (i == 0) {
result.address = ip6_band(net->address, net->mask);
result.prefixlen = net->prefixlen;
result.mask = net->mask;
} else {
while(result.prefixlen > net->prefixlen ||
!ip6_eql_p(result.address, ip6_band(net->address, result.mask))) {
result.prefixlen = MIN(result.prefixlen-1, net->prefixlen);
result.mask = mk_mask6(result.prefixlen);
result.address = ip6_band(result.address, result.mask);
}
}
}
return net6_new(class, result);
}
|
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
# File 'ext/subnets/ext.c', line 679
VALUE
method_net6_eql_p(VALUE self, VALUE other) {
net6_t *a, *b;
if (CLASS_OF(other) != CLASS_OF(self)) {
return Qfalse;
}
Data_Get_Struct(self, net6_t, a);
Data_Get_Struct(other, net6_t, b);
if (a->prefixlen != b->prefixlen) {
return Qfalse;
}
for (int i=0; i<8; i++) {
if (a->address.x[i] != b->address.x[i]) return Qfalse;
}
return Qtrue;
}
|
#address ⇒ Object
769 770 771 772 773 774 |
# File 'ext/subnets/ext.c', line 769
VALUE
method_net6_address(VALUE self) {
net6_t *net;
Data_Get_Struct(self, net6_t, net);
return ip6_new(IP6, net->address);
}
|
#hash ⇒ Integer
740 741 742 743 744 745 746 747 748 749 750 751 752 |
# File 'ext/subnets/ext.c', line 740
VALUE
method_net6_hash(VALUE self) {
net6_t *net;
VALUE ret;
Data_Get_Struct(self, net6_t, net);
ret = hash(INT2FIX(net->prefixlen));
for (int i=0; i<8; i++) {
ret = xor(ret, hash(INT2FIX(net->address.x[i])));
}
return ret;
}
|
#hextets ⇒ Array<Fixnum>
Returns 16-bit hextets, most significant first.
810 811 812 813 814 815 816 817 818 819 820 821 822 |
# File 'ext/subnets/ext.c', line 810
VALUE
method_net6_hextets(VALUE self) {
net6_t *net;
VALUE hextets;
Data_Get_Struct(self, net6_t, net);
hextets = rb_ary_new();
for (int i=0; i<8; i++) {
rb_ary_push(hextets, INT2FIX(net->address.x[i]));
}
return hextets;
}
|
#include?(v) ⇒ Boolean Also known as: ===
Test if this network includes v.
A String must parse as an IP6 or Net6. An IP6 must be included within the range defined by this network. A Net6 must both have a prefixlen greater than or equal to that of this network, and have an address included within the range defined by this network.
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
# File 'ext/subnets/ext.c', line 488
VALUE
method_net6_include_p(VALUE self, VALUE v) {
net6_t *net;
Data_Get_Struct(self, net6_t, net);
if (CLASS_OF(v) == IP6) {
ip6_t *ip;
Data_Get_Struct(v, ip6_t, ip);
return net6_include_p(*net, *ip) ? Qtrue : Qfalse;
} else if (CLASS_OF(v) == Net6) {
net6_t *other;
Data_Get_Struct(v, net6_t, other);
return net6_include_net6_p(*net, *other) ? Qtrue : Qfalse;
} else if (CLASS_OF(v) == IP4 || CLASS_OF(v) == Net4) {
return Qfalse;
} else if (rb_obj_is_kind_of(v, rb_cString)) {
const char *buf = StringValueCStr(v);
{
net6_t other;
if (read_net6_strict(buf, &other)) {
return net6_include_net6_p(*net, other) ? Qtrue : Qfalse;
}
}
{
ip6_t ip;
if (read_ip6_strict(buf, &ip)) {
return net6_include_p(*net, ip) ? Qtrue : Qfalse;
}
}
}
return Qfalse;
}
|
#mask ⇒ Object
783 784 785 786 787 788 |
# File 'ext/subnets/ext.c', line 783
VALUE
method_net6_mask(VALUE self) {
net6_t *net;
Data_Get_Struct(self, net6_t, net);
return ip6_new(IP6, net->mask);
}
|
#prefixlen ⇒ Fixnum
The prefix length of this network, or number of leading ones in the netmask.
426 427 428 429 430 431 |
# File 'ext/subnets/ext.c', line 426
VALUE
method_net6_prefixlen(VALUE self) {
net6_t *net;
Data_Get_Struct(self, net6_t, net);
return INT2FIX(net->prefixlen);
}
|
#to_s ⇒ String
Return a String in CIDR notation.
574 575 576 577 578 579 580 581 582 |
# File 'ext/subnets/ext.c', line 574 VALUE method_net6_to_s(VALUE self) { net6_t *net; char buf[64]; Data_Get_Struct(self, net6_t, net); net6_snprint(*net, buf, 64); return rb_str_new2(buf); } |