jamesdmorris has asked for the wisdom of the Perl Monks concerning the following question:

At work we have a lot of Lucent ISDN Routers to configure, they come with a Java config utility, but this does not do everything we want, and besides I would like to automate the process down to a single script.

When an ISDN router is unboxed, it has no ip based settings at all. To avoid having to connect a serial cable to the device and give it an ip address, the Java config utility sends a UDP broadcast (255.255.255.255) to port 9 (discard) with the required ip settings in the data portion.

I have sniffed the traffic and successfully written a program to send the required UDP packet to 255.255.255.255. The ISDN router then replies with a confirmation packet, here lies the problem....
I can see the packet being transmitted from the ISDN router back to the pc doing the configuration, but I cannot get the perl program to receive that packet !
Does anyone have any source code to first send a broadcast then receive reponses from the hosts that send packets back ?

For reference the conversation normally goes thus:

PC: sends udp port 9, src: 192.168.1.1 dst: 255.255.255.255

ISDN: send udp response, src: <anything> dst: 192.168.1.1

Any help would be much appreciated !

Replies are listed 'Best First'.
Re: UDP Broadcasts
by rob_au (Abbot) on May 03, 2002 at 12:07 UTC
    Another way which you may want to go is to make use of the low-level libpcap packet capturing library through the combined usage of theNet::Pcap and NetPacket modules. This approach, while more involved, offers greater control over the router communication.

    For example, the following snippet of code can be used to capture UDP packets from the local network:

    use Net::PcapUtils; use NetPacket::IP; use NetPacket::UDP; use NetPacket::Ethernet qw/:types/; use strict; Net::PcapUtils::loop( sub { my ($arg, $header, $packet) = @_; my $ethernet = NetPacket::Ethernet->decode($packet); if ($ethernet->{'type'} == ETH_TYPE_IP) { my $ip = NetPacket::IP->decode($ethernet->{'data'}, $ether +net); my $udp = NetPacket::UDP->decode($ip->{'data'}); . . print $ip->{'src_ip'}, ":", $udp->{'src_port'}, " -> ", $ip->{'dest_ip'}, ":", $udp->{'dest_port'}, "\n"; } }, 'DEV' => 'eth0', # 'FILTER' => 'udp dst host 192.168.1.1' );

    The commented line in the above code snippet is an example filter which can be passed the packet-capturing library to minimise unwanted 'overhead' packets also captured.

    With regard to the initial UDP broadcast over the network, you will need to set the SO_BROADCAST option on the socket in order to request permission for the communication given the priviledged nature of this type of communication. For example:

    use IO::Socket; use strict; my $sock = new IO::Socket::INET( 'PeerAddr' => '55.255.255.255' 'PeerPort' => '9', 'Proto' => 'udp' ); $sock->sockopt(SO_BROADCAST, 1);

    Alternatively, depending upon your data requirements, the NetPacket group of modules referenced earlier can also be used to manually construct packets for transmission.

     

Re: UDP Broadcasts
by Anonymous Monk on May 02, 2002 at 16:48 UTC
    If you bind your socket before the broadcast to a portnumber (nothing fancy there, just any ordinary 1234 number) I think you will get your response there, which means a recv will do.
      here is my current source:
      #!/opt/perl-5.004/bin/perl use IO::Socket; my $pipeline_string= "\x00\x00\x07\xa2\x08\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x +00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0 +0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 +\x00\x00\x00\x00\x00\x00"; $bufsize = 1024; my $myip="204.4.143.170"; $sock = new IO::Socket::INET(PeerAddr => "255.255.255.255", PeerPort => "9", Proto => "udp", LocalAddr => $myip, LocalPort => "9999" ); $sock->send($pipeline_string); $sock->recv($buf, $bufsize); print $buf;
        I think there is a bug(let) in IO::Socket::INET. Local* is ignored if there is a PeerAddr. Annoyingly you will need it in your code. Otherwise your code should be good. Are you sure that the answer is printable and is not cut short at the first \x00?