class Subnets::Net6
Public Class Methods
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
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.
@param [String] s @return {Net6} @raise {Subnets::ParseError}
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); }
@overload random(rand=Random.new, opts={})
@param rand [#rand] (optional) a random number generator @param opts [Hash] @option opts [Boolean] :zeros include a random string of zeros at a random position rather than simply randomizing the entire address
@return [Net6] a random Net6
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); }
@return [Subnets::Net6] the smallest subnet that includes all of the subnets in nets
@param nets [Array<Subnets::Net6>]
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); }
Public Instance Methods
@return [Boolean]
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; }
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.
@param [String, IP
, Net] v
VALUE method_net6_address(VALUE self) { net6_t *net; Data_Get_Struct(self, net6_t, net); return ip6_new(IP6, net->address); }
@return [Integer]
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; }
(see Subnets::IP6#hextets
)
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; }
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.
@param [String, IP
, Net] v
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; }
VALUE method_net6_mask(VALUE self) { net6_t *net; Data_Get_Struct(self, net6_t, net); return ip6_new(IP6, net->mask); }
(see Subnets::Net4#prefixlen
)
VALUE method_net6_prefixlen(VALUE self) { net6_t *net; Data_Get_Struct(self, net6_t, net); return INT2FIX(net->prefixlen); }
Return a String in CIDR notation.
@return [String]
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); }