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