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

I can't seem to find a dhcp server in perl (that supports multiple interfaces). Any ideas how I can figure out which interface a broadcast udp packet came in on (for Linux 2.6)?

With Linux according to man 7 ip, it seems one is supposed to set the necessary socket options, read the ip_pktinfo/in_pktinfo stuff and then figure out what the ipi_ifindex is. Is there an easy way to do this in Perl? e.g. with IO::Socket::INET or something like that? :).

Of course one would also need to be able to specify that the reply frames leave on the same interface AND are destined to the relevant layer 2 address.

Is there a Perl way to do all that? Or is it easier to do this in Python or Ruby? I don't know either yet, but it seems likely to be more fun than writing everything in C... ;)

Thanks!

  • Comment on Figuring out which network interface a broadcast packet came in on?

Replies are listed 'Best First'.
Re: Figuring out which network interface a broadcast packet came in on?
by linuxfan (Beadle) on Sep 02, 2005 at 16:26 UTC
    I am not sure why you would need a DHCP server in perl? One easy way to determine the interface of an incoming packet is to use iptables with the LOG target. A rule similar to the following (untested) should log udp packets coming through eth0 to your /var/log/messages
    iptables -I INPUT -p udp --dport 67 -i eth0 -j LOG \ --log-prefix \ "broadcast on eth0"
    I do not know if what you want can be done using existing perl modules. Your problem requires querying kernel info, and am not sure if there are perl modules for that.
Re: Figuring out which network interface a broadcast packet came in on?
by gam3 (Curate) on Sep 02, 2005 at 16:34 UTC
      I believe those modules are for constructing DHCP packets, not for the actual sending or receiving.

      Something like Net-Packet (which I checked out months back) would be good. However I would like to bind to 0.0.0.0:$someport (and listen on all interfaces - not specific interfaces), and then figure out which interface a packet is coming in on (and then reply using the relevant interface). This would be much simpler and more efficient.

      With perl one can set socket options (I've done it for other socket options like SO_ORIGINAL_DST), however I don't know how to set the particular Linux options I need for this case and retrieve the ancillary messages, in order to figure out the packet's interface.

      Any ideas on how to do this in perl?

        I think you need to set rules in your routing table in order to route packets based on incoming/outgoing interfaces (ip is your friend here).

        As far as I know, a socket at the application layer can give you only information on ip address/port number and not about interface on which it arrived. You might have to dig into writing your own code at the kernel layer, or use one of the utilities like ip to get the information you want.

        Just my 2 cents..