Changeset 884:4496ced01993

Show
Ignore:
Timestamp:
08/25/08 19:34:47 (4 months ago)
Author:
Phil <phil@secdev.org>
Message:

Splitted arch.py into a submodule and different architectures

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • scapy/arch/__init__.py

    r862 r884  
    77import sys,os,struct,socket,time 
    88from fcntl import ioctl 
    9 from data import * 
    10  
    11 import config 
     9from scapy.error import * 
    1210 
    1311try: 
     
    2523    PYX=0 
    2624 
    27  
    28 LINUX=sys.platform.startswith("linux") 
    29 OPENBSD=sys.platform.startswith("openbsd") 
    30 FREEBSD=sys.platform.startswith("freebsd") 
    31 NETBSD = sys.platform.startswith("netbsd") 
    32 DARWIN=sys.platform.startswith("darwin") 
    33 BIG_ENDIAN= struct.pack("H",1) == "\x00\x01" 
    34 X86_64 = (os.uname()[4] == 'x86_64') 
    35 SOLARIS=sys.platform.startswith("sunos") 
    36  
    37 if LINUX: 
    38     DNET=PCAP=0 
    39 else: 
    40     DNET=PCAP=1 
    41  
    42 if OPENBSD or FREEBSD or NETBSD or DARWIN: 
    43     LOOPBACK_NAME="lo0" 
    44 else: 
    45     LOOPBACK_NAME="lo" 
    46  
    47      
    48  
    49 if PCAP: 
    50     try: 
    51         import pcap 
    52         PCAP = 1 
    53     except ImportError: 
    54         if LINUX: 
    55             log_loading.warning("did not find pcap module. Fallback to linux primitives") 
    56             PCAP = 0 
    57         else: 
    58             if __name__ == "__main__": 
    59                 log_loading.error("did not find pcap module") 
    60                 raise SystemExit 
    61             else: 
    62                 raise 
    63  
    64 if DNET: 
    65     try: 
    66         import dnet 
    67         DNET = 1 
    68     except ImportError: 
    69         if LINUX: 
    70             log_loading.warning("did not find dnet module. Fallback to linux primitives") 
    71             DNET = 0 
    72         else: 
    73             if __name__ == "__main__": 
    74                 log_loading.error("did not find dnet module") 
    75                 raise SystemExit 
    76             else: 
    77                 raise 
    78  
    79 if not PCAP: 
    80     f = os.popen("tcpdump -V 2> /dev/null") 
    81     if f.close() >> 8 == 0x7f: 
    82         log_loading.warning("Failed to execute tcpdump. Check it is installed and in the PATH") 
    83         TCPDUMP=0 
    84     else: 
    85         TCPDUMP=1 
    86     del(f) 
    87          
    88      
    89  
    9025try: 
    9126    from Crypto.Cipher import ARC4 
     
    9328    log_loading.info("Can't find Crypto python lib. Won't be able to decrypt WEP") 
    9429 
    95  
    96 # Workarround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470 
    97 try: 
    98     socket.inet_aton("255.255.255.255") 
    99 except socket.error: 
    100     def inet_aton(x): 
    101         if x == "255.255.255.255": 
    102             return "\xff"*4 
    103         else: 
    104             return socket.inet_aton(x) 
    105 else: 
    106     inet_aton = socket.inet_aton 
    107  
    108 inet_ntoa = socket.inet_ntoa 
    109 try: 
    110     inet_ntop = socket.inet_ntop 
    111     inet_pton = socket.inet_pton 
    112 except AttributeError: 
    113     log_loading.info("inet_ntop/pton functions not found. Python IPv6 support not present") 
    114  
    115  
    116 if SOLARIS: 
    117     # GRE is missing on Solaris 
    118     socket.IPPROTO_GRE = 47 
    11930 
    12031 
     
    12435 
    12536 
    126 ###################### 
    127 ## Interfaces stuff ## 
    128 ###################### 
    129  
    130  
    131 if DNET: 
    132     def get_if_raw_hwaddr(iff): 
    133         if iff[:2] == LOOPBACK_NAME: 
    134             return (772, '\x00'*6) 
    135         try: 
    136             l = dnet.intf().get(iff) 
    137             l = l["link_addr"] 
    138         except: 
    139             raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff) 
    140         return l.type,l.data 
    141     def get_if_raw_addr(ifname): 
    142         i = dnet.intf() 
    143         return i.get(ifname)["addr"].data 
    144 else: 
    145     def get_if_raw_hwaddr(iff): 
    146         return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR)) 
    147  
    148     def get_if_raw_addr(iff): 
    149         try: 
    150             return get_if(iff, SIOCGIFADDR)[20:24] 
    151         except IOError: 
    152             return "\0\0\0\0" 
    153  
    154  
    155 if PCAP: 
    156     def get_if_list(): 
    157         # remove 'any' interface 
    158         return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs())) 
    159     def get_working_if(): 
    160         try: 
    161             return pcap.lookupdev() 
    162         except Exception: 
    163             return LOOPBACK_NAME 
    164  
    165     def attach_filter(s, filter): 
    166         warning("attach_filter() should not be called in PCAP mode") 
    167     def set_promisc(s,iff,val=1): 
    168         warning("set_promisc() should not be called in DNET/PCAP mode") 
    169      
    170 else: 
    171     def get_if_list(): 
    172         f=open("/proc/net/dev","r") 
    173         lst = [] 
    174         f.readline() 
    175         f.readline() 
    176         for l in f: 
    177             lst.append(l.split(":")[0].strip()) 
    178         return lst 
    179     def get_working_if(): 
    180         for i in get_if_list(): 
    181             if i == LOOPBACK_NAME:                 
    182                 continue 
    183             ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0] 
    184             if ifflags & IFF_UP: 
    185                 return i 
    186         return LOOPBACK_NAME 
    187     def attach_filter(s, filter): 
    188         # XXX We generate the filter on the interface conf.iface  
    189         # because tcpdump open the "any" interface and ppp interfaces 
    190         # in cooked mode. As we use them in raw mode, the filter will not 
    191         # work... one solution could be to use "any" interface and translate 
    192         # the filter from cooked mode to raw mode 
    193         # mode 
    194         if not TCPDUMP: 
    195             return 
    196         try: 
    197             f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (config.conf.prog.tcpdump,config.conf.iface,filter)) 
    198         except OSError,msg: 
    199             log_interactive.warning("Failed to execute tcpdump: (%s)") 
    200             return 
    201         lines = f.readlines() 
    202         if f.close(): 
    203             raise Scapy_Exception("Filter parse error") 
    204         nb = int(lines[0]) 
    205         bpf = "" 
    206         for l in lines[1:]: 
    207             bpf += struct.pack("HBBI",*map(long,l.split())) 
    208      
    209         # XXX. Argl! We need to give the kernel a pointer on the BPF, 
    210         # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch. 
    211         if X86_64: 
    212             bpfh = struct.pack("HL", nb, id(bpf)+36) 
    213         else: 
    214             bpfh = struct.pack("HI", nb, id(bpf)+20)   
    215         s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh) 
    216  
    217     def set_promisc(s,iff,val=1): 
    218         mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "") 
    219         if val: 
    220             cmd = PACKET_ADD_MEMBERSHIP 
    221         else: 
    222             cmd = PACKET_DROP_MEMBERSHIP 
    223         s.setsockopt(SOL_PACKET, cmd, mreq) 
    224  
    225  
    226  
    227 ################## 
    228 ## Routes stuff ## 
    229 ################## 
    230  
    231 if not LINUX: 
    232  
    233     def new_read_routes(): 
    234  
    235         rtlst = [] 
    236         def addrt(rt,lst): 
    237             dst,gw = rt 
    238             lst.append(rt) 
    239  
    240         r = dnet.route() 
    241         print r.loop(addrt, rtlst) 
    242         return rtlst 
    243  
    244     def read_routes(): 
    245         if SOLARIS: 
    246             f=os.popen("netstat -rvn") # -f inet 
    247         elif FREEBSD: 
    248             f=os.popen("netstat -rnW") # -W to handle long interface names 
    249         else: 
    250             f=os.popen("netstat -rn") # -f inet 
    251         ok = 0 
    252         mtu_present = False 
    253         routes = [] 
    254         for l in f.readlines(): 
    255             if not l: 
    256                 break 
    257             l = l.strip() 
    258             if l.find("----") >= 0: # a separation line 
    259                 continue 
    260             if l.find("Destination") >= 0: 
    261                 ok = 1 
    262                 if l.find("Mtu") >= 0: 
    263                     mtu_present = True 
    264                 continue 
    265             if ok == 0: 
    266                 continue 
    267             if not l: 
    268                 break 
    269             if SOLARIS: 
    270                 dest,mask,gw,netif,mxfrg,rtt,ref,flg = l.split()[:8] 
    271             else: 
    272                 if mtu_present: 
    273                     dest,gw,flg,ref,use,mtu,netif = l.split()[:7] 
    274                 else: 
    275                     dest,gw,flg,ref,use,netif = l.split()[:6] 
    276             if flg.find("Lc") >= 0: 
    277                 continue                 
    278             if dest == "default": 
    279                 dest = 0L 
    280                 netmask = 0L 
    281             else: 
    282                 if SOLARIS: 
    283                     netmask = atol(mask) 
    284                 elif "/" in dest: 
    285                     dest,netmask = dest.split("/") 
    286                     netmask = itom(int(netmask)) 
    287                 else: 
    288                     netmask = itom((dest.count(".") + 1) * 8) 
    289                 dest += ".0"*(3-dest.count(".")) 
    290                 dest = atol(dest) 
    291             if not "G" in flg: 
    292                 gw = '0.0.0.0' 
    293             ifaddr = get_if_addr(netif) 
    294             routes.append((dest,netmask,gw,netif,ifaddr)) 
    295         f.close() 
    296         return routes 
    297  
    298     def read_interfaces(): 
    299         i = dnet.intf() 
    300         ifflist = {} 
    301         def addif(iff,lst): 
    302             if not iff.has_key("addr"): 
    303                 return 
    304             if not iff.has_key("link_addr"): 
    305                 return 
    306             rawip = iff["addr"].data 
    307             ip = inet_ntoa(rawip) 
    308             rawll = iff["link_addr"].data 
    309             ll = str2mac(rawll) 
    310             lst[iff["name"]] = (rawll,ll,rawip,ip) 
    311         i.loop(addif, ifflist) 
    312         return ifflist 
    313  
    314              
    315 else: 
    316  
    317     def read_routes(): 
    318         f=open("/proc/net/route","r") 
    319         routes = [] 
    320         s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    321         ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",LOOPBACK_NAME)) 
    322         addrfamily = struct.unpack("h",ifreq[16:18])[0] 
    323         if addrfamily == socket.AF_INET: 
    324             ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x",LOOPBACK_NAME)) 
    325             msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0]) 
    326             dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk 
    327             ifaddr = inet_ntoa(ifreq[20:24]) 
    328             routes.append((dst, msk, "0.0.0.0", LOOPBACK_NAME, ifaddr)) 
    329         else: 
    330             warning("Interface lo: unkown address family (%i)"% addrfamily) 
    331      
    332         for l in f.readlines()[1:]: 
    333             iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split() 
    334             flags = int(flags,16) 
    335             if flags & RTF_UP == 0: 
    336                 continue 
    337             if flags & RTF_REJECT: 
    338                 continue 
    339             try: 
    340                 ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff)) 
    341             except IOError: # interface is present in routing tables but does not have any assigned IP 
    342                 ifaddr="0.0.0.0" 
    343             else: 
    344                 addrfamily = struct.unpack("h",ifreq[16:18])[0] 
    345                 if addrfamily == socket.AF_INET: 
    346                     ifaddr = inet_ntoa(ifreq[20:24]) 
    347                 else: 
    348                     warning("Interface %s: unkown address family (%i)"%(iff, addrfamily)) 
    349                     continue 
    350             routes.append((socket.htonl(long(dst,16))&0xffffffffL, 
    351                            socket.htonl(long(msk,16))&0xffffffffL, 
    352                            inet_ntoa(struct.pack("I",long(gw,16))), 
    353                            iff, ifaddr)) 
    354          
    355         f.close() 
    356         return routes 
    357  
    358     def get_if(iff,cmd): 
    359         s=socket.socket() 
    360         ifreq = ioctl(s, cmd, struct.pack("16s16x",iff)) 
    361         s.close() 
    362         return ifreq 
    363  
    364  
    365     def get_if_index(iff): 
    366         return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0]) 
    367  
    368     def get_last_packet_timestamp(sock): 
    369         ts = ioctl(sock, SIOCGSTAMP, "12345678") 
    370         s,us = struct.unpack("II",ts) 
    371         return s+us/1000000.0 
    372  
    37337     
    37438def get_if_addr(iff): 
    375     return inet_ntoa(get_if_raw_addr(iff)) 
     39    return socket.inet_ntoa(get_if_raw_addr(iff)) 
    37640     
    37741def get_if_hwaddr(iff): 
     
    38347 
    38448 
     49LINUX=sys.platform.startswith("linux") 
     50OPENBSD=sys.platform.startswith("openbsd") 
     51FREEBSD=sys.platform.startswith("freebsd") 
     52NETBSD = sys.platform.startswith("netbsd") 
     53DARWIN=sys.platform.startswith("darwin") 
     54SOLARIS=sys.platform.startswith("sunos") 
    38555 
     56X86_64 = (os.uname()[4] == 'x86_64') 
     57 
     58 
     59# Next step is to import following architecture specific functions: 
     60# def get_if_raw_hwaddr(iff) 
     61# def get_if_raw_addr(iff): 
     62# def get_if_list(): 
     63# def get_working_if(): 
     64# def attach_filter(s, filter): 
     65# def set_promisc(s,iff,val=1): 
     66# def read_routes(): 
     67# def get_if(iff,cmd): 
     68# def get_if_index(iff): 
     69 
     70 
     71 
     72if LINUX: 
     73    from linux import * 
     74elif OPENBSD or FREEBSD or NETBSD or DARWIN: 
     75    from bsd import * 
     76elif SOLARIS: 
     77    from solaris import * 
     78     
     79 
     80import scapy.config 
     81scapy.config.conf.iface = get_working_if() 
  • scapy/arch/linux.py

    r862 r884  
    55 
    66 
     7from __future__ import with_statement 
    78import sys,os,struct,socket,time 
    89from fcntl import ioctl 
    9 from data import * 
    10  
    11 import config 
    12  
    13 try: 
    14     import Gnuplot 
    15     GNUPLOT=1 
    16 except ImportError: 
    17     log_loading.info("did not find python gnuplot wrapper . Won't be able to plot") 
    18     GNUPLOT=0 
    19  
    20 try: 
    21     import pyx 
    22     PYX=1 
    23 except ImportError: 
    24     log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump()") 
    25     PYX=0 
     10import scapy.utils 
    2611 
    2712 
    28 LINUX=sys.platform.startswith("linux") 
    29 OPENBSD=sys.platform.startswith("openbsd") 
    30 FREEBSD=sys.platform.startswith("freebsd") 
    31 NETBSD = sys.platform.startswith("netbsd") 
    32 DARWIN=sys.platform.startswith("darwin") 
    33 BIG_ENDIAN= struct.pack("H",1) == "\x00\x01" 
    34 X86_64 = (os.uname()[4] == 'x86_64') 
    35 SOLARIS=sys.platform.startswith("sunos") 
     13# From bits/ioctls.h 
     14SIOCGIFHWADDR  = 0x8927          # Get hardware address     
     15SIOCGIFADDR    = 0x8915          # get PA address           
     16SIOCGIFNETMASK = 0x891b          # get network PA mask      
     17SIOCGIFNAME    = 0x8910          # get iface name           
     18SIOCSIFLINK    = 0x8911          # set iface channel        
     19SIOCGIFCONF    = 0x8912          # get iface list           
     20SIOCGIFFLAGS   = 0x8913          # get flags                
     21SIOCSIFFLAGS   = 0x8914          # set flags                
     22SIOCGIFINDEX   = 0x8933          # name -> if_index mapping 
     23SIOCGIFCOUNT   = 0x8938          # get number of devices 
     24SIOCGSTAMP     = 0x8906          # get packet timestamp (as a timeval) 
    3625 
    37 if LINUX: 
    38     DNET=PCAP=0 
    39 else: 
    40     DNET=PCAP=1 
     26# From if.h 
     27IFF_UP = 0x1               # Interface is up. 
     28IFF_BROADCAST = 0x2        # Broadcast address valid. 
     29IFF_DEBUG = 0x4            # Turn on debugging. 
     30IFF_LOOPBACK = 0x8         # Is a loopback net. 
     31IFF_POINTOPOINT = 0x10     # Interface is point-to-point link. 
     32IFF_NOTRAILERS = 0x20      # Avoid use of trailers. 
     33IFF_RUNNING = 0x40         # Resources allocated. 
     34IFF_NOARP = 0x80           # No address resolution protocol. 
     35IFF_PROMISC = 0x100        # Receive all packets. 
    4136 
    42 if OPENBSD or FREEBSD or NETBSD or DARWIN: 
    43     LOOPBACK_NAME="lo0" 
    44 else: 
    45     LOOPBACK_NAME="lo" 
     37# From netpacket/packet.h 
     38PACKET_ADD_MEMBERSHIP  = 1 
     39PACKET_DROP_MEMBERSHIP = 2 
     40PACKET_RECV_OUTPUT     = 3 
     41PACKET_RX_RING         = 5 
     42PACKET_STATISTICS      = 6 
     43PACKET_MR_MULTICAST    = 0 
     44PACKET_MR_PROMISC      = 1 
     45PACKET_MR_ALLMULTI     = 2 
    4646 
    47      
     47# From bits/socket.h 
     48SOL_PACKET = 263 
     49# From asm/socket.h 
     50SO_ATTACH_FILTER = 26 
     51SOL_SOCKET = 1 
    4852 
    49 if PCAP: 
    50     try: 
    51         import pcap 
    52         PCAP = 1 
    53     except ImportError: 
    54         if LINUX: 
    55             log_loading.warning("did not find pcap module. Fallback to linux primitives") 
    56             PCAP = 0 
    57         else: 
    58             if __name__ == "__main__": 
    59                 log_loading.error("did not find pcap module") 
    60                 raise SystemExit 
    61             else: 
    62                 raise 
     53# From net/route.h 
     54RTF_UP = 0x0001  # Route usable 
     55RTF_REJECT = 0x0200 
    6356 
    64 if DNET: 
    65     try: 
    66         import dnet 
    67         DNET = 1 
    68     except ImportError: 
    69         if LINUX: 
    70             log_loading.warning("did not find dnet module. Fallback to linux primitives") 
    71             DNET = 0 
    72         else: 
    73             if __name__ == "__main__": 
    74                 log_loading.error("did not find dnet module") 
    75                 raise SystemExit 
    76             else: 
    77                 raise 
    7857 
    79 if not PCAP: 
    80     f = os.popen("tcpdump -V 2> /dev/null") 
     58 
     59DNET=PCAP=0 
     60LOOPBACK_NAME="lo" 
     61 
     62with os.popen("tcpdump -V 2> /dev/null") as f: 
    8163    if f.close() >> 8 == 0x7f: 
    8264        log_loading.warning("Failed to execute tcpdump. Check it is installed and in the PATH") 
     
    8466    else: 
    8567        TCPDUMP=1 
    86     del(f) 
    8768         
    8869     
    8970 
    90 try: 
    91     from Crypto.Cipher import ARC4 
    92 except ImportError: 
    93     log_loading.info("Can't find Crypto python lib. Won't be able to decrypt WEP") 
     71def get_if_raw_hwaddr(iff): 
     72    return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR)) 
     73 
     74def get_if_raw_addr(iff): 
     75    try: 
     76        return get_if(iff, SIOCGIFADDR)[20:24] 
     77    except IOError: 
     78        return "\0\0\0\0" 
    9479 
    9580 
    96 # Workarround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470 
    97 try: 
    98     socket.inet_aton("255.255.255.255") 
    99 except socket.error: 
    100     def inet_aton(x): 
    101         if x == "255.255.255.255": 
    102             return "\xff"*4 
    103         else: 
    104             return socket.inet_aton(x) 
    105 else: 
    106     inet_aton = socket.inet_aton 
     81def get_if_list(): 
     82    f=open("/proc/net/dev","r") 
     83    lst = [] 
     84    f.readline() 
     85    f.readline() 
     86    for l in f: 
     87        lst.append(l.split(":")[0].strip()) 
     88    return lst 
     89def get_working_if(): 
     90    for i in get_if_list(): 
     91        if i == LOOPBACK_NAME:                 
     92            continue 
     93        ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0] 
     94        if ifflags & IFF_UP: 
     95            return i 
     96    return LOOPBACK_NAME 
     97def attach_filter(s, filter): 
     98    # XXX We generate the filter on the interface conf.iface  
     99    # because tcpdump open the "any" interface and ppp interfaces 
     100    # in cooked mode. As we use them in raw mode, the filter will not 
     101    # work... one solution could be to use "any" interface and translate 
     102    # the filter from cooked mode to raw mode 
     103    # mode 
     104    if not TCPDUMP: 
     105        return 
     106    try: 
     107        f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (config.conf.prog.tcpdump,config.conf.iface,filter)) 
     108    except OSError,msg: 
     109        log_interactive.warning("Failed to execute tcpdump: (%s)") 
     110        return 
     111    lines = f.readlines() 
     112    if f.close(): 
     113        raise Scapy_Exception("Filter parse error") 
     114    nb = int(lines[0]) 
     115    bpf = "" 
     116    for l in lines[1:]: 
     117        bpf += struct.pack("HBBI",*map(long,l.split())) 
    107118 
    108 inet_ntoa = socket.inet_ntoa 
    109 try: 
    110     inet_ntop = socket.inet_ntop 
    111     inet_pton = socket.inet_pton 
    112 except AttributeError: 
    113     log_loading.info("inet_ntop/pton functions not found. Python IPv6 support not present") 
     119    # XXX. Argl! We need to give the kernel a pointer on the BPF, 
     120    # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch. 
     121    if X86_64: 
     122        bpfh = struct.pack("HL", nb, id(bpf)+36) 
     123    else: 
     124        bpfh = struct.pack("HI", nb, id(bpf)+20)   
     125    s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh) 
    114126 
    115  
    116 if SOLARIS: 
    117     # GRE is missing on Solaris 
    118     socket.IPPROTO_GRE = 47 
     127def set_promisc(s,iff,val=1): 
     128    mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "") 
     129    if val: 
     130        cmd = PACKET_ADD_MEMBERSHIP 
     131    else: 
     132        cmd = PACKET_DROP_MEMBERSHIP 
     133    s.setsockopt(SOL_PACKET, cmd, mreq) 
    119134 
    120135 
    121136 
    122 def str2mac(s): 
    123     return ("%02x:"*6)[:-1] % tuple(map(ord, s))  
     137def read_routes(): 
     138    f=open("/proc/net/route","r") 
     139    routes = [] 
     140    s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
     141    ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",LOOPBACK_NAME)) 
     142    addrfamily = struct.unpack("h",ifreq[16:18])[0] 
     143    if addrfamily == socket.AF_INET: 
     144        ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x",LOOPBACK_NAME)) 
     145        msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0]) 
     146        dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk 
     147        ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) 
     148        routes.append((dst, msk, "0.0.0.0", LOOPBACK_NAME, ifaddr)) 
     149    else: 
     150        warning("Interface lo: unkown address family (%i)"% addrfamily) 
     151 
     152    for l in f.readlines()[1:]: 
     153        iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split() 
     154        flags = int(flags,16) 
     155        if flags & RTF_UP == 0: 
     156            continue 
     157        if flags & RTF_REJECT: 
     158            continue 
     159        try: 
     160            ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff)) 
     161        except IOError: # interface is present in routing tables but does not have any assigned IP 
     162            ifaddr="0.0.0.0" 
     163        else: 
     164            addrfamily = struct.unpack("h",ifreq[16:18])[0] 
     165            if addrfamily == socket.AF_INET: 
     166                ifaddr = scapy.utils.inet_ntoa(ifreq[20:24]) 
     167            else: 
     168                warning("Interface %s: unkown address family (%i)"%(iff, addrfamily)) 
     169                continue 
     170        routes.append((socket.htonl(long(dst,16))&0xffffffffL, 
     171                       socket.htonl(long(msk,16))&0xffffffffL, 
     172                       scapy.utils.inet_ntoa(struct.pack("I",long(gw,16))), 
     173                       iff, ifaddr)) 
     174     
     175    f.close() 
     176    return routes 
     177 
     178def get_if(iff,cmd): 
     179    s=socket.socket() 
     180    ifreq = ioctl(s, cmd, struct.pack("16s16x",iff)) 
     181    s.close() 
     182    return ifreq 
    124183 
    125184 
    126 ###################### 
    127 ## Interfaces stuff ## 
    128 ###################### 
     185def get_if_index(iff): 
     186    return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0]) 
    129187 
    130  
    131 if DNET: 
    132     def get_if_raw_hwaddr(iff): 
    133         if iff[:2] == LOOPBACK_NAME: 
    134             return (772, '\x00'*6) 
    135         try: 
    136             l = dnet.intf().get(iff) 
    137             l = l["link_addr"] 
    138         except: 
    139             raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff) 
    140         return l.type,l.data 
    141     def get_if_raw_addr(ifname): 
    142         i = dnet.intf() 
    143         return i.get(ifname)["addr"].data 
    144 else: 
    145     def get_if_raw_hwaddr(iff): 
    146         return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR)) 
    147  
    148     def get_if_raw_addr(iff): 
    149         try: 
    150             return get_if(iff, SIOCGIFADDR)[20:24] 
    151         except IOError: 
    152             return "\0\0\0\0" 
    153  
    154  
    155 if PCAP: 
    156     def get_if_list(): 
    157         # remove 'any' interface 
    158         return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs())) 
    159     def get_working_if(): 
    160         try: 
    161             return pcap.lookupdev() 
    162         except Exception: 
    163             return LOOPBACK_NAME 
    164  
    165     def attach_filter(s, filter): 
    166         warning("attach_filter() should not be called in PCAP mode") 
    167     def set_promisc(s,iff,val=1): 
    168         warning("set_promisc() should not be called in DNET/PCAP mode") 
    169      
    170 else: 
    171     def get_if_list(): 
    172         f=open("/proc/net/dev","r") 
    173         lst = [] 
    174         f.readline() 
    175         f.readline() 
    176         for l in f: 
    177             lst.append(l.split(":")[0].strip()) 
    178         return lst 
    179     def get_working_if(): 
    180         for i in get_if_list(): 
    181             if i == LOOPBACK_NAME:                 
    182                 continue 
    183             ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0] 
    184             if ifflags & IFF_UP: 
    185                 return i 
    186         return LOOPBACK_NAME 
    187     def attach_filter(s, filter): 
    188         # XXX We generate the filter on the interface conf.iface  
    189         # because tcpdump open the "any" interface and ppp interfaces 
    190         # in cooked mode. As we use them in raw mode, the filter will not 
    191         # work... one solution could be to use "any" interface and translate 
    192         # the filter from cooked mode to raw mode 
    193         # mode 
    194         if not TCPDUMP: 
    195             return 
    196         try: 
    197             f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (config.conf.prog.tcpdump,config.conf.iface,filter)) 
    198         except OSError,msg: 
    199             log_interactive.warning("Failed to execute tcpdump: (%s)") 
    200             return 
    201         lines = f.readlines() 
    202         if f.close(): 
    203             raise Scapy_Exception("Filter parse error") 
    204         nb = int(lines[0]) 
    205         bpf = "" 
    206         for l in lines[1:]: 
    207             bpf += struct.pack("HBBI",*map(long,l.split())) 
    208      
    209         # XXX. Argl! We need to give the kernel a pointer on the BPF, 
    210         # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch. 
    211         if X86_64: 
    212             bpfh = struct.pack("HL", nb, id(bpf)+36) 
    213         else: 
    214             bpfh = struct.pack("HI", nb, id(bpf)+20)   
    215         s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh) 
    216  
    217     def set_promisc(s,iff,val=1): 
    218         mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "") 
    219         if val: 
    220             cmd = PACKET_ADD_MEMBERSHIP 
    221         else: 
    222             cmd = PACKET_DROP_MEMBERSHIP 
    223         s.setsockopt(SOL_PACKET, cmd, mreq) 
     188def get_last_packet_timestamp(sock): 
     189    ts = ioctl(sock, SIOCGSTAMP, "12345678") 
     190    s,us = struct.unpack("II",ts) 
     191    return s+us/1000000.0 
    224192 
    225193 
    226194 
    227 ################## 
    228 ## Routes stuff ## 
    229 ################## 
    230195 
    231 if not LINUX: 
    232  
    233     def new_read_routes(): 
    234  
    235         rtlst = [] 
    236         def addrt(rt,lst): 
    237             dst,gw = rt 
    238             lst.append(rt) 
    239  
    240         r = dnet.route() 
    241         print r.loop(addrt, rtlst) 
    242         return rtlst 
    243  
    244     def read_routes(): 
    245         if SOLARIS: 
    246             f=os.popen("netstat -rvn") # -f inet 
    247         elif FREEBSD: 
    248             f=os.popen("netstat -rnW") # -W to handle long interface names 
    249         else: 
    250             f=os.popen("netstat -rn") # -f inet 
    251         ok = 0 
    252         mtu_present = False 
    253         routes = [] 
    254         for l in f.readlines(): 
    255             if not l: 
    256                 break 
    257             l = l.strip() 
    258             if l.find("----") >= 0: # a separation line 
    259                 continue 
    260             if l.find("Destination") >= 0: 
    261                 ok = 1 
    262                 if l.find("Mtu") >= 0: 
    263                     mtu_present = True 
    264                 continue 
    265             if ok == 0: 
    266                 continue 
    267             if not l: 
    268                 break 
    269             if SOLARIS: 
    270                 dest,mask,gw,netif,mxfrg,rtt,ref,flg = l.split()[:8] 
    271             else: 
    272                 if mtu_present: 
    273                     dest,gw,flg,ref,use,mtu,netif = l.split()[:7] 
    274                 else: 
    275                     dest,gw,flg,ref,use,netif = l.split()[:6] 
    276             if flg.find("Lc") >= 0: 
    277                 continue                 
    278             if dest == "default": 
    279                 dest = 0L 
    280                 netmask = 0L 
    281             else: 
    282                 if SOLARIS: 
    283                     netmask = atol(mask) 
    284                 elif "/" in dest: 
    285                     dest,netmask = dest.split("/") 
    286                     netmask = itom(int(netmask)) 
    287                 else: 
    288                     netmask = itom((dest.count(".") + 1) * 8) 
    289                 dest += ".0"*(3-dest.count(".")) 
    290                 dest = atol(dest) 
    291             if not "G" in flg: 
    292                 gw = '0.0.0.0' 
    293             ifaddr = get_if_addr(netif) 
    294             routes.append((dest,netmask,gw,netif,ifaddr)) 
    295         f.close() 
    296         return routes 
    297  
    298     def read_interfaces(): 
    299         i = dnet.intf() 
    300         ifflist = {} 
    301         def addif(iff,lst): 
    302             if not iff.has_key("addr"): 
    303                 return 
    304             if not iff.has_key("link_addr"): 
    305                 return 
    306             rawip = iff["addr"].data 
    307             ip = inet_ntoa(rawip) 
    308             rawll = iff["link_addr"].data 
    309             ll = str2mac(rawll) 
    310             lst[iff["name"]] = (rawll,ll,rawip,ip) 
    311         i.loop(addif, ifflist) 
    312         return ifflist 
    313  
    314              
    315 else: 
    316  
    317     def read_routes(): 
    318         f=open("/proc/net/route","r") 
    319         routes = [] 
    320         s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    321         ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",LOOPBACK_NAME)) 
    322         addrfamily = struct.unpack("h",ifreq[16:18])[0] 
    323         if addrfamily == socket.AF_INET: 
    324             ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x",LOOPBACK_NAME)) 
    325             msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0]) 
    326             dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk 
    327             ifaddr = inet_ntoa(ifreq[20:24]) 
    328             routes.append((dst, msk, "0.0.0.0", LOOPBACK_NAME, ifaddr)) 
    329         else: 
    330             warning("Interface lo: unkown address family (%i)"% addrfamily) 
    331      
    332         for l in f.readlines()[1:]: 
    333             iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split() 
    334             flags = int(flags,16) 
    335             if flags & RTF_UP == 0: 
    336                 continue 
    337             if flags & RTF_REJECT: 
    338                 continue 
    339             try: 
    340                 ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff)) 
    341             except IOError: # interface is present in routing tables but does not have any assigned IP 
    342                 ifaddr="0.0.0.0" 
    343             else: 
    344                 addrfamily = struct.unpack("h",ifreq[16:18])[0] 
    345                 if addrfamily == socket.AF_INET: 
    346                     ifaddr = inet_ntoa(ifreq[20:24]) 
    347                 else: 
    348                     warning("Interface %s: unkown address family (%i)"%(iff, addrfamily)) 
    349                     continue 
    350             routes.append((socket.htonl(long(dst,16))&0xffffffffL, 
    351                            socket.htonl(long(msk,16))&0xffffffffL, 
    352                            inet_ntoa(struct.pack("I",long(gw,16))), 
    353                            iff, ifaddr)) 
    354          
    355         f.close() 
    356         return routes 
    357  
    358     def get_if(iff,cmd): 
    359         s=socket.socket() 
    360         ifreq = ioctl(s, cmd, struct.pack("16s16x",iff)) 
    361         s.close() 
    362         return ifreq 
    363  
    364  
    365     def get_if_index(iff): 
    366         return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0]) 
    367  
    368     def get_last_packet_timestamp(sock): 
    369         ts = ioctl(sock, SIOCGSTAMP, "12345678") 
    370         s,us = struct.unpack("II",ts) 
    371         return s+us/1000000.0 
    372  
    373      
    374 def get_if_addr(iff): 
    375     return inet_ntoa(get_if_raw_addr(iff)) 
    376      
    377 def get_if_hwaddr(iff): 
    378     addrfamily, mac = get_if_raw_hwaddr(iff) 
    379     if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]: 
    380         return str2mac(mac) 
    381     else: 
    382         raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily,iff)) 
    383  
    384  
    385  
  • scapy/arch/unix.py

    r862 r884  
    77import sys,os,struct,socket,time 
    88from fcntl import ioctl 
    9 from data import * 
     9import scapy.utils 
     10import scapy.arch 
    1011 
    11 import config 
     12DNET=PCAP=1 
     13 
    1214 
    1315try: 
    14     import Gnuplot 
    15     GNUPLOT=
     16    import pcap 
     17    PCAP =
    1618except ImportError: 
    17     log_loading.info("did not find python gnuplot wrapper . Won't be able to plot") 
    18     GNUPLOT=0 
     19    if __name__ == "__main__": 
     20        log_loading.error("did not find pcap module") 
     21        raise SystemExit 
     22    else: 
     23        raise 
    1924 
    2025try: 
    21     import pyx 
    22     PYX=
     26    import dnet 
     27    DNET =
    2328except ImportError: 
    24     log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump()") 
    25     PYX=0 
     29    if __name__ == "__main__": 
     30        log_loading.error("did not find dnet module") 
     31        raise SystemExit 
     32    else: 
     33        raise 
    2634 
    2735 
    28 LINUX=sys.platform.startswith("linux") 
    29 OPENBSD=sys.platform.startswith("openbsd") 
    30 FREEBSD=sys.platform.startswith("freebsd") 
    31 NETBSD = sys.platform.startswith("netbsd") 
    32 DARWIN=sys.platform.startswith("darwin") 
    33 BIG_ENDIAN= struct.pack("H",1) == "\x00\x01" 
    34 X86_64 = (os.uname()[4] == 'x86_64') 
    35 SOLARIS=sys.platform.startswith("sunos") 
     36def get_if_raw_hwaddr(iff): 
     37    if iff[:2] == scapy.arch.LOOPBACK_NAME: 
     38        return (772, '\x00'*6) 
     39    try: 
     40        l = dnet.intf().get(iff) 
     41        l = l["link_addr"] 
     42    except: 
     43        raise Scapy_Exception("Error in attempting to get hw address for interface [%s]" % iff) 
     44    return l.type,l.data 
     45def get_if_raw_addr(ifname): 
     46    i = dnet.intf() 
     47    return i.get(ifname)["addr"].data 
    3648 
    37 if LINUX: 
    38     DNET=PCAP=0 
    39 else: 
    40     DNET=PCAP=1 
     49def get_if_list(): 
     50    # remove 'any' interface 
     51    return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs())) 
     52def get_working_if(): 
     53    try: 
     54        return pcap.lookupdev() 
     55    except Exception: 
     56        return scapy.arch.LOOPBACK_NAME 
    4157 
    42 if OPENBSD or FREEBSD or NETBSD or DARWIN: 
    43     LOOPBACK_NAME="lo0" 
    44 else: 
    45     LOOPBACK_NAME="lo" 
    46  
     58def attach_filter(s, filter): 
     59    warning("attach_filter() should not be called in PCAP mode") 
     60def set_promisc(s,iff,val=1): 
     61    warning("set_promisc() should not be called in DNET/PCAP mode") 
    4762     
    48  
    49 if PCAP: 
    50     try: 
    51         import pcap 
    52         PCAP = 1 
    53     except ImportError: 
    54         if LINUX: 
    55             log_loading.warning("did not find pcap module. Fallback to linux primitives") 
    56             PCAP = 0 
    57         else: 
    58             if __name__ == "__main__": 
    59                 log_loading.error("did not find pcap module") 
    60                 raise SystemExit 
    61             else: 
    62                 raise 
    63