1 # Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
20 from ryu.lib import addrconv
23 def carry_around_add(a, b):
25 return (c & 0xffff) + (c >> 16)
29 data = six.binary_type(data) # input can be bytearray.
33 s = sum(array.array('H', data))
34 s = (s & 0xffff) + (s >> 16)
36 return socket.ntohs(~s & 0xffff)
39 # avoid circular import
40 _IPV4_PSEUDO_HEADER_PACK_STR = '!4s4sxBH'
41 _IPV6_PSEUDO_HEADER_PACK_STR = '!16s16sI3xB'
44 def checksum_ip(ipvx, length, payload):
46 calculate checksum of IP pseudo header
53 +--------+--------+--------+--------+
55 +--------+--------+--------+--------+
56 | destination address |
57 +--------+--------+--------+--------+
58 | zero |protocol| length |
59 +--------+--------+--------+--------+
64 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 + Destination Address +
80 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 | Upper-Layer Packet Length |
82 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83 | zero | Next Header |
84 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
87 header = struct.pack(_IPV4_PSEUDO_HEADER_PACK_STR,
88 addrconv.ipv4.text_to_bin(ipvx.src),
89 addrconv.ipv4.text_to_bin(ipvx.dst),
91 elif ipvx.version == 6:
92 header = struct.pack(_IPV6_PSEUDO_HEADER_PACK_STR,
93 addrconv.ipv6.text_to_bin(ipvx.src),
94 addrconv.ipv6.text_to_bin(ipvx.dst),
97 raise ValueError('Unknown IP version %d' % ipvx.version)
99 buf = header + payload
106 def fletcher_checksum(data, offset):
108 Fletcher Checksum -- Refer to RFC1008
110 calling with offset == _FLETCHER_CHECKSUM_VALIDATE will validate the
111 checksum without modifying the buffer; a valid checksum returns 0.
117 data = bytearray(data)
118 data[offset:offset + 2] = [0] * 2
121 tlen = min(length - pos, _MODX)
122 for d in data[pos:pos + tlen]:
129 x = ((length - offset - 1) * c0 - c1) % 255
138 return (x << 8) | (y & 0xff)