summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2013-03-29 12:50:59 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2013-03-31 18:21:01 +0900
commit2195ba0e4dea9c6447af646c98c2d1b3a9805130 (patch)
tree172d76dd65778ce9386dbd378cc43fa2653c9c07
parent565df6fc483653cc93d12ec3aed70fa81b5b973a (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.py61
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)