(args []super.Value)
| 14 | } |
| 15 | |
| 16 | func (n *NetworkOf) Call(args []super.Value) super.Value { |
| 17 | ipVal := args[0].Under() |
| 18 | if ipVal.Type().ID() != super.IDIP { |
| 19 | return n.sctx.WrapError("network_of: not an IP", ipVal) |
| 20 | } |
| 21 | ip := super.DecodeIP(ipVal.Bytes()) |
| 22 | var bits int |
| 23 | if len(args) == 1 { |
| 24 | switch { |
| 25 | case !ip.Is4(): |
| 26 | return n.sctx.WrapError("network_of: not an IPv4 address", ipVal) |
| 27 | case ip.As4()[0] < 0x80: |
| 28 | bits = 8 |
| 29 | case ip.As4()[0] < 0xc0: |
| 30 | bits = 16 |
| 31 | default: |
| 32 | bits = 24 |
| 33 | } |
| 34 | } else { |
| 35 | // two args |
| 36 | maskVal := args[1].Under() |
| 37 | switch id := maskVal.Type().ID(); { |
| 38 | case id == super.IDIP: |
| 39 | mask := super.DecodeIP(maskVal.Bytes()) |
| 40 | if mask.BitLen() != ip.BitLen() { |
| 41 | val := addressAndMask(n.sctx, ipVal, maskVal) |
| 42 | return n.sctx.WrapError("network_of: address and mask have different lengths", val) |
| 43 | } |
| 44 | bits = super.LeadingOnes(mask.AsSlice()) |
| 45 | if netip.PrefixFrom(mask, bits).Masked().Addr() != mask { |
| 46 | return n.sctx.WrapError("network_of: mask is non-contiguous", maskVal) |
| 47 | } |
| 48 | case super.IsInteger(id): |
| 49 | if super.IsSigned(id) { |
| 50 | bits = int(maskVal.Int()) |
| 51 | } else { |
| 52 | bits = int(maskVal.Uint()) |
| 53 | } |
| 54 | if bits > 128 || bits > 32 && ip.Is4() { |
| 55 | val := addressAndMask(n.sctx, ipVal, maskVal) |
| 56 | return n.sctx.WrapError("network_of: CIDR bit count out of range", val) |
| 57 | } |
| 58 | default: |
| 59 | return n.sctx.WrapError("network_of: bad arg for CIDR mask", args[1]) |
| 60 | } |
| 61 | } |
| 62 | // Mask for canonical form. |
| 63 | prefix := netip.PrefixFrom(ip, bits).Masked() |
| 64 | return super.NewNet(prefix) |
| 65 | } |
| 66 | |
| 67 | func addressAndMask(sctx *super.Context, address, mask super.Value) super.Value { |
| 68 | val, err := sup.NewBSUPMarshalerWithContext(sctx).Marshal(struct { |
nothing calls this directly
no test coverage detected