Class: CiscoAclIntp::AceIpSpec

Inherits:
AceSpecBase show all
Extended by:
Forwardable
Defined in:
lib/cisco_acl_intp/acespec_ip.rb

Overview

IP Address and Wildcard mask container

Constant Summary collapse

OCTET_BIT_LENGTH =

Convert table of IPv4 bit-flapped wildcard octet to bit length

{
  '255' => 0, '127' => 1, '63' => 2, '31' => 3,
  '15' => 4, '7' => 5, '3' => 6, '1' => 7, '0' => 8
}.freeze

Constants inherited from AccessControlContainer

CiscoAclIntp::AccessControlContainer::TERM_COLOR_TABLE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from AccessControlContainer

#clean_acl_string, disable_color, #generate_tag_footer, #generate_tag_header, #generate_tagged_str, #method_missing

Constructor Details

#initialize(opts) ⇒ AceIpSpec

Constructor

Parameters:

  • opts (Hash)

    Options

Options Hash (opts):

  • :ipaddr (String)

    IP address (dotted decimal notation)

  • :wildcard (String)

    Wildcard mask (dotted decimal and bit flipped notation)

  • :netmask (Integer)

    Network Mask Length

Raises:



39
40
41
42
43
44
45
46
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 39

def initialize(opts)
  if opts.key?(:ipaddr)
    @options = opts
    define_addrinfo
  else
    raise AclArgumentError, 'Not specified IP address'
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class CiscoAclIntp::AccessControlContainer

Instance Attribute Details

#ipaddrNetAddr::CIDR (readonly)

Parameters:

  • value (NetAddr::CIDR)

    IP address (dotted decimal notation)

Returns:

  • (NetAddr::CIDR)


14
15
16
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 14

def ipaddr
  @ipaddr
end

#netmaskInteger (readonly)

Parameters:

  • value (Integer)

    Netmask length

Returns:

  • (Integer)


18
19
20
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 18

def netmask
  @netmask
end

#wildcardString (readonly)

Parameters:

  • value (String)

    Wildcard mask (dotted decimal and bit flapped notation)

Returns:

  • (String)


23
24
25
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 23

def wildcard
  @wildcard
end

Instance Method Details

#==(other) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


50
51
52
53
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 50

def ==(other)
  @ipaddr == other.ipaddr && ip == other.ip &&
    @netmask == other.netmask && @wildcard == other.wildcard
end

#check_ip_any_aliasAceIpSpec (private)

Check ip addr string: alias ‘any’ ipaddr

Returns:



110
111
112
113
114
115
116
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 110

def check_ip_any_alias
  case @options[:ipaddr]
  when nil, '', 'any', /^\s*$/
    @options[:ipaddr] = '0.0.0.0'
    @options[:netmask] = 0
  end
end

#contains?(address) ⇒ Boolean

Check subnet contained this object or not.

Parameters:

  • address (String)

    Subnet address string e.g. 192.168.0.0/24, 192.168.0.0/255.255.255.0

Returns:

  • (Boolean)

Raises:

  • (NetAddr::ValidationError)


82
83
84
85
86
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 82

def contains?(address)
  # `@ipaddr` contains(1), is same block(0),
  # is `contained(-1), is not related(nil)
  [0, 1].include?(@ipaddr.cmp(address))
end

#define_addrinfoObject (private)

Set instance variables



119
120
121
122
123
124
125
126
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 119

def define_addrinfo
  check_ip_any_alias
  if @options.key?(:wildcard)
    define_addrinfo_prefer_wildcard
  else
    define_addrinfo_by_netmask_or_default
  end
end

#define_addrinfo_by_netmask_or_defaultObject (private)

Set instance variables. Secondary prioritize option is netmask,

and third(last) one is default-mask


142
143
144
145
146
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 142

def define_addrinfo_by_netmask_or_default
  # default ('host' mask)
  @options[:netmask] = 32 unless @options.key?(:netmask)
  define_addrinfo_with_netmask
end

#define_addrinfo_prefer_wildcardObject (private)

Set instance variables. assume that wildcard is primary option.



129
130
131
132
133
134
135
136
137
138
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 129

def define_addrinfo_prefer_wildcard
  @wildcard = @options[:wildcard]
  @netmask = wildcard_bitlength
  if @netmask
    @options[:netmask] = @netmask
    define_addrinfo_with_netmask
  else
    define_addrinfo_with_wildcard
  end
end

#define_addrinfo_with_netmaskObject (private)

Set instance variables with ip/netmask



158
159
160
161
162
163
164
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 158

def define_addrinfo_with_netmask
  @netmask = @options[:netmask]
  @ipaddr = NetAddr::CIDR.create(
    format('%s/%s', @options[:ipaddr], @netmask)
  )
  @wildcard = @ipaddr.wildcard_mask(true)
end

#define_addrinfo_with_wildcardObject (private)

Set instance variables with ip/wildcard



149
150
151
152
153
154
155
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 149

def define_addrinfo_with_wildcard
  @ipaddr = NetAddr::CIDR.create(
    @options[:ipaddr],
    WildcardMask: [@wildcard, true]
  )
  @netmask = nil
end

#to_sString

Generate string for Cisco IOS access list

Returns:

  • (String)


57
58
59
60
61
62
63
64
65
66
67
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 57

def to_s
  if to_wmasked_ip_s == '0.0.0.0'
    # ip = '0.0.0.0' or wildcard = '255.255.255.255'
    tag_ip('any')
  elsif @wildcard == '0.0.0.0'
    # /32 mask
    format '%s %s', tag_mask('host'), tag_ip(@ipaddr.ip)
  else
    format '%s %s', tag_ip(to_wmasked_ip_s), tag_mask(@wildcard)
  end
end

#to_wmasked_ip_sString

Generate wildcard-masked ip address string

Returns:

  • (String)

    wildcard-masked ip address string



71
72
73
74
75
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 71

def to_wmasked_ip_s
  ai = NetAddr.ip_to_i(@ipaddr.ip)
  mi = NetAddr.ip_to_i(@ipaddr.wildcard_mask)
  NetAddr.i_to_ip(ai & mi)
end

#wildcard_bitlengthFixnum (private)

TODO:

Known bug: it cannot handle wrong wildcard, e.g. ‘0.0.0.1.255’ #=> 31

Covnet IPv4 bit-flapped wildcard to netmask length

Returns:

  • (Fixnum)

    netmask length or ‘nil` when discontinuous-bits-wildcard-mask



101
102
103
104
105
106
# File 'lib/cisco_acl_intp/acespec_ip.rb', line 101

def wildcard_bitlength
  @wildcard.split(/\./).reduce(0) do |len, octet|
    break unless len && OCTET_BIT_LENGTH.key?(octet)
    len + OCTET_BIT_LENGTH[octet]
  end
end