Forum Discussion

Joel_42834's avatar
Joel_42834
Icon for Nimbostratus rankNimbostratus
Oct 19, 2012

IP Address Validation with CIDR

How can a validate an IP address that is stored in a string data group that uses CIDR notation?

 

 

For dotted netmasks I use: [IP::addr $address mask $netmask]

 

where $address is say "1.2.3.4" and $netmask is "255.255.255.0"

 

 

But this doesn't work for CIDR notation. You can't have "/24" for the value of $netmask.

 

 

I tried leaving it off: [IP::addr $address]

 

where $address = "1.2.3.4/24"

 

 

But it appears that the "mask" keyword & its argument are required.

 

Any help would be greatly appreciated.

 

5 Replies

  • not sure if i understand your question correctly or not.

    e.g.

    [root@ve10:Active] config  b class cidr_class list
    class cidr_class {
       {
          "1.1.1.1/24"
          "2.2.2.2/16"
       }
    }
    [root@ve10:Active] config  b rule myrule list
    rule myrule {
       when CLIENT_ACCEPTED {
       foreach elm [class get cidr_class] {
          if { [scan [lindex $elm 0] {%[^/]/%d} ip mask] == 2 } {
             switch $mask {
                16 { set mask_num "255.255.0.0" }
                24 { set mask_num "255.255.255.0" }
             }
             log local0. "\[IP::addr [lindex $elm 0]\] = [IP::addr $ip mask $mask_num]"
          }
       }
    }
    }
    
    [root@ve10:Active] config  cat /var/log/ltm
    Oct 19 17:47:50 local/tmm info tmm[7926]: Rule myrule : [IP::addr 1.1.1.1/24] = 1.1.1.0
    Oct 19 17:47:50 local/tmm info tmm[7926]: Rule myrule : [IP::addr 2.2.2.2/16] = 2.2.0.0
    
  • Sure, but that would require that I enumerate each possible CIDR value either in the code or in a data group that could be used to lookup the corresponding dotted netmask.

     

     

    There must be a better way!!
  • There must be a better way!!e.g.

     

     

    convert CIDR to subnet mask in tcl

     

    http://pastebin.com/KG4eLdCr
  • [root@ve10:Active] config  b rule myrule list
    rule myrule {
       when CLIENT_ACCEPTED {
       foreach elm [class get cidr_class] {
          if { [scan [lindex $elm 0] {%[^/]/%d} ip mask] == 2 } {
             set mask [expr {~ 0 << ( 32 - $mask )}]
             set mask_num [format "%d.%d.%d.%d" [expr {$mask >> 24 & 255}] [expr {$mask >> 16 & 255}] [expr {$mask >> 8 & 255}] [expr {$mask & 255}]]
             log local0. "\[IP::addr [lindex $elm 0]\] = [IP::addr $ip mask $mask_num]"
          }
       }
    }
    }
    
    [root@ve10:Active] config  cat /var/log/ltm
    Oct 20 00:52:16 local/tmm info tmm[7926]: Rule myrule : [IP::addr 1.1.1.1/24] = 1.1.1.0
    Oct 20 00:52:16 local/tmm info tmm[7926]: Rule myrule : [IP::addr 2.2.2.2/16] = 2.2.0.0
    
  • This works great.

     

     

    I think in the long run the IP::addr command should support direct checking: [IP::addr "1.2.3.4/24"]

     

     

    But for now, this will work well.

     

     

    Thanks - It's a big help