Date: Sat, 17 Jun 2006 20:41:48 GMT From: Clément Lecigne <clem1@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 99463 for review Message-ID: <200606172041.k5HKfmC9005327@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=99463 Change 99463 by clem1@clem1_ipv6vulns on 2006/06/17 20:41:06 icmp6 improvements plus basic samples, new connectors and python bpf wrapper. Affected files ... .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/bpf/bpfmodule.c#1 add .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/icmpv6.py#2 edit .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/nd6.py#2 delete .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/pseudoipv6.py#1 add .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/pcs.py#2 edit .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/samples/ping6.py#1 add .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/samples/rawping6.py#1 add .. //depot/projects/soc2006/clem1_ipv6vulns/pcs/setup.py#2 edit Differences ... ==== //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/packets/icmpv6.py#2 (text+ko) ==== @@ -36,15 +36,122 @@ import pcs import struct +from pseudoipv6 import * +ND_ROUTER_SOLICIT = 133 +ND_ROUTER_ADVERT = 134 +ND_NEIGHBOR_SOLICIT = 135 +ND_NEIGHBOR_ADVERT = 136 +ND_REDIRECT = 137 +ICMP6_ROUTER_RENUMBERING = 138 +ICMP6_WRUREQUEST = 139 +ICMP6_WRUREPLY = 140 +ICMP6_DST_UNREACH = 1 +ICMP6_PACKET_TOO_BIG = 2 +ICMP6_TIME_EXCEEDED = 3 +ICMP6_PARAM_PROB = 4 +ICMP6_ECHO_REQUEST = 128 +ICMP6_ECHO_REPLY = 129 + +op = 0 + class icmpv6(pcs.Packet): layout = pcs.Layout() - def __init__(self, bytes = None): - type = pcs.Field("type", 8) + def __init__(self, type = 0, bytes = None): + """icmpv6 header RFC2463 and RFC2461""" + ty = pcs.Field("type", 8, default = type) code = pcs.Field("code", 8) cksum = pcs.Field("checksum", 16) - pcs.Packet.__init__(self, [type, code, cksum], bytes) + if type == ICMP6_ECHO_REQUEST or type == ICMP6_ECHO_REPLY: + id = pcs.Field("id", 16) + seq = pcs.Field("sequence", 16) + pcs.Packet.__init__(self, [ty, code, cksum, id, seq], bytes) + elif type == ICMP6_TIME_EXCEEDED or type == ICMP6_DST_UNREACH or type == ND_ROUTER_SOLICIT: + unused = pcs.Field("unused", 32) + pcs.Packet.__init__(self, [ty, code, cksum, unused], bytes) + elif type == ICMP6_PARAM_PROB: + pointer = pcs.Field("pointer", 32) + pcs.Packet.__init__(self, [ty, code, cksum, pointer], bytes) + 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 == ND_ROUTER_ADVERT: + chp = pcs.Field("current_hop_limit", 8) + m = pcs.Field("m", 1) + o = pcs.Field("o", 1) + unused = pcs.Field("unused", 6) + 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) + elif type == ND_NEIGHBOR_SOLICIT: + reserved = pcs.Field("reserved", 32) + target = pcs.Field("target", 16 * 8) + 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) + pcs.Packet.__init__(self, [ty, code, cksum, r, s, o, reserved, target], bytes) + else: + pcs.Packet.__init__(self, [ty, code, cksum], bytes) + + def option(self, type = 0): + """add icmp6 option header RFC2461""" + global op + op += 1 + ty = pcs.Field("type" + str(op), 8, default = type) + length = pcs.Field("length" + str(op), 8) + # Source Link-Layer Address. + if type == 1: + source = pcs.Field("source" + str(op), 48) + pcs.Packet.__add__(self, [ty, length, source]) + # Target Link-Layer Address + elif type == 2: + target = pcs.Field("target" + str(op), 48) + pcs.Packet.__add__(self, [ty, length, target]) + # Prefix Information. + elif type == 3: + plength = pcs.Field("prefix_length" + str(op), 8) + l = pcs.Field("L" + str(op), 1) + a = pcs.Field("A" + str(op), 1) + reserved1 = pcs.Field("reserved1" + str(op), 6) + vlf = pcs.Field("valid_lifetime" + str(op), 32) + plf = pcs.Field("preferred_lifetime" + str(op), 32) + reserved2 = pcs.Field("reserved2" + str(op), 32) + prefix = pcs.Field("prefix" + str(op), 48) + pcs.Packet.__add__(self, [ty, length, plength, l, a, reserved1, vlf, plf, reserved2, prefix]) + # Redirected Header. + elif type == 4: + reserved = pcs.Field("reserved" + str(op), 48) + pcs.Packet.__add__(self, [ty, length, reserved]) + # MTU + elif type == 5: + reserved = pcs.Field("reserved" + str(op), 16) + mtu = pcs.Field("mtu" + str(op), 32) + pcs.Packet.__add__(self, [ty, length, reserved, mtu]) + else: + pcs.Packet.__add__(self, [ty, length]) - + def cksum(self, ip, data = ""): + """return icmpv6 checksum if we send packet through + raw link level (i.e bpf)""" + total = 0 + p6 = pseudoipv6() + p6.src = ip.src + p6.dst = ip.dst + p6.length = len(self.getbytes()) + len (data) + p6.next_header = ip.next_header + pkt = p6.getbytes() + self.getbytes() + data + if len(pkt) % 2 == 1: + pkt += "\0" + for i in range(len(pkt)/2): + total += (struct.unpack("!H", pkt[2*i:2*i+2])[0]) + total = (total >> 16) + (total & 0xffff) + total += total >> 16 + return ~total ==== //depot/projects/soc2006/clem1_ipv6vulns/pcs/pcs/pcs.py#2 (text+ko) ==== @@ -169,6 +169,11 @@ if bytes != None: self.decode(bytes) + def __add__(self, layout = None): + for field in layout: + self.layout.append(field) + self._needencode = True + def __setattr__(self, name, value): """Setting the layout is a special case because of the ramifications this has on the packet. Only fields represented @@ -345,27 +350,44 @@ unifying mechanism so you can write packets over any of the available APIs and the connector will do the right thing.""" - def __init__(name, mode, arg): - import socket + def __init__(self, name, arg = ""): + from socket import * + import bpf + connectors = [ "IPV4", "IPV6", "ICMP6", "UDP6", "TCP6", "ICMP", "UDP", "TCP", "BPF", "PCAP" ] + self.bsd = 0 if name not in connectors: raise InvalidConnectorError - if name == "TCP": - self.sock = socket(socket.AF_INET, socket.SOCK_STREAM) - elif name == "UDP": - self.sock = socket(socket.AF_INET, socket.SOCK_DGRAM) + if name == "IPV4": + self.sock = socket(AF_INET, SOCK_RAW, arg) + self.sock.setsockopt(IPPROTO_IP, IP_HDRINCL, 1) + elif name == "ICMP6": + self.sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6) elif name == "TCP6": - self.sock = socket(socket.AF_INET6, socket.SOCK_STREAM) + self.sock = socket(AF_INET6, SOCK_RAW, IPPROTO_TCP) + elif name == "TCP": + self.sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP) elif name == "UDP6": - self.sock = socket(socket.AF_INET6, socket.SOCK_DGRAM) + self.sock = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP) + elif name == "UDP": + self.sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP) + elif name == "IPV6" or name == "BPF": + if re.search("bsd|BSD", sys.platform): + self.sock = bpf.open(arg) + self.bsd = 1 + else: + self.sock = socket(PF_PACKET, SOCK_RAW) + sock.bind((arg, 0x86dd)) elif name == "PCAP": self.sock = pcap.pcap(arg) def read(): pass - def write(): - pass - - def close(): - pass - + def write(self, packet, ip = ""): + if self.bsd: + self.sock.write(packet) + else: + self.sock.sendto(packet, (ip, 0)) + + def close(self): + self.sock.close() ==== //depot/projects/soc2006/clem1_ipv6vulns/pcs/setup.py#2 (text+ko) ==== @@ -36,9 +36,11 @@ # Description: The setup script for all of the Packet Construction Set -from distutils.core import setup +from distutils.core import setup, Extension from pcs import pcs +bpf = Extension('bpf', sources = ['bpf/bpfmodule.c']) + setup(name='pcs', version = '0.1', description = 'Packet Construction Set', @@ -46,4 +48,5 @@ author_email = 'gnn@neville-neil.com', url = 'http://pcs.sf.net', packages = ['pcs', 'pcs.packets'], + ext_modules = [bpf], )
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606172041.k5HKfmC9005327>