Date: Sun, 25 Jun 2006 07:55:55 GMT From: Clément Lecigne <clem1@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 99971 for review Message-ID: <200606250755.k5P7tton082448@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=99971 Change 99971 by clem1@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606250755.k5P7tton082448>