PERFORCE change 99463 for review
Clément Lecigne
clem1 at FreeBSD.org
Sat Jun 17 20:41:49 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=99463
Change 99463 by clem1 at 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 at neville-neil.com',
url = 'http://pcs.sf.net',
packages = ['pcs', 'pcs.packets'],
+ ext_modules = [bpf],
)
More information about the p4-projects
mailing list