diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2013-03-29 12:50:59 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2013-03-31 18:21:01 +0900 |
commit | 2195ba0e4dea9c6447af646c98c2d1b3a9805130 (patch) | |
tree | 172d76dd65778ce9386dbd378cc43fa2653c9c07 | |
parent | 565df6fc483653cc93d12ec3aed70fa81b5b973a (diff) |
lib/packet: checksum function with pseudo ipv4/ipv6 header
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/lib/packet/packet_utils.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/ryu/lib/packet/packet_utils.py b/ryu/lib/packet/packet_utils.py index 2a7f2218..b8f2e058 100644 --- a/ryu/lib/packet/packet_utils.py +++ b/ryu/lib/packet/packet_utils.py @@ -14,6 +14,7 @@ # limitations under the License. import socket +import struct def carry_around_add(a, b): @@ -30,3 +31,63 @@ def checksum(data): w = data[i] + (data[i + 1] << 8) s = carry_around_add(s, w) return socket.ntohs(~s & 0xffff) + + +# avoid circular import +_IPV4_PSEUDO_HEADER_PACK_STR = '!IIxBH' +_IPV6_PSEUDO_HEADER_PACK_STR = '!16s16sI3xB' + + +def checksum_ip(ipvx, length, payload): + """ + calculate checksum of IP pseudo header + + IPv4 pseudo header + UDP RFC768 + TCP RFC793 3.1 + + 0 7 8 15 16 23 24 31 + +--------+--------+--------+--------+ + | source address | + +--------+--------+--------+--------+ + | destination address | + +--------+--------+--------+--------+ + | zero |protocol| length | + +--------+--------+--------+--------+ + + + IPv6 pseudo header + RFC2460 8.1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Source Address + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Destination Address + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Upper-Layer Packet Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | zero | Next Header | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + """ + if ipvx.version == 4: + header = struct.pack(_IPV4_PSEUDO_HEADER_PACK_STR, + ipvx.src, ipvx.dst, ipvx.proto, length) + elif ipvx.version == 6: + header = struct.pack(_IPV6_PSEUDO_HEADER_PACK_STR, + ipvx.src, ipvx.dst, length, ipvx.nxt) + else: + raise ValueError('Unknown IP version %d' % ipvx.version) + + buf = header + payload + return checksum(buf) |