class Subnets::Net4
Public Class Methods
VALUE method_net4_new(VALUE class, VALUE address, VALUE prefixlen) { net4_t net; net.address = RB_NUM2UINT(address); net.prefixlen = NUM2INT(prefixlen); if (!(net.prefixlen >= 0 && net.prefixlen <= 32)) { rb_raise(rb_eArgError, "prefixlen must be in range [0,32], was %d", net.prefixlen); } net.mask = mk_mask4(net.prefixlen); return net4_new(class, net); }
Parse s
as an IPv4 network in CIDR notation.
@param [String] s @return {Net4} @raise {Subnets::ParseError}
VALUE method_net4_parse(VALUE class, VALUE s) { const char *buf = StringValueCStr(s); net4_t net; if (!read_net4_strict(buf, &net)) { raise_parse_error("net4", buf); } return net4_new(class, net); }
@overload random(rng=Random.new)
@param rng [#rand] (optional) a random number generator
@return [Net4] a random Net4
address
VALUE method_net4_random(int argc, VALUE *argv, VALUE class) { net4_t net; VALUE rng, rand; rb_scan_args(argc, argv, "01", &rng); if (Qnil == rng) { rng = rb_funcall(rb_cRandom, rb_intern("new"), 0); } rand = rb_intern("rand"); net.address = FIX2INT(rb_funcall(rng, rand, 1, INT2FIX(0xffff+1))); net.address |= FIX2INT(rb_funcall(rng, rand, 1, INT2FIX(0xffff+1))) << 16; net.prefixlen = FIX2INT(rb_funcall(rng, rb_intern("rand"), 1, INT2FIX(32+1))); net.mask = mk_mask4(net.prefixlen); return net4_new(class, net); }
@return [Subnets::Net4] the smallest subnet that includes all of the subnets in nets
@param nets [Array<Subnets::Net4>]
VALUE method_net4_summarize(VALUE class, VALUE nets) { net4_t result; for (ssize_t i = 0; i < RARRAY_LEN(nets); i++) { const net4_t *net; VALUE rbnet = RARRAY_AREF(nets, i); assert_kind_of(rbnet, Net4); Data_Get_Struct(rbnet, net4_t, net); if (i == 0) { result.address = (net->address & net->mask); result.prefixlen = net->prefixlen; result.mask = net->mask; } else { while (result.prefixlen > net->prefixlen || result.address != (net->address & result.mask)) { result.prefixlen = MIN(result.prefixlen-1, net->prefixlen); result.mask = mk_mask4(result.prefixlen); result.address &= result.mask; } } } return net4_new(class, result); }
Public Instance Methods
@return [Boolean]
VALUE method_net4_eql_p(VALUE self, VALUE other) { net4_t *a, *b; if (CLASS_OF(other) != CLASS_OF(self)) { return Qfalse; } Data_Get_Struct(self, net4_t, a); Data_Get_Struct(other, net4_t, b); if (a->prefixlen != b->prefixlen) { return Qfalse; } if (a->address != b->address) { return Qfalse; } return Qtrue; }
Test if this network includes v
.
A String must parse as an IP4
or Net4
. An IP4
must be included within the range defined by this network. A Net4
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_net4_address(VALUE self) { net4_t *net; Data_Get_Struct(self, net4_t, net); return ip4_new(IP4, net->address); }
@return [Integer]
VALUE method_net4_hash(VALUE self) { net4_t *net; Data_Get_Struct(self, net4_t, net); return xor(hash(INT2FIX(net->prefixlen)), hash(UINT2NUM(net->address))); }
Test if this network includes v
.
A String must parse as an IP4
or Net4
. An IP4
must be included within the range defined by this network. A Net4
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_net4_include_p(VALUE self, VALUE v) { net4_t *net; Data_Get_Struct(self, net4_t, net); if (CLASS_OF(v) == IP4) { ip4_t *ip; Data_Get_Struct(v, ip4_t, ip); return net4_include_p(*net, *ip) ? Qtrue : Qfalse; } else if (CLASS_OF(v) == Net4) { net4_t *other; Data_Get_Struct(v, net4_t, other); return net4_include_net4_p(*net, *other) ? Qtrue : Qfalse; } else if (CLASS_OF(v) == IP6 || CLASS_OF(v) == Net6) { return Qfalse; } else { v = StringValue(v); { net4_t other; if (read_net4_strict(RSTRING_PTR(v), &other)) { return net4_include_net4_p(*net, other) ? Qtrue : Qfalse; } } { ip4_t ip; if (read_ip4_strict(RSTRING_PTR(v), &ip)) { return net4_include_p(*net, ip) ? Qtrue : Qfalse; } } return Qfalse; } }
VALUE method_net4_mask(VALUE self) { net4_t *net; Data_Get_Struct(self, net4_t, net); return ip4_new(IP4, net->mask); }
The prefix length of this network, or number of leading ones in the netmask.
@return [Fixnum]
VALUE method_net4_prefixlen(VALUE self) { net4_t *net; Data_Get_Struct(self, net4_t, net); return INT2FIX(net->prefixlen); }
Return a String in CIDR notation.
@return [String]
VALUE method_net4_to_s(VALUE self) { net4_t *net; char buf[32]; Data_Get_Struct(self, net4_t, net); net4_snprint(*net, buf, 32); return rb_str_new2(buf); }