Class: Subnets::Net4

Inherits:
Net
  • Object
show all
Defined in:
ext/subnets/ext.c

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Net

#inspect

Class Method Details

.new(address, prefixlen) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
# File 'ext/subnets/ext.c', line 101

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) ⇒ Net4

Parse s as an IPv4 network in CIDR notation.

Parameters:

  • s (String)

Returns:

Raises:



142
143
144
145
146
147
148
149
150
151
# File 'ext/subnets/ext.c', line 142

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);
}

.random(rng = Random.new) ⇒ Net4

Returns a random Net4 address.

Parameters:

  • rng (#rand) (defaults to: Random.new)

    (optional) a random number generator

Returns:

  • (Net4)

    a random Net4 address



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'ext/subnets/ext.c', line 209

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);
}

.summarize(nets) ⇒ Subnets::Net4

the subnets in nets

Parameters:

Returns:



830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
# File 'ext/subnets/ext.c', line 830

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);
}

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Returns:

  • (Boolean)


639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
# File 'ext/subnets/ext.c', line 639

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;
}

#addressObject



762
763
764
765
766
767
# File 'ext/subnets/ext.c', line 762

VALUE
method_net4_address(VALUE self) {
  net4_t *net;
  Data_Get_Struct(self, net4_t, net);
  return ip4_new(IP4, net->address);
}

#hashInteger

Returns:

  • (Integer)


713
714
715
716
717
718
# File 'ext/subnets/ext.c', line 713

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)));
}

#include?(v) ⇒ Boolean Also known as: ===

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.

Parameters:

Returns:

  • (Boolean)


443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
# File 'ext/subnets/ext.c', line 443

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;
  }
}

#maskObject



776
777
778
779
780
781
# File 'ext/subnets/ext.c', line 776

VALUE
method_net4_mask(VALUE self) {
  net4_t *net;
  Data_Get_Struct(self, net4_t, net);
  return ip4_new(IP4, net->mask);
}

#prefixlenFixnum

The prefix length of this network, or number of leading ones in the netmask.

Returns:

  • (Fixnum)


416
417
418
419
420
421
# File 'ext/subnets/ext.c', line 416

VALUE
method_net4_prefixlen(VALUE self) {
  net4_t *net;
  Data_Get_Struct(self, net4_t, net);
  return INT2FIX(net->prefixlen);
}

#to_sString

Return a String in CIDR notation.

Returns:

  • (String)


559
560
561
562
563
564
565
566
567
# File 'ext/subnets/ext.c', line 559

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);
}