# and Technology through the research contract #IP-2003-143.
#
-# $Id: ipv4.tcl,v 1.15 2008/01/02 12:08:46 marko Exp $
+# $Id: ipv4.tcl,v 1.16 2008/05/17 01:57:02 marko Exp $
#****h* imunes/ipv4.tcl
# ipv4.tcl -- file for handeling IPv4
#****
+set ipv4 10.0.0.0/24
+set numbits [lindex [split $ipv4 /] 1]
+set control 0
+set changeAddrRange 0
+
+proc IPv4AddrApply { w } {
+ global ipv4
+ global numbits
+ global changed
+ global control
+
+ set newipv4 [$w.e1 get]
+
+ if { [checkIPv4Net $newipv4] == 0 } {
+ focusAndFlash .entry1.e1
+ return
+ }
+ destroy $w
+
+ if { $newipv4 != $ipv4 } {
+ set changed 1
+ set control 1
+ }
+ set ipv4 $newipv4
+ set numbits [lindex [split $ipv4 /] 1]
+}
+
+proc dec2bin {dec} {
+ set res ""
+ while {$dec > 0} {
+ set res [expr {$dec % 2}]$res
+ set dec [expr {$dec / 2}]
+ }
+ if {$res == ""} {set res 0}
+ if {[string length $res] < 8} {
+ set n [expr {8-[string length $res]}]
+ for {set i 0} {$i < $n} {incr i} {
+ set res 0$res
+ }
+ }
+ return $res
+}
+
+proc bin2dec {bin} {
+ set res 0
+ foreach i $bin {
+ set res [expr {$res*2 + $i}]
+ }
+ return $res
+}
+
+
#****f* ipv4.tcl/findFreeIPv4Net
# NAME
# findFreeIPv4Net -- find free IPv4 network
# INPUTS
# * mask -- this parameter is left unused for now
# RESULT
-# * ipnet -- returns the free IPv4 network address in the form 10.a.b
-#****
-
+# * ipnet -- returns the free IPv4 network address in the form a.b.c.d
+#****
+
proc findFreeIPv4Net { mask } {
upvar 0 ::cf::[set ::curcfg]::node_list node_list
+ global ipv4
+ global numbits
+
+ set numbits $mask
+
+ set addr [lindex [split $ipv4 /] 0]
+
+ set a [dec2bin [lindex [split $addr .] 0]]
+ set b [dec2bin [lindex [split $addr .] 1]]
+ set c [dec2bin [lindex [split $addr .] 2]]
+ set d [dec2bin [lindex [split $addr .] 3]]
+
+ set addr_bin $a$b$c$d
+
+ set host_id [string range $addr_bin $numbits end]
+
+ while {[string first 1 $host_id] != -1} {
+ set i [string first 1 $host_id]
+ set host_id [string replace $host_id $i $i 0]
+ }
+
+ set net_id [string range $addr_bin 0 [expr {$numbits-1}]]
+
+ set sub_addr $net_id$host_id
+
+ if {$numbits == 8 || $numbits == 16 || $numbits == 24} {
+ set pot 0
+ } else {
+ set pot [expr {8 - ($numbits % 8)}]
+ }
+
+ set step [expr {1 << $pot}]
+
set ipnets {}
+
foreach node $node_list {
foreach ifc [ifcList $node] {
- set ipnet [lrange [split [getIfcIPv4addr $node $ifc] .] 0 2]
+ if {$numbits <= 8} {
+ set ipnet [lindex [split [getIfcIPv4addr $node $ifc] .] 0]
+ } elseif {$numbits > 8 && $numbits <=16} {
+ set ipnet [lrange [split [getIfcIPv4addr $node $ifc] .] 0 1]
+ } elseif {$numbits > 16 && $numbits <=24} {
+ set ipnet [lrange [split [getIfcIPv4addr $node $ifc] .] 0 2]
+ } elseif {$numbits > 24} {
+ set ifcaddr [lindex [split [getIfcIPv4addr $node $ifc] /] 0]
+ if {[lindex [split $ifcaddr .] 3] != ""} {
+ set x [expr {[lindex [split $ifcaddr .] 3] - \
+ ([lindex [split $ifcaddr .] 3] % $step)}]
+ set ipnet [split $ifcaddr .]
+ lset ipnet 3 $x
+ } else {
+ set ipnet {}
+ }
+ }
if {[lsearch $ipnets $ipnet] == -1} {
lappend ipnets $ipnet
}
}
}
- for { set i 0 } { $i <= 255 } { incr i } {
- for { set j 0 } { $j <= 255 } { incr j } {
- if {[lsearch $ipnets "10 $i $j"] == -1} {
- set ipnet "10.$i.$j"
+
+ set a_sub [bin2dec [split [string range $sub_addr 0 7] {}]]
+ set b_sub [bin2dec [split [string range $sub_addr 8 15] {}]]
+ set c_sub [bin2dec [split [string range $sub_addr 16 23] {}]]
+ set d_sub [bin2dec [split [string range $sub_addr 24 31] {}]]
+
+ if {$numbits <= 8} {
+ for { set i $a_sub } { $i <= 255 } { incr i $step } {
+ if {[lsearch $ipnets "$i"] == -1} {
+ set ipnet "$i"
return $ipnet
+ }
+ }
+ } elseif {$numbits > 8 && $numbits <=16} {
+ for { set i $a_sub } { $i <= 255 } { incr i } {
+ for { set j $b_sub } { $j <= 255 } { incr j $step } {
+ if {[lsearch $ipnets "$i $j"] == -1} {
+ set ipnet "$i.$j"
+ return $ipnet
+ }
}
}
- }
+ } elseif {$numbits > 16 && $numbits <=24} {
+ for { set i $a_sub } { $i <= 255 } { incr i } {
+ for { set j $b_sub } { $j <= 255 } { incr j } {
+ for { set k $c_sub } { $k <= 255 } { incr k $step } {
+ if {[lsearch $ipnets "$i $j $k"] == -1} {
+ set ipnet "$i.$j.$k"
+ return $ipnet
+ }
+ }
+ }
+ }
+ } elseif {$numbits > 24} {
+ for { set i $a_sub } { $i <= 255 } { incr i } {
+ for { set j $b_sub } { $j <= 255 } { incr j } {
+ for { set k $c_sub } { $k <= 255 } { incr k } {
+ for { set l $d_sub } { $l <= 255 } { incr l $step } {
+ if {[lsearch $ipnets "$i $j $k $l"] == -1} {
+ set ipnet "$i.$j.$k.$l"
+ return $ipnet
+ }
+ }
+ }
+ }
+ }
+ }
}
#****f* ipv4.tcl/autoIPv4addr
#****
proc autoIPv4addr { node iface } {
+
+ global numbits
+ global changeAddrRange
+ global control
+
set peer_ip4addrs {}
if { [[typemodel $node].layer] != "NETWORK" } {
set peer_node [logicalPeerByIfc $node $iface]
- if { [[typemodel $peer_node].layer] == "LINK" } {
+ if { [[typemodel $peer_node].layer] == "LINK" && $control == 0 } {
foreach l2node [listLANnodes $peer_node {}] {
foreach ifc [ifcList $l2node] {
set peer [logicalPeerByIfc $l2node $ifc]
}
}
}
- } else {
+ } elseif {[[typemodel $peer_node].layer] != "LINK"} {
set peer_if [ifcByLogicalPeer $peer_node $node]
set peer_ip4addr [getIfcIPv4addr $peer_node $peer_if]
set peer_ip4addrs [lindex [split $peer_ip4addr /] 0]
}
+
switch -exact -- [nodeType $node] {
router {
set targetbyte 1
set targetbyte 20
}
}
- if { $peer_ip4addrs != "" } {
- set ipnums [split [lindex $peer_ip4addrs 0] .]
- set net "[lindex $ipnums 0].[lindex $ipnums 1].[lindex $ipnums 2]"
- set ipaddr $net.$targetbyte
- while { [lsearch $peer_ip4addrs $ipaddr] >= 0 } {
- incr targetbyte
- set ipaddr $net.$targetbyte
- }
- setIfcIPv4addr $node $iface "$ipaddr/24"
+
+ set targetbyte2 0
+
+ if { $peer_ip4addrs != "" && $changeAddrRange == 0 } {
+ set ipnums [split [lindex $peer_ip4addrs 0] .]
+
+ set targetbyte3 [expr {[lindex $ipnums 3] + 1}]
+
+ if {$numbits <= 8} {
+ set net "[lindex $ipnums 0]"
+ set ipaddr $net.$targetbyte2.$targetbyte2.$targetbyte
+ while { [lsearch $peer_ip4addrs $ipaddr] >= 0 } {
+ incr targetbyte
+ set ipaddr $net.$targetbyte2.$targetbyte2.$targetbyte
+ }
+ } elseif {$numbits > 8 && $numbits <=16} {
+ set net "[lindex $ipnums 0].[lindex $ipnums 1]"
+ set ipaddr $net.$targetbyte2.$targetbyte
+ set x [lindex [split $net .] 1]
+ while { [lsearch $peer_ip4addrs $ipaddr] >= 0 } {
+ incr targetbyte
+ set ipaddr $net.$targetbyte2.$targetbyte
+ }
+ } elseif {$numbits > 16 && $numbits <=24} {
+ set net "[lindex $ipnums 0].[lindex $ipnums 1].[lindex $ipnums 2]"
+ set ipaddr $net.$targetbyte
+ while { [lsearch $peer_ip4addrs $ipaddr] >= 0 } {
+ incr targetbyte
+ set ipaddr $net.$targetbyte
+ }
+ } elseif {$numbits > 24} {
+ set first3bytes \
+ "[lindex $ipnums 0].[lindex $ipnums 1].[lindex $ipnums 2]"
+ set ipaddr $first3bytes.$targetbyte3
+ while { [lsearch $peer_ip4addrs $ipaddr] >= 0 } {
+ incr targetbyte3
+ set ipaddr $first3bytes.$targetbyte3
+ }
+ }
+
+ setIfcIPv4addr $node $iface "$ipaddr/$numbits"
+
} else {
- setIfcIPv4addr $node $iface "[findFreeIPv4Net 24].$targetbyte/24"
+ if {$numbits <= 8} {
+ setIfcIPv4addr $node $iface "[findFreeIPv4Net $numbits].$targetbyte2.$targetbyte2.$targetbyte/$numbits"
+ } elseif {$numbits > 8 && $numbits <=16} {
+ setIfcIPv4addr $node $iface "[findFreeIPv4Net $numbits].$targetbyte2.$targetbyte/$numbits"
+ } elseif {$numbits > 16 && $numbits <=24} {
+ setIfcIPv4addr $node $iface "[findFreeIPv4Net $numbits].$targetbyte/$numbits"
+ } elseif {$numbits > 24} {
+ set lastbyte [lindex [split [findFreeIPv4Net $numbits] .] 3]
+ set first3bytes [join [lrange [split [findFreeIPv4Net $numbits] .] 0 2] .]
+ set targetbyte3 [expr {$lastbyte + 1}]
+ setIfcIPv4addr $node $iface "$first3bytes.$targetbyte3/$numbits"
+ }
}
}