Changeset 919:8811cea5c4f8

Show
Ignore:
Timestamp:
09/12/08 17:57:20 (4 months ago)
Author:
Phil <phil@secdev.org>
Message:

Split inet6

Files:

Legend:

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

    r903 r919  
    7575    scapy.config.conf.iface = LOOPBACK_NAME 
    7676 
     77 
     78def get_if_raw_addr6(iff): 
     79    """ 
     80    Returns the main global unicast address associated with provided  
     81    interface, in network format. If no global address is found, None  
     82    is returned.  
     83    """ 
     84    r = filter(lambda x: x[2] == iff and x[1] == IPV6_ADDR_GLOBAL, in6_getifaddr()) 
     85    if len(r) == 0: 
     86        return None 
     87    else: 
     88        r = r[0][0]  
     89    return inet_pton(socket.AF_INET6, r) 
  • scapy/arch/linux.py

    r903 r919  
    180180    f.close() 
    181181    return routes 
     182 
     183############ 
     184### IPv6 ### 
     185############ 
     186 
     187def in6_getifaddr(): 
     188    """ 
     189    Returns a list of 3-tuples of the form (addr, scope, iface) where 
     190    'addr' is the address of scope 'scope' associated to the interface 
     191    'ifcace'. 
     192 
     193    This is the list of all addresses of all interfaces available on 
     194    the system. 
     195    """ 
     196    ret = [] 
     197    try: 
     198        f = open("/proc/net/if_inet6","r") 
     199    except IOError, err:     
     200        return ret 
     201    l = f.readlines() 
     202    for i in l: 
     203        # addr, index, plen, scope, flags, ifname 
     204        tmp = i.split() 
     205        addr = struct.unpack('4s4s4s4s4s4s4s4s', tmp[0]) 
     206        addr = in6_ptop(':'.join(addr)) 
     207        ret.append((addr, int(tmp[3], 16), tmp[5])) # (addr, scope, iface) 
     208    return ret 
     209 
     210def read_routes6(): 
     211    try: 
     212        f = open("/proc/net/ipv6_route","r") 
     213    except IOError, err: 
     214        return [] 
     215    # 1. destination network 
     216    # 2. destination prefix length 
     217    # 3. source network displayed 
     218    # 4. source prefix length 
     219    # 5. next hop 
     220    # 6. metric 
     221    # 7. reference counter (?!?) 
     222    # 8. use counter (?!?) 
     223    # 9. flags 
     224    # 10. device name 
     225    routes = [] 
     226    def proc2r(p): 
     227        ret = struct.unpack('4s4s4s4s4s4s4s4s', p) 
     228        ret = ':'.join(ret) 
     229        return in6_ptop(ret) 
     230     
     231    lifaddr = in6_getifaddr()  
     232    for l in f.readlines(): 
     233        d,dp,s,sp,nh,m,rc,us,fl,dev = l.split() 
     234        fl = int(fl, 16) 
     235 
     236        if fl & RTF_UP == 0: 
     237            continue 
     238        if fl & RTF_REJECT: 
     239            continue 
     240 
     241        d = proc2r(d) ; dp = int(dp, 16) 
     242        s = proc2r(s) ; sp = int(sp, 16) 
     243        nh = proc2r(nh) 
     244 
     245        cset = [] # candidate set (possible source addresses) 
     246        if dev == LOOPBACK_NAME: 
     247            if d == '::': 
     248                continue 
     249            cset = ['::1'] 
     250        else: 
     251            devaddrs = filter(lambda x: x[2] == dev, lifaddr) 
     252            cset = construct_source_candidate_set(d, dp, devaddrs) 
     253         
     254        if len(cset) != 0: 
     255            routes.append((d, dp, nh, dev, cset)) 
     256    f.close() 
     257    return routes    
     258 
     259 
     260 
    182261 
    183262def get_if(iff,cmd): 
  • scapy/arch/unix.py

    r906 r919  
    106106    return routes 
    107107 
     108############ 
     109### IPv6 ### 
     110############ 
     111 
     112def in6_getifaddr(): 
     113    """ 
     114    Returns a list of 3-tuples of the form (addr, scope, iface) where 
     115    'addr' is the address of scope 'scope' associated to the interface 
     116    'ifcace'. 
     117 
     118    This is the list of all addresses of all interfaces available on 
     119    the system. 
     120    """ 
     121 
     122    ret = [] 
     123    i = dnet.intf() 
     124    for int in i: 
     125        ifname = int['name'] 
     126        v6 = [] 
     127        if int.has_key('alias_addrs'): 
     128            v6 = int['alias_addrs'] 
     129        for a in v6: 
     130            if a.type != dnet.ADDR_TYPE_IP6: 
     131                continue 
     132 
     133            xx = str(a).split('/')[0] 
     134            addr = in6_ptop(xx) 
     135 
     136            scope = in6_getscope(addr) 
     137 
     138            ret.append((xx, scope, ifname)) 
     139    return ret 
     140 
     141def read_routes6(): 
     142    f = os.popen("netstat -rn -f inet6") 
     143    ok = -1 
     144    routes = [] 
     145    lifaddr = in6_getifaddr() 
     146    for l in f.readlines(): 
     147        if not l: 
     148            break 
     149        l = l.strip() 
     150        if ok < 0: 
     151            ok = l.find('Destination') 
     152            continue 
     153        # gv 12/12/06: under debugging       
     154        if NETBSD or OPENBSD: 
     155            d,nh,fl,_,_,_,dev = l.split()[:7] 
     156        else:       # FREEBSD or DARWIN  
     157            d,nh,fl,dev = l.split()[:4] 
     158        if filter(lambda x: x[2] == dev, lifaddr) == []: 
     159            continue 
     160        if 'L' in fl: # drop MAC addresses 
     161            continue 
     162 
     163        if 'link' in nh: 
     164            nh = '::' 
     165 
     166        cset = [] # candidate set (possible source addresses) 
     167        dp = 128 
     168        if d == 'default': 
     169            d = '::' 
     170            dp = 0 
     171        if '/' in d: 
     172            d,dp = d.split("/") 
     173            dp = int(dp) 
     174        if '%' in d: 
     175            d,dev = d.split('%') 
     176        if '%' in nh: 
     177            nh,dev = nh.split('%') 
     178        if scapy.arch.LOOPBACK_NAME in dev: 
     179            cset = ['::1'] 
     180            nh = '::' 
     181        else: 
     182            devaddrs = filter(lambda x: x[2] == dev, lifaddr) 
     183            cset = construct_source_candidate_set(d, dp, devaddrs) 
     184 
     185        if len(cset) != 0: 
     186            routes.append((d, dp, nh, dev, cset)) 
     187 
     188    f.close() 
     189    return routes 
     190 
    108191 
    109192             
  • scapy/data.py

    r884 r919  
    1818ETH_P_IP = 0x800 
    1919ETH_P_ARP = 0x806 
     20ETH_P_IPV6 = 0x86dd 
    2021 
    2122# From net/if_arp.h 
     
    2526ARPHDR_LOOPBACK = 772 
    2627ARPHDR_TUN = 65534 
     28 
     29 
     30# From net/ipv6.h on Linux (+ Additions) 
     31IPV6_ADDR_UNICAST     = 0x01 
     32IPV6_ADDR_MULTICAST   = 0x02 
     33IPV6_ADDR_CAST_MASK   = 0x0F 
     34IPV6_ADDR_LOOPBACK    = 0x10 
     35IPV6_ADDR_GLOBAL      = 0x00 
     36IPV6_ADDR_LINKLOCAL   = 0x20 
     37IPV6_ADDR_SITELOCAL   = 0x40     # deprecated since Sept. 2004 by RFC 3879 
     38IPV6_ADDR_SCOPE_MASK  = 0xF0 
     39#IPV6_ADDR_COMPATv4   = 0x80     # deprecated; i.e. ::/96 
     40#IPV6_ADDR_MAPPED     = 0x1000   # i.e.; ::ffff:0.0.0.0/96 
     41IPV6_ADDR_6TO4        = 0x0100   # Added to have more specific info (should be 0x0101 ?) 
     42IPV6_ADDR_UNSPECIFIED = 0x10000 
    2743 
    2844 
  • scapy/layers/inet6.py

    r918 r919  
    4141    return globals().get(name, fallback_cls) 
    4242 
    43  
    44 ############################################################################# 
    45 ## Constants                                                               ## 
    46 ############################################################################# 
    47  
    48 ETH_P_IPV6 = 0x86dd 
    49 OPENBSD=sys.platform.startswith("openbsd") 
    50 FREEBSD=sys.platform.startswith("freebsd") 
    51 NETBSD = sys.platform.startswith("netbsd") 
    52 DARWIN=sys.platform.startswith("darwin") 
    53 WINDOWS = sys.platform.startswith("win") 
    54  
    55  
    56 # From net/ipv6.h on Linux (+ Additions) 
    57 IPV6_ADDR_UNICAST     = 0x01 
    58 IPV6_ADDR_MULTICAST   = 0x02 
    59 IPV6_ADDR_CAST_MASK   = 0x0F 
    60 IPV6_ADDR_LOOPBACK    = 0x10 
    61 IPV6_ADDR_GLOBAL      = 0x00 
    62 IPV6_ADDR_LINKLOCAL   = 0x20 
    63 IPV6_ADDR_SITELOCAL   = 0x40     # deprecated since Sept. 2004 by RFC 3879 
    64 IPV6_ADDR_SCOPE_MASK  = 0xF0 
    65 #IPV6_ADDR_COMPATv4   = 0x80     # deprecated; i.e. ::/96 
    66 #IPV6_ADDR_MAPPED     = 0x1000   # i.e.; ::ffff:0.0.0.0/96 
    67 IPV6_ADDR_6TO4        = 0x0100   # Added to have more specific info (should be 0x0101 ?) 
    68 IPV6_ADDR_UNSPECIFIED = 0x10000 
    6943 
    7044 
     
    374348        return res[0][1] 
    375349 
    376 def get_if_raw_addr6(iff): 
    377     """ 
    378     Returns the main global unicast address associated with provided  
    379     interface, in network format. If no global address is found, None  
    380     is returned.  
    381     """ 
    382     r = filter(lambda x: x[2] == iff and x[1] == IPV6_ADDR_GLOBAL, in6_getifaddr()) 
    383     if len(r) == 0: 
    384         return None 
    385     else: 
    386         r = r[0][0]  
    387     return inet_pton(socket.AF_INET6, r) 
    388  
    389 if LINUX: 
    390  
    391     def in6_getifaddr(): 
    392         """ 
    393         Returns a list of 3-tuples of the form (addr, scope, iface) where 
    394         'addr' is the address of scope 'scope' associated to the interface 
    395         'ifcace'. 
    396  
    397         This is the list of all addresses of all interfaces available on 
    398         the system. 
    399         """ 
    400         ret = [] 
    401         try: 
    402             f = open("/proc/net/if_inet6","r") 
    403         except IOError, err:     
    404             return ret 
    405         l = f.readlines() 
    406         for i in l: 
    407             # addr, index, plen, scope, flags, ifname 
    408             tmp = i.split() 
    409             addr = struct.unpack('4s4s4s4s4s4s4s4s', tmp[0]) 
    410             addr = in6_ptop(':'.join(addr)) 
    411             ret.append((addr, int(tmp[3], 16), tmp[5])) # (addr, scope, iface) 
    412         return ret 
    413  
    414     def read_routes6(): 
    415         try: 
    416             f = open("/proc/net/ipv6_route","r") 
    417         except IOError, err: 
    418             return [] 
    419         # 1. destination network 
    420         # 2. destination prefix length 
    421         # 3. source network displayed 
    422         # 4. source prefix length 
    423         # 5. next hop 
    424         # 6. metric 
    425         # 7. reference counter (?!?) 
    426         # 8. use counter (?!?) 
    427         # 9. flags 
    428         # 10. device name 
    429         routes = [] 
    430         def proc2r(p): 
    431             ret = struct.unpack('4s4s4s4s4s4s4s4s', p) 
    432             ret = ':'.join(ret) 
    433             return in6_ptop(ret) 
    434          
    435         lifaddr = in6_getifaddr()  
    436         for l in f.readlines(): 
    437             d,dp,s,sp,nh,m,rc,us,fl,dev = l.split() 
    438             fl = int(fl, 16) 
    439  
    440             if fl & RTF_UP == 0: 
    441                 continue 
    442             if fl & RTF_REJECT: 
    443                 continue 
    444  
    445             d = proc2r(d) ; dp = int(dp, 16) 
    446             s = proc2r(s) ; sp = int(sp, 16) 
    447             nh = proc2r(nh) 
    448  
    449             cset = [] # candidate set (possible source addresses) 
    450             if dev == LOOPBACK_NAME: 
    451                 if d == '::': 
    452                     continue 
    453                 cset = ['::1'] 
    454             else: 
    455                 devaddrs = filter(lambda x: x[2] == dev, lifaddr) 
    456                 cset = construct_source_candidate_set(d, dp, devaddrs) 
    457              
    458             if len(cset) != 0: 
    459                 routes.append((d, dp, nh, dev, cset)) 
    460         f.close() 
    461         return routes    
    462  
    463 elif WINDOWS: 
    464     def in6_getifaddr(): 
    465         """ 
    466         Returns a list of 3-tuples of the form (addr, scope, iface) where 
    467         'addr' is the address of scope 'scope' associated to the interface 
    468         'ifcace'. 
    469  
    470         This is the list of all addresses of all interfaces available on 
    471         the system. 
    472         """ 
    473         ret = [] 
    474         # Just some dummy values for now 
    475         xx = "::1" 
    476         scope = 128 
    477         ifname = LOOPBACK_NAME 
    478         ret.append(xx, scope, ifname) 
    479         return ret 
    480  
    481     def read_routes6(): 
    482         routes = [] 
    483         # Just some dummy values for now 
    484         d = '::' 
    485         dp = 0 
    486         nh = '::' 
    487         dev = LOOPBACK_NAME 
    488         cset = ['::1'] 
    489         routes.append((d, dp, nh, dev, cset)) 
    490         return routes 
    491  
    492 else: 
    493     def in6_getifaddr(): 
    494         """ 
    495         Returns a list of 3-tuples of the form (addr, scope, iface) where 
    496         'addr' is the address of scope 'scope' associated to the interface 
    497         'ifcace'. 
    498  
    499         This is the list of all addresses of all interfaces available on 
    500         the system. 
    501         """ 
    502  
    503         ret = [] 
    504         i = dnet.intf() 
    505         for int in i: 
    506             ifname = int['name'] 
    507             v6 = [] 
    508             if int.has_key('alias_addrs'): 
    509                 v6 = int['alias_addrs'] 
    510             for a in v6: 
    511                 if a.type != dnet.ADDR_TYPE_IP6: 
    512                     continue 
    513  
    514                 xx = str(a).split('/')[0] 
    515                 addr = in6_ptop(xx) 
    516  
    517                 scope = in6_getscope(addr) 
    518  
    519                 ret.append((xx, scope, ifname)) 
    520         return ret 
    521  
    522     def read_routes6(): 
    523         f = os.popen("netstat -rn -f inet6") 
    524         ok = -1 
    525         routes = [] 
    526         lifaddr = in6_getifaddr() 
    527         for l in f.readlines(): 
    528             if not l: 
    529                 break 
    530             l = l.strip() 
    531             if ok < 0: 
    532                 ok = l.find('Destination') 
    533                 continue 
    534             # gv 12/12/06: under debugging       
    535             if NETBSD or OPENBSD: 
    536                 d,nh,fl,_,_,_,dev = l.split()[:7] 
    537             else:       # FREEBSD or DARWIN  
    538                 d,nh,fl,dev = l.split()[:4] 
    539             if filter(lambda x: x[2] == dev, lifaddr) == []: 
    540                 continue 
    541             if 'L' in fl: # drop MAC addresses 
    542                 continue 
    543  
    544             if 'link' in nh: 
    545                 nh = '::' 
    546  
    547             cset = [] # candidate set (possible source addresses) 
    548             dp = 128 
    549             if d == 'default': 
    550                 d = '::' 
    551                 dp = 0 
    552             if '/' in d: 
    553                 d,dp = d.split("/") 
    554                 dp = int(dp) 
    555             if '%' in d: 
    556                 d,dev = d.split('%') 
    557             if '%' in nh: 
    558                 nh,dev = nh.split('%') 
    559             if LOOPBACK_NAME in dev: 
    560                 cset = ['::1'] 
    561                 nh = '::' 
    562             else: 
    563                 devaddrs = filter(lambda x: x[2] == dev, lifaddr) 
    564                 cset = construct_source_candidate_set(d, dp, devaddrs) 
    565  
    566             if len(cset) != 0: 
    567                 routes.append((d, dp, nh, dev, cset)) 
    568  
    569         f.close() 
    570         return routes 
    571350 
    572351