views:

3842

answers:

4

How can I get a list of the IP addresses or host names from a local network easily in Python?

It would be best if it was multi-platform, but it needs to work on Mac OS X first, then others follow.

Edit: By local I mean all active addresses within a local network, such as 192.168.xxx.xxx.

So, if the IP address of my computer (within the local network) is 192.168.1.1, and I have three other connected computers, I would want it to return the IP addresses 192.168.1.2, 192.168.1.3, 192.168.1.4, and possibly their hostnames.

A: 

One of the answers in this question might help you. There seems to be a platform agnostic version for python, but I haven't tried it yet.

TheObserver
No, i dont want my ip address, i want everyone elses. What Steve Moyer has said, but with code :)
joshhunt
+3  A: 

If by "local" you mean on the same network segment, then you have to perform the following steps:

  1. Determine your own IP address
  2. Determine your own netmask
  3. Determine the network range
  4. Scan all the addresses (except the lowest, which is your network address and the highest, which is your broadcast address).
  5. Use your DNS's reverse lookup to determine the hostname for IP addresses which respond to your scan.

Or you can just let Python execute nmap externally and pipe the results back into your program.

Steve Moyer
A: 

If you know the names of your computers you can use:

import socket
IP1 = socket.gethostbyname(socket.gethostname()) # local IP adress of your computer
IP2 = socket.gethostbyname('name_of_your_computer') # IP adress of remote computer

Otherwise you will have to scan for all the IP addresses that follow the same mask as your local computer (IP1), as stated in another answer.

Mapad
+2  A: 

I once wrote a small script, that leverages scapy's arping():

#! /usr/bin/env python
# vim: set fenc=utf8 ts=4 sw=4 et :

import scapy, sys, socket, math

def long2ip(arg):
    ip = [0,0,0,0]
    for i in xrange(0, 4):
        ip[i] = arg%256
        arg /= 256
    return ".".join(map(str, ip))

def long2net(arg):
    return int(round(math.log(arg,2)))

def to_CIDR_notation(bytes_network, bytes_netmask):
    network = long2ip(bytes_network)
    netmask = long2net(bytes_netmask)
    net = "%s/%s"%(network,netmask)
    return net

def scan_and_print_neighbors(net):
    ans,unans = scapy.arping(net, timeout=1, verbose=False)
    for s,r in ans.res:
        hostname = socket.gethostbyaddr(r.psrc)
        print r.sprintf("%Ether.src%  %ARP.psrc%"),
        print " ", hostname[0]

for r in scapy.conf.route.routes:
    # skip 127.0.0.0/8 and 0.0.0.0/0
    if r[0]==127 or r[0]==0:
        continue

    scan_and_print_neighbors(to_CIDR_notation(r[0], r[1]))

It's only tested on Linux, though.

bene
your endianness is incorrect in long2ip() and long2net()
newacct