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

Here is the problem. I have 9 IP blocks to monitor on a weekly basis for the addition of hosts. I have written a script that uses socket(), however, I don't want the whole socket, as it takes too much time. All I want is:
My station target host syn----------------------> <--------------------- syn/ack rst---------------------->
I have everything the script working with the socket() for my block of IP's, but want to reduce the load. Thus changing the code to only use the syn, syn/ack, rst to reduce network load thus reducing the overall time.

PS.. I am intentionally running this at full boar to create lots of noise to prevent it from being used for evil.

Edit by tye to preserve structure

Replies are listed 'Best First'.
Re: Low Level Network Connections
by tadman (Prior) on Mar 01, 2002 at 18:03 UTC
    The trick is to use SOCK_RAW to do the dirty work. You can formulate your own packets here, sans protocol. You should look at examples like traceroute.c for inspiration, and should also have a full understanding of both IP and the UNIX socket architecture. Otherwise, this will be an exercise in futility.

    I would suggest that a better approach is to interface Perl with NMAP which does everything you want, and then some, and has the advantage of already being implemented and tested.
Re: Low Level Network Connections
by dws (Chancellor) on Mar 01, 2002 at 18:04 UTC
    I have everything the script working with the socket() for my block of IP's, but want to reduce the load. Thus changing the code to only use the syn, syn/ack, rst to reduce network load thus reducing the overall time.

    What is your basis for determining that you need to reduce a 7 packet connect/disconnect sequence to 3 packets? Are you really sure you need to reduce load, or might you be indulging in a round of premature optimization?

    Unless you need sub-second awareness of new hosts, I wouldn't bother with this. A simple "can I open a socket to a port at this IP address" test is more sufficient, and more maintainable to whoever picks up the code after you move on.

      Currently the scan of a /28 network via a dial-up connection takes roughly 1.5 hours. We are migrating from one /28 to 7-/27's, 1-/25 and 1-/24. I'm looking to reduce time any place I can. PS... Our policy insists that we use an outside connection and broadband isn't available. That is why I'm using a dial-up connection.
        If this is taking 1.5 hours, then whatever system you are using can't be that efficient. Assuming you're looking for a particular port to be open, you can do this quickly with NMAP. Here is an example that looks for machines with port 80 (http) open:
        % nmap X.X.X.0/24 -p 80 -T Insane -n The 1 scanned port on (X.X.X.137) is: closed The 1 scanned port on (X.X.X.146) is: closed The 1 scanned port on (X.X.X.147) is: closed Interesting ports on (X.X.X.152): Port State Service 80/tcp open http :
        So you get this output quickly and easily. If you want, you can choose XML output using -oX and then use XML::Parser to get the goods.

        As the root user you can engage the -PS option which uses SYN instead of ACK, the feature you were asking how to implement.

        Even over 300-baud dial-up, NMAP should be able to finish in several minutes for a /28, which is all of 30 hosts. 30. That's not a lot.
        Currently the scan of a /28 network via a dial-up connection takes roughly 1.5 hours.

        This sounds very wrong. That's 90 minutes to scan 31 hosts. That's nearly 3 minutes per host! I can manually ping all 31 hosts faster than that.

        Show us your code.

Re: Low Level Network Connections
by gellyfish (Monsignor) on Mar 01, 2002 at 23:20 UTC

    You might want to look at Net::Pcap if nothing else will suit.

    /J\

Re: Low Level Network Connections
by zengargoyle (Deacon) on Mar 02, 2002 at 02:07 UTC

    You say: "I have 9 IP blocks to monitor on a weekly basis for the addition of hosts."

    What do you mean?

    1. I don't trust my co-lo's security. I'm fearfull somebody is going to sneak in and put a machine on my hub without my knowledge.
    2. I have a bunch of UML hosts and I want to make sure my IP's don't end up on somebody elses host.
    3. I'm scanning (2**16) * 2 * every IP that's mine without checking to see if the machine is actually there in a single thread. (this over dialup is a fools-errand)
    4. Other...

    Each is a different problem.

    If you have reason enough to be paranoid to such a degree (not that it's a bad thing to be), here's a first go at it.

    I'm going to assume that you're scanning from outside your space on the odd chance that a cracker/whatever might be smart enough to hide something on your server that won't respond to hosts in it's local subnet.

    I'm also assuming that you have a single router interface from your provider for all your subnets. Things can get more complex.

    Make sure the ACL on the interface drops(logs) incoming packets from outside your address space (spoof).

    Put a secure as possible server on you net. Say only latest SSH on non standard port. If you can arrange a static ip for your dialup.... (ha) only accept connections from the static ip.

    SSH to the sekret server, add an alias to it's interface for some far out random ip, use nmap from that alias.

    Try ping -b. A host that want's to communicate will have to answer an ARP.

    Run Snort on the sekret server. Pay special attention to alerting on traffic to (host|port)'s that aren't on your special list. Bonus: have it page you when it finds something at 3:14 a.m.