mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-05 20:36:10 +02:00
packet lib: add ipv6 ICMP support
Signed-off-by: "Henkel, Michael" <michael.henkel@hp.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
bed275ec1b
commit
e91758277c
179
ryu/lib/packet/icmp6.py
Normal file
179
ryu/lib/packet/icmp6.py
Normal file
@ -0,0 +1,179 @@
|
||||
# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import struct
|
||||
import socket
|
||||
import sys
|
||||
import array
|
||||
import binascii
|
||||
from . import packet_base
|
||||
from . import packet_utils
|
||||
from ryu.lib.mac import haddr_to_bin, haddr_to_str
|
||||
|
||||
ICMP6_DST_UNREACH = 1 # dest unreachable, codes:
|
||||
ICMP6_PACKET_TOO_BIG = 2 # packet too big
|
||||
ICMP6_TIME_EXCEEDED = 3 # time exceeded, code:
|
||||
ICMP6_PARAM_PROB = 4 # ip6 header bad
|
||||
|
||||
ICMP6_ECHO_REQUEST = 128 # echo service
|
||||
ICMP6_ECHO_REPLY = 129 # echo reply
|
||||
MLD_LISTENER_QUERY = 130 # multicast listener query
|
||||
MLD_LISTENER_REPOR = 131 # multicast listener report
|
||||
MLD_LISTENER_DONE = 132 # multicast listener done
|
||||
|
||||
# RFC2292 decls
|
||||
ICMP6_MEMBERSHIP_QUERY = 130 # group membership query
|
||||
ICMP6_MEMBERSHIP_REPORT = 131 # group membership report
|
||||
ICMP6_MEMBERSHIP_REDUCTION = 132 # group membership termination
|
||||
|
||||
ND_ROUTER_SOLICIT = 133 # router solicitation
|
||||
ND_ROUTER_ADVERT = 134 # router advertisment
|
||||
ND_NEIGHBOR_SOLICIT = 135 # neighbor solicitation
|
||||
ND_NEIGHBOR_ADVERT = 136 # neighbor advertisment
|
||||
ND_REDIREC = 137 # redirect
|
||||
|
||||
ICMP6_ROUTER_RENUMBERING = 138 # router renumbering
|
||||
|
||||
ICMP6_WRUREQUEST = 139 # who are you request
|
||||
ICMP6_WRUREPLY = 140 # who are you reply
|
||||
ICMP6_FQDN_QUERY = 139 # FQDN query
|
||||
ICMP6_FQDN_REPLY = 140 # FQDN reply
|
||||
ICMP6_NI_QUERY = 139 # node information request
|
||||
ICMP6_NI_REPLY = 140 # node information reply
|
||||
|
||||
ICMP6_MAXTYPE = 201
|
||||
|
||||
|
||||
class icmp6(packet_base.PacketBase):
|
||||
_PACK_STR = '!BBH'
|
||||
_MIN_LEN = struct.calcsize(_PACK_STR)
|
||||
_ICMP6_TYPES = {}
|
||||
|
||||
@staticmethod
|
||||
def register_icmp6_type(*args):
|
||||
def _register_icmp6_type(cls):
|
||||
for type_ in args:
|
||||
icmp6._ICMP6_TYPES[type_] = cls
|
||||
return cls
|
||||
return _register_icmp6_type
|
||||
|
||||
def __init__(self, type_, code, csum, data=None):
|
||||
super(icmp6, self).__init__()
|
||||
self.type_ = type_
|
||||
self.code = code
|
||||
self.csum = csum
|
||||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def parser(cls, buf):
|
||||
(type_, code, csum) = struct.unpack_from(cls._PACK_STR, buf)
|
||||
msg = cls(type_, code, csum)
|
||||
offset = cls._MIN_LEN
|
||||
if len(buf) > offset:
|
||||
cls_ = cls._ICMP6_TYPES.get(type_, None)
|
||||
if cls_:
|
||||
msg.data = cls_.parser(buf, offset)
|
||||
else:
|
||||
msg.data = buf[offset:]
|
||||
|
||||
return msg, None
|
||||
|
||||
def serialize(self, payload, prev):
|
||||
hdr = bytearray(struct.pack(icmp6._PACK_STR, self.type_,
|
||||
self.code, self.csum))
|
||||
|
||||
if self.data is not None:
|
||||
if self.type_ in icmp6._ICMP6_TYPES:
|
||||
hdr += self.data.serialize()
|
||||
else:
|
||||
hdr += self.data
|
||||
src = prev.src
|
||||
dst = prev.dst
|
||||
nxt = prev.nxt
|
||||
if self.csum == 0:
|
||||
length = len(str(hdr))
|
||||
ph = struct.pack('!16s16sBBH', prev.src, prev.dst, 0, prev.nxt,
|
||||
length)
|
||||
f = ph + hdr + payload
|
||||
if len(f) % 2:
|
||||
f += '\x00'
|
||||
self.csum = socket.htons(packet_utils.checksum(f))
|
||||
struct.pack_into('!H', hdr, 2, self.csum)
|
||||
|
||||
return hdr
|
||||
|
||||
|
||||
@icmp6.register_icmp6_type(ND_NEIGHBOR_SOLICIT, ND_NEIGHBOR_ADVERT)
|
||||
class nd_s(object):
|
||||
_PACK_STR = '!I16sBB6s'
|
||||
_MIN_LEN = struct.calcsize(_PACK_STR)
|
||||
|
||||
def __init__(self, res, dst, type_, length, hw_src, data=None):
|
||||
self.res = res << 29
|
||||
self.dst = dst
|
||||
self.type_ = type_
|
||||
self.length = length
|
||||
self.hw_src = hw_src
|
||||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def parser(cls, buf, offset):
|
||||
(res, dst, type_, length, hw_src) = struct.unpack_from(cls._PACK_STR,
|
||||
buf, offset)
|
||||
msg = cls(res, dst, type_, length, hw_src)
|
||||
offset += cls._MIN_LEN
|
||||
if len(buf) > offset:
|
||||
msg.data = buf[offset:]
|
||||
|
||||
return msg
|
||||
|
||||
def serialize(self):
|
||||
hdr = bytearray(struct.pack(nd_s._PACK_STR, self.res, self.dst,
|
||||
self.type_, self.length, self.hw_src))
|
||||
|
||||
if self.data is not None:
|
||||
hdr += self.data
|
||||
|
||||
return hdr
|
||||
|
||||
|
||||
@icmp6.register_icmp6_type(ICMP6_ECHO_REPLY, ICMP6_ECHO_REQUEST)
|
||||
class echo(object):
|
||||
_PACK_STR = '!HH'
|
||||
_MIN_LEN = struct.calcsize(_PACK_STR)
|
||||
|
||||
def __init__(self, id_, seq, data=None):
|
||||
self.id = id_
|
||||
self.seq = seq
|
||||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def parser(cls, buf, offset):
|
||||
(id_, seq) = struct.unpack_from(cls._PACK_STR, buf, offset)
|
||||
msg = cls(id_, seq)
|
||||
offset += cls._MIN_LEN
|
||||
|
||||
if len(buf) > offset:
|
||||
msg.data = buf[offset:]
|
||||
|
||||
return msg
|
||||
|
||||
def serialize(self):
|
||||
hdr = bytearray(struct.pack(echo._PACK_STR, self.id,
|
||||
self.seq))
|
||||
if self.data is not None:
|
||||
hdr += bytearray(self.data)
|
||||
|
||||
return hdr
|
||||
@ -17,6 +17,7 @@ import struct
|
||||
import socket
|
||||
from . import packet_base
|
||||
from . import packet_utils
|
||||
from . import icmp6
|
||||
from . import tcp
|
||||
from ryu.ofproto import inet
|
||||
|
||||
@ -64,4 +65,5 @@ class ipv6(packet_base.PacketBase):
|
||||
self.src, self.dst)
|
||||
return hdr
|
||||
|
||||
ipv6.register_packet_type(icmp6.icmp6, inet.IPPROTO_ICMP6)
|
||||
ipv6.register_packet_type(tcp.tcp, inet.IPPROTO_TCP)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user