[prev in list] [next in list] [prev in thread] [next in thread] 

List:       tkined
Subject:    Re: [tkined] [patch] make ip discovery handle subnets
From:       COLIN_Stéphane <scolin () planetepc ! fr>
Date:       2002-09-17 10:44:41
[Download RAW message or body]

Hi !

Many thanks to you ...

This patch seem to fix even the troubles about the map of network after 
the ip discovery tool.

++

Keith Owens wrote:
> Trying to discover a subnet does not work on all versions of Linux.
> For example, ip discovery of a.b.c will probe a.b.c.[0-254].  But what
> if the probing machine has a netmask of a.b.c.0/25?  When netping tries
> a.b.c.128 (the broadcast address of the /25 subnet), some versions of
> Linux will return an error (cannot ping broadcast address) which kills
> netping and therefore ip discovery.
> 
> This patch against current CVS implements full CIDR support for ip
> discovery.  It also correctly handles class A and B networks, including
> subnets of A and B.  The old network formats are supported for
> backwards compatibility.  Now I can discover a.b.c.0/25 :)
> 
> My Tcl is rusty, this code can probably be improved.  There is a
> similar problem in ip_trouble.tcl which needs subnet support, one patch
> at a time ...
> 
> Even with CIDR support in ip discovery, you cannot probe outside the
> current host's network, because of the "cannot ping broadcast address"
> problem.  Either netping needs to recover from this error or the
> network list must exclude the current host's network and broadcast
> addresses.  I need to think about this a bit more.
> 
> diff -ur scotty/tkined/apps/ip_discover.tcl scotty.new/tkined/apps/ip_discover.tcl
> --- scotty/tkined/apps/ip_discover.tcl	Tue Feb 15 11:50:23 2000
> +++ scotty.new/tkined/apps/ip_discover.tcl	Tue Sep 17 18:11:44 2002
> @@ -153,19 +153,12 @@
> ##
> 
> ##
> -## Send an icmp request to all hosts on a class C like network. Return
> -## a list of all ip addresses that have responded to our request.
> +## Send an icmp request to a list of hosts. Return a list of all ip
> +## addresses that have responded to our request.
> ##
> 
> -proc netping { network } {
> -    set result ""
> -    if {[regexp {^[0-9]+\.[0-9]+\.[0-9]+$} $network] > 0} {
> -	set hosts ""
> -	for {set a4 1} {$a4<255} {incr a4} {
> -	    append hosts " $network.$a4"
> -	}
> -	set result [icmp echo $hosts]
> -    }
> +proc netping { hosts } {
> +    set result [icmp echo $hosts]
> set res ""
> foreach {pr_ip pr_time} $result {
> 	if {$pr_time>=0} {
> @@ -177,32 +170,96 @@
> 
> ##
> ## Try to get all ip nodes of a given network. We currently handle
> -## 255 nodes (all addresses of a class C like network) in parallel.
> -## Bigger networks (class B or even class A) are split in class C
> -## like networks.
> +## up to 256 hosts (all addresses of a class C like network) in
> +## parallel.  Bigger networks (class B or even class A) are split up
> +## into 256 host chunks.
> ##
> 
> proc discover_nodes {network} {
> -    if {[regexp {^[0-9]+\.[0-9]+\.[0-9]+$} $network] > 0} {
> -	set count 0
> -	set start [clock seconds]
> -	foreach ip [netping $network] {
> -	    create_node $ip
> -	    incr count
> -	}
> -	writeln "$count nodes found on network $network in [expr {[clock \
>                 seconds]-$start}] seconds."
> -	flush stdout
> +    set start_time [clock seconds]
> +    set oldnetwork "$network"
> +    if {[regexp {^[0-9]+$} $network] > 0} {
> +	set network "$network.0.0.0/8"
> }
> if {[regexp {^[0-9]+\.[0-9]+$} $network] > 0} {
> -	for {set a3 0} {$a3<256} {incr a3} {
> -	    discover_nodes $network.$a3
> -	}
> +	set network "$network.0.0/16"
> }
> -    if {[regexp {^[0-9]+$} $network] > 0} {
> -	for {set a2 0} {$a2<256} {incr a2} {
> -	    discover_nodes $network.$a2
> +    if {[regexp {^[0-9]+\.[0-9]+\.[0-9]+$} $network] > 0} {
> +	set network "$network.0/24"
> +    }
> +    if {"$oldnetwork" != "$network"} {
> +	writeln "$oldnetwork converted to $network"
> +    }
> +
> +    set valid 1
> +    if {[regexp {^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/([0-9]+)$} $network all \
> ia1 ia2 ia3 ia4 nm] == 0} { +	writeln "Not in network format, did you forget \
> /netmask?" +	set valid 0
> +    }
> +    if {$valid == 1 && ($ia1 < 1 || $ia1 > 223)} {
> +    	writeln "Invalid first byte $ia1"
> +	set valid 0
> +    }
> +    if {$valid == 1 && ($ia2 > 256)} {
> +    	writeln "Invalid byte $ia2"
> +	set valid 0
> +    }
> +    if {$valid == 1 && ($ia3 > 256)} {
> +    	writeln "Invalid byte $ia3"
> +	set valid 0
> +    }
> +    if {$valid == 1 && ($ia4 > 256)} {
> +    	writeln "Invalid byte $ia4"
> +	set valid 0
> +    }
> +    if {$valid == 1 && ($nm < 1 || $nm > 30)} {
> +    	writeln "Invalid netmask size $nm"
> +	set valid 0
> +    }
> +    if {$valid == 0} {
> +	writeln "Networks must be x.y.y.y/n with 1 <= x <= 223, 0 <= y <= 255, 1 <= n <= \
> 30" +	writeln "Short forms x, x.y and x.y.y are accepted for backwards \
> compatibility" +	return
> +    }
> +
> +    set ip [expr {($ia1 << 24) + ($ia2 << 16) + ($ia3 << 8) + $ia4}]
> +    set mask [expr {-(1 << (32 - $nm))}]
> +    if {[expr {$ip & ~$mask}] != 0} {
> +	set ip [expr {$ip & $mask}]
> +	set ia1 [expr {($ip >> 24) & 0xff}]
> +	set ia2 [expr {($ip >> 16) & 0xff}]
> +	set ia3 [expr {($ip >> 8) & 0xff}]
> +	set ia4 [expr {$ip & 0xff}]
> +	set network "$ia1.$ia2.$ia3.$ia4/$nm"
> +	writeln "Network has non-zero host bits, rewritten to $network"
> +    }
> +    set th [expr {(1<<[expr 32-$nm])-2}]
> +    set count 0
> +    set found 0
> +    for {} {$th > 0} {incr th -1} {
> +	incr ip
> +	set ia1 [expr {($ip >> 24) & 0xff}]
> +	set ia2 [expr {($ip >> 16) & 0xff}]
> +	set ia3 [expr {($ip >> 8) & 0xff}]
> +	set ia4 [expr {$ip & 0xff}]
> +	set host "$ia1.$ia2.$ia3.$ia4"
> +	if {$count == 0} {
> +	    set hosts ""
> +	    set start $host
> +	}
> +	incr count
> +	lappend hosts $host
> +	if {$count == 256 || $th == 1} {
> +	    writeln "Pinging hosts $start - $host"
> +	    foreach ip [netping $hosts] {
> +		create_node $ip
> +		incr found
> +	    }
> +	    set count 0
> 	}
> }
> +    writeln "$found nodes found on network $network in [expr {[clock \
> seconds]-$start_time}] seconds." +    flush stdout
> }
> 
> 
> 

-- 
-----------------------------------
COLIN Stephane, scolin@planetepc.fr
-----------------------------------

-- 
!! This message is brought to you via the `tkined' mailing list.
!! Please do not reply to this message to unsubscribe. To unsubscribe or adjust
!! your settings, send a mail message to <tkined-request@ibr.cs.tu-bs.de>
!! or look at https://www.ibr.cs.tu-bs.de/mailman/listinfo/tkined.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic