PERFORCE change 99971 for review

Clément Lecigne clem1 at FreeBSD.org
Sun Jun 25 07:55:58 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=99971

Change 99971 by clem1 at clem1_ipv6vulns on 2006/06/25 07:55:15

	pcs improvements:
		- almost icmp6 full support.
		- new samples (mld6query, nb-sk)	

Affected files ...

.. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/ethernet.py#2 edit
.. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/icmpv6.py#3 edit
.. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/ipv6.py#2 edit
.. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/pcs.py#3 edit
.. //depot/projects/soc2006/clem1_ipv6vulns/pcs/samples/mld6query.py#1 add
.. //depot/projects/soc2006/clem1_ipv6vulns/pcs/samples/nb-sk.py#1 add

Differences ...

==== //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/ethernet.py#2 (text+ko) ====

@@ -1,5 +1,6 @@
 import pcs
 import struct
+import os
 import ipv4
 import ipv6
 
@@ -19,7 +20,7 @@
         type = pcs.Field("type", 16)
         etherlen = 14
 
-        pcs.Packet.__init__(self, [src, dst, type], bytes = bytes)
+        pcs.Packet.__init__(self, [dst, src, type], bytes = bytes)
         
         if (bytes != None):
             self.data = self.next(bytes[etherlen:len(bytes)])
@@ -50,3 +51,19 @@
             return ipv6.ipv6(bytes)
         return None
 
+    def name2eth(self, mac):
+        """return big endian representation of the human readable mac"""
+        addr = ""
+        for i in 0, 3, 6, 9, 12, 15:
+            addr += "%c" % int(mac[i:i+2], 16)
+        return addr
+
+    def getmac(self, iface):
+        """return mac address associated to interface iface."""
+        mac = ""
+        # XXX: use ioctl() instead.
+        for line in os.popen("/sbin/ifconfig %s" % iface):
+            if line.find('ether') > -1:
+                mac = line.split()[1]
+                break
+        return mac

==== //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/icmpv6.py#3 (text+ko) ====

@@ -38,12 +38,22 @@
 import struct
 from pseudoipv6 import *
 
+# icmp6 type
 ND_ROUTER_SOLICIT = 133
 ND_ROUTER_ADVERT = 134	
 ND_NEIGHBOR_SOLICIT = 135	
 ND_NEIGHBOR_ADVERT = 136	
 ND_REDIRECT = 137
-ICMP6_ROUTER_RENUMBERING = 138	
+
+MLD6_LISTENER_QUERY = 130
+MLD6_LISTENER_REPORT = 131
+MLD6_LISTENER_DONE = 132
+MLD6_MTRACE_RESP = 200
+MLD6_MTRACE = 201
+
+ICMP6_ROUTER_RENUMBERING = 138
+ICMP6_NI_QUERY = 139
+ICMP6_NI_REPLY = 140
 ICMP6_WRUREQUEST = 139	
 ICMP6_WRUREPLY = 140	
 ICMP6_DST_UNREACH = 1
@@ -53,6 +63,13 @@
 ICMP6_ECHO_REQUEST = 128	
 ICMP6_ECHO_REPLY = 129
 
+# router renumbering flags
+ICMP6_RR_FLAGS_TEST	= 0x80
+ICMP6_RR_FLAGS_REQRESULT = 0x40
+ICMP6_RR_FLAGS_FORCEAPPLY = 0x20
+ICMP6_RR_FLAGS_SPECSITE	= 0x10
+ICMP6_RR_FLAGS_PREVDONE = 0x08
+
 op = 0
 
 class icmpv6(pcs.Packet):
@@ -61,6 +78,8 @@
 
     def __init__(self, type = 0, bytes = None):
         """icmpv6 header RFC2463 and RFC2461"""
+        global op 
+        op = 0
         ty = pcs.Field("type", 8, default = type)
         code = pcs.Field("code", 8)
         cksum = pcs.Field("checksum", 16)
@@ -77,7 +96,11 @@
         elif type == ICMP6_PACKET_TOO_BIG:
             mtu = pcs.Field("mtu", 32)
             pcs.Packet.__init__(self, [ty, code, cksum, mtu], bytes)
-        #elif type == ICMP6_WRUREQUEST or type == ICMP6_WRUREPLY:
+        elif type == ICMP6_NI_QUERY or type == ICMP6_NI_REPLY:
+            qtype = pcs.Field("qtype", 16)
+            flags = pcs.Field("flags", 16)
+            nonce = pcs.Field("nonce", 64)
+            pcs.Packet.__init__(self, [ty, code, cksum, qtype, flags, nonce], bytes)
         elif type == ND_ROUTER_ADVERT:
             chp = pcs.Field("current_hop_limit", 8)
             m = pcs.Field("m", 1)
@@ -86,18 +109,28 @@
             rlf = pcs.Field("router_lifetime", 16)
             rct = pcs.Field("reachable_time", 32)
             rtt = pcs.Field("retrans_timer", 32)
-            pcs.Packet.__init__(self, [ty, code, cksum, chp, m, o, unused, rlt, rct, rtt], bytes)
+            pcs.Packet.__init__(self, [ty, code, cksum, chp, m, o, unused, rlf, rct, rtt], bytes)
         elif type == ND_NEIGHBOR_SOLICIT:
             reserved = pcs.Field("reserved", 32)
-            target = pcs.Field("target", 16 * 8)
+            target = pcs.Field("target", 16 * 8, type = str)
             pcs.Packet.__init__(self, [ty, code, cksum, reserved, target], bytes)
         elif type == ND_NEIGHBOR_ADVERT:
             r = pcs.Field("router", 1)
             s = pcs.Field("solicited", 1)
             o = pcs.Field("override", 1)
             reserved = pcs.Field("reserved", 29)
-            target = pcs.Field("target", 16 * 8)
+            target = pcs.Field("target", 16 * 8, type = str)
             pcs.Packet.__init__(self, [ty, code, cksum, r, s, o, reserved, target], bytes)
+        elif type == ND_REDIRECT:
+            reserved = pcs.Field("reserved", 32)
+            target = pcs.Field("target", 16 * 8, type = str)
+            dest = pcs.Field("destination", 16 * 8, type = str)
+            pcs.Packet.__init__(self, [ty, code, cksum, reserved, target, dest], bytes)
+        elif type == MLD6_LISTENER_QUERY or type == MLD6_LISTENER_REPORT or MLD6_LISTENER_DONE:
+            md = pcs.Field("maxdelay", 16)
+            reserved = pcs.Field("reserved", 16)
+            mcast = pcs.Field("mcastaddr", 16 * 8, type = str)
+            pcs.Packet.__init__(self, [ty, code, cksum, md, reserved, mcast], bytes)            
         else:
             pcs.Packet.__init__(self, [ty, code, cksum], bytes)
 

==== //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/ipv6.py#2 (text+ko) ====

@@ -37,8 +37,15 @@
 
 import pcs
 import struct
+import os
 from socket import AF_INET6, inet_ntop
 
+# extension header next header field.
+IPV6_FRAG = 44
+IPV6_HOPOPTS = 49
+IPV6_RTHDR = 43
+IPV6_DSTOPTS = 60
+
 class ipv6(pcs.Packet):
     """A class that contains the IPv6 header.  All other data is
     chained on the end."""
@@ -69,3 +76,114 @@
             else:
                 retval += "%s %s\n" % (field.name, self.__dict__[field.name])
         return retval
+
+    def getipv6(self, iface):
+        """return one ipv6 address associated to iface"""
+        v6 = ""
+        # XXX: improve this using getifaddrs() wrapper.
+        for line in os.popen("/sbin/ifconfig %s" % iface):
+            if line.find('inet6') > -1:
+                if line.split()[1][:4] == "fe80" or line.split()[1][:4] == "fec0":
+                    continue
+                v6 = line.split()[1]
+                break
+        return v6
+
+class rthdr(pcs.Packet):
+    """A class that contains the IPv6 routing extension-headers."""
+
+    layout = pcs.Layout()
+
+    def __init__(self, bytes = None):
+        """IPv6 routing extension header from RFC 2460"""
+        next = pcs.Field("next_header", 8)
+        len = pcs.Field("length", 8)
+        type = pcs.Field("type", 8)
+        segments_left = pcs.Field("segments_left", 8)
+        pcs.Packet.__init__(self,
+                            [next, len, type, segments_left], bytes)
+
+    def rthdr0(self, seg = 1, bytes = None):
+        """IPv6 routing extension header type 0"""
+        reserved = pcs.Field("reserved", 32, default = 0)
+        header = [ reserved ]
+        for i in range(seg):
+            header.append(pcs.Field("address" + str(i), 128, type = str))
+        pcs.Packet.__add__(self, header)
+
+class hopopts(pcs.Packet):
+    """A class that contains the IPv6 hop-by-hop options 
+    extension-headers."""
+
+    layout = pcs.Layout()
+
+    op = 0
+    
+    def __init__(self, bytes = None):
+        """IPv6 hopbyhop options extension header from RFC 2460"""
+        global op
+        op = 0
+        next = pcs.Field("next_header", 8)
+        len = pcs.Field("length", 8)
+        type = pcs.Field("type", 8)
+        pcs.Packet.__init__(self,
+                            [next, len, type, segments_left], bytes)
+    
+    def option(self, len = 0):
+        """add option header to the hop-by-hop extension header"""
+        global op
+        op += 1
+        otype = pcs.Field("otype" + str(op), 8)
+        olen = pcs.Field("olength" + str(op), 8, default = len / 8)
+        if len != 0:
+            odata = pcs.Field("odata" + str(op), len)
+            pcs.Packet.__add__(self, [otype, olen, odata])
+        else:
+            pcs.Packet.__add__(self, [otype, olen])
+
+class dstopts(pcs.Packet):
+    """A class that contains the IPv6 destination options 
+    extension-headers."""
+
+    layout = pcs.Layout()
+
+    op = 0
+    
+    def __init__(self, bytes = None):
+        """IPv6 destination options extension header from RFC 2460"""
+        global op
+        op = 0
+        next = pcs.Field("next_header", 8)
+        len = pcs.Field("length", 8)
+        type = pcs.Field("type", 8)
+        pcs.Packet.__init__(self,
+                            [next, len, type, segments_left], bytes)
+
+    def option(self, len = 0):
+        """add option header to the destination extension header"""
+        global op
+        op += 1
+        otype = pcs.Field("otype" + str(op), 8)
+        olen = pcs.Field("olength" + str(op), 8, default = len / 8)
+        if len != 0:
+            odata = pcs.Field("odata" + str(op), len)
+            pcs.Packet.__add__(self, [otype, olen, odata])
+        else:
+            pcs.Packet.__add__(self, [otype, olen])
+
+class frag(pcs.Packet):
+    """A class that contains the IPv6 fragmentation extension-headers."""
+
+    layout = pcs.Layout()
+    
+    def __init__(self, bytes = None):
+        """IPv6 fragmentation extension header from RFC 2460"""
+        next = pcs.Field("next_header", 8)
+        reserved = pcs.Field("reserved", 8)
+        offset = pcs.Field("offset", 13)
+        res = pcs.Field("res", 2)
+        m = pcs.Field("m", 1)
+        identification = pcs.Field("identification", 32)
+        pcs.Packet.__init__(self,
+                            [next, reserved, offset, res, m, identification], bytes)
+

==== //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/pcs.py#3 (text+ko) ====

@@ -36,8 +36,8 @@
 # individual protocols separately.
 
 # We need the struct module to pack our class into a byte string.
-import struct
-
+import struct, re, sys
+from socket import *
 import itertools
 
 def attribreprlist(obj, attrs):
@@ -349,9 +349,7 @@
     and low level stuff like pcap and bpf, connectors will be a
     unifying mechanism so you can write packets over any of the
     available APIs and the connector will do the right thing."""
-
     def __init__(self, name, arg = ""):
-        from socket import *
         import bpf
         connectors = [ "IPV4", "IPV6", "ICMP6", "UDP6", "TCP6", "ICMP", "UDP", "TCP",  "BPF", "PCAP" ]
         self.bsd = 0
@@ -380,6 +378,14 @@
         elif name == "PCAP":
             self.sock = pcap.pcap(arg)
 
+    def mcast(self, iface):
+        import dl
+        _libc = dl.open('libc.so')
+        ifn = _libc.call('if_nametoindex', iface)
+        self.sock.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 1)
+        self.sock.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 5)
+        self.sock.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_IF, ifn)
+
     def read():
         pass
 


More information about the p4-projects mailing list