1# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. 2# 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 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 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 12# implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import abc 17import six 18import struct 19 20from ryu.lib import addrconv 21from ryu.lib import stringify 22from ryu.lib.packet import packet_base 23 24# Chunk Types 25TYPE_DATA = 0 26TYPE_INIT = 1 27TYPE_INIT_ACK = 2 28TYPE_SACK = 3 29TYPE_HEARTBEAT = 4 30TYPE_HEARTBEAT_ACK = 5 31TYPE_ABORT = 6 32TYPE_SHUTDOWN = 7 33TYPE_SHUTDOWN_ACK = 8 34TYPE_ERROR = 9 35TYPE_COOKIE_ECHO = 10 36TYPE_COOKIE_ACK = 11 37TYPE_ECN_ECHO = 12 38TYPE_CWR = 13 39TYPE_SHUTDOWN_COMPLETE = 14 40 41# Cause Code 42CCODE_INVALID_STREAM_ID = 1 43CCODE_MISSING_PARAM = 2 44CCODE_STALE_COOKIE = 3 45CCODE_OUT_OF_RESOURCE = 4 46CCODE_UNRESOLVABLE_ADDR = 5 47CCODE_UNRECOGNIZED_CHUNK = 6 48CCODE_INVALID_PARAM = 7 49CCODE_UNRECOGNIZED_PARAM = 8 50CCODE_NO_USERDATA = 9 51CCODE_COOKIE_WHILE_SHUTDOWN = 10 52CCODE_RESTART_WITH_NEW_ADDR = 11 53CCODE_USER_INITIATED_ABORT = 12 54CCODE_PROTOCOL_VIOLATION = 13 55 56# Chunk Parameter Types 57PTYPE_HEARTBEAT = 1 58PTYPE_IPV4 = 5 59PTYPE_IPV6 = 6 60PTYPE_STATE_COOKIE = 7 61PTYPE_UNRECOGNIZED_PARAM = 8 62PTYPE_COOKIE_PRESERVE = 9 63PTYPE_HOST_ADDR = 11 64PTYPE_SUPPORTED_ADDR = 12 65PTYPE_ECN = 32768 66 67 68class sctp(packet_base.PacketBase): 69 """Stream Control Transmission Protocol (SCTP) 70 header encoder/decoder class (RFC 4960). 71 72 An instance has the following attributes at least. 73 Most of them are same to the on-wire counterparts but in host byte order. 74 __init__ takes the corresponding args in this order. 75 76 .. tabularcolumns:: |l|L| 77 78 ============== ===================================================== 79 Attribute Description 80 ============== ===================================================== 81 src_port Source Port 82 dst_port Destination Port 83 vtag Verification Tag 84 csum Checksum 85 (0 means automatically-calculate when encoding) 86 chunks a list of derived classes of ryu.lib.packet.sctp.chunk. 87 ============== ===================================================== 88 """ 89 90 _PACK_STR = '!HHII' 91 _MIN_LEN = struct.calcsize(_PACK_STR) 92 _SCTP_CHUNK_TYPE = {} 93 _class_prefixes = ['chunk_'] 94 95 @staticmethod 96 def register_chunk_type(*args): 97 def _register_chunk_type(cls): 98 sctp._SCTP_CHUNK_TYPE[cls.chunk_type()] = cls 99 return cls 100 return _register_chunk_type(args[0]) 101 102 def __init__(self, src_port=1, dst_port=1, vtag=0, csum=0, chunks=None): 103 super(sctp, self).__init__() 104 self.src_port = src_port 105 self.dst_port = dst_port 106 self.vtag = vtag 107 self.csum = csum 108 chunks = chunks or [] 109 assert isinstance(chunks, list) 110 for one in chunks: 111 assert isinstance(one, chunk) 112 self.chunks = chunks 113 114 @classmethod 115 def parser(cls, buf): 116 (src_port, dst_port, vtag, csum) = struct.unpack_from( 117 cls._PACK_STR, buf) 118 chunks = [] 119 offset = cls._MIN_LEN 120 while offset < len(buf): 121 (type_, ) = struct.unpack_from('!B', buf, offset) 122 cls_ = cls._SCTP_CHUNK_TYPE.get(type_) 123 if not cls_: 124 break 125 ins = cls_.parser(buf[offset:]) 126 chunks.append(ins) 127 offset += len(ins) 128 msg = cls(src_port, dst_port, vtag, csum, chunks) 129 return msg, None, buf[offset:] 130 131 def serialize(self, payload, prev): 132 buf = bytearray(struct.pack( 133 self._PACK_STR, self.src_port, self.dst_port, self.vtag, 134 self.csum)) 135 if self.chunks: 136 for one in self.chunks: 137 buf.extend(one.serialize()) 138 if self.csum == 0: 139 self.csum = self._checksum(buf) 140 struct.pack_into('!I', buf, 8, self.csum) 141 return six.binary_type(buf) 142 143 def __len__(self): 144 length = self._MIN_LEN 145 if self.chunks is not None: 146 for one in self.chunks: 147 length += len(one) 148 return length 149 150 def _checksum(self, data): 151 # from RFC 3309 152 crc_c = [ 153 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 154 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 155 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 156 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 157 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 158 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, 159 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 160 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, 161 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 162 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, 163 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 164 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, 165 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 166 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, 167 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 168 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 169 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 170 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, 171 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 172 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, 173 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 174 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, 175 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 176 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, 177 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 178 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, 179 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 180 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, 181 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 182 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, 183 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 184 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, 185 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 186 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, 187 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 188 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, 189 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 190 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, 191 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 192 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, 193 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 194 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, 195 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 196 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, 197 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 198 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 199 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 200 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, 201 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 202 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, 203 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 204 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 205 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 206 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, 207 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 208 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, 209 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 210 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, 211 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 212 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, 213 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 214 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, 215 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 216 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351, 217 ] 218 219 crc32 = 0xffffffff 220 for c in str(data): 221 crc32 = (crc32 >> 8) ^ crc_c[(crc32 ^ (ord(c))) & 0xFF] 222 crc32 = (~crc32) & 0xffffffff 223 return struct.unpack(">I", struct.pack("<I", crc32))[0] 224 225 226# ======================================================================= 227# 228# Chunk Types 229# 230# ======================================================================= 231@six.add_metaclass(abc.ABCMeta) 232class chunk(stringify.StringifyMixin): 233 _PACK_STR = '!BBH' 234 _MIN_LEN = struct.calcsize(_PACK_STR) 235 236 @classmethod 237 @abc.abstractmethod 238 def chunk_type(cls): 239 pass 240 241 @abc.abstractmethod 242 def __init__(self, type_, length): 243 self._type = type_ 244 self.length = length 245 246 @classmethod 247 @abc.abstractmethod 248 def parser(cls, buf): 249 pass 250 251 def __len__(self): 252 return self.length 253 254 255@six.add_metaclass(abc.ABCMeta) 256class chunk_init_base(chunk): 257 _PACK_STR = '!BBHIIHHI' 258 _MIN_LEN = struct.calcsize(_PACK_STR) 259 _class_prefixes = ['param_'] 260 261 def __init__(self, flags=0, length=0, init_tag=0, a_rwnd=0, os=0, 262 mis=0, i_tsn=0, params=None): 263 super(chunk_init_base, self).__init__(self.chunk_type(), length) 264 self.flags = flags 265 self.init_tag = init_tag 266 self.a_rwnd = a_rwnd 267 self.os = os 268 self.mis = mis 269 self.i_tsn = i_tsn 270 params = params or [] 271 assert isinstance(params, list) 272 for one in params: 273 assert isinstance(one, param) 274 self.params = params 275 276 @classmethod 277 def parser_base(cls, buf, recog): 278 (_, flags, length, init_tag, a_rwnd, os, mis, i_tsn 279 ) = struct.unpack_from(cls._PACK_STR, buf) 280 params = [] 281 offset = cls._MIN_LEN 282 while offset < length: 283 (ptype, ) = struct.unpack_from('!H', buf, offset) 284 cls_ = recog.get(ptype) 285 if not cls_: 286 break 287 ins = cls_.parser(buf[offset:]) 288 params.append(ins) 289 offset += len(ins) 290 msg = cls(flags, length, init_tag, a_rwnd, os, mis, i_tsn, params) 291 return msg 292 293 def serialize(self): 294 buf = bytearray(struct.pack( 295 self._PACK_STR, self.chunk_type(), self.flags, 296 self.length, self.init_tag, self.a_rwnd, self.os, self.mis, 297 self.i_tsn)) 298 for one in self.params: 299 buf.extend(one.serialize()) 300 if 0 == self.length: 301 self.length = len(buf) 302 struct.pack_into('!H', buf, 2, self.length) 303 return six.binary_type(buf) 304 305 306@six.add_metaclass(abc.ABCMeta) 307class chunk_heartbeat_base(chunk): 308 _class_prefixes = ['param_'] 309 310 def __init__(self, flags=0, length=0, info=None): 311 super(chunk_heartbeat_base, self).__init__( 312 self.chunk_type(), length) 313 self.flags = flags 314 if info is not None: 315 assert isinstance(info, param) 316 self.info = info 317 318 @classmethod 319 def parser_base(cls, buf, recog): 320 (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) 321 (ptype, ) = struct.unpack_from('!H', buf, cls._MIN_LEN) 322 cls_ = recog.get(ptype) 323 info = cls_.parser(buf[cls._MIN_LEN:]) 324 msg = cls(flags, length, info) 325 return msg 326 327 def serialize(self): 328 buf = bytearray(struct.pack( 329 self._PACK_STR, self.chunk_type(), self.flags, 330 self.length)) 331 if self.info is not None: 332 buf.extend(self.info.serialize()) 333 if 0 == self.length: 334 self.length = len(buf) 335 struct.pack_into('!H', buf, 2, self.length) 336 return six.binary_type(buf) 337 338 339@six.add_metaclass(abc.ABCMeta) 340class chunk_ack_base(chunk): 341 def __init__(self, flags=0, length=0): 342 super(chunk_ack_base, self).__init__(self.chunk_type(), length) 343 self.flags = flags 344 345 @classmethod 346 def parser(cls, buf): 347 (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) 348 return cls(flags, length) 349 350 def serialize(self): 351 if 0 == self.length: 352 self.length = self._MIN_LEN 353 buf = struct.pack( 354 self._PACK_STR, self.chunk_type(), self.flags, 355 self.length) 356 return buf 357 358 359@six.add_metaclass(abc.ABCMeta) 360class chunk_ecn_base(chunk): 361 _PACK_STR = '!BBHI' 362 _MIN_LEN = struct.calcsize(_PACK_STR) 363 364 def __init__(self, flags=0, length=0, low_tsn=0): 365 super(chunk_ecn_base, self).__init__(self.chunk_type(), length) 366 self.flags = flags 367 self.low_tsn = low_tsn 368 369 @classmethod 370 def parser(cls, buf): 371 (_, flags, length, low_tsn) = struct.unpack_from(cls._PACK_STR, buf) 372 return cls(flags, length, low_tsn) 373 374 def serialize(self): 375 if 0 == self.length: 376 self.length = self._MIN_LEN 377 buf = struct.pack( 378 self._PACK_STR, self.chunk_type(), self.flags, self.length, 379 self.low_tsn) 380 return buf 381 382 383@sctp.register_chunk_type 384class chunk_data(chunk): 385 """Stream Control Transmission Protocol (SCTP) 386 sub encoder/decoder class for Payload Data (DATA) chunk (RFC 4960). 387 388 This class is used with the following. 389 390 - ryu.lib.packet.sctp.sctp 391 392 An instance has the following attributes at least. 393 Most of them are same to the on-wire counterparts but in host byte order. 394 __init__ takes the corresponding args in this order. 395 396 .. tabularcolumns:: |l|L| 397 398 ============== ===================================================== 399 Attribute Description 400 ============== ===================================================== 401 unordered if set to '1', the receiver ignores the sequence number. 402 begin if set to '1', this chunk is the first fragment. 403 end if set to '1', this chunk is the last fragment. 404 length length of this chunk containing this header. 405 (0 means automatically-calculate when encoding) 406 tsn Transmission Sequence Number. 407 sid stream id. 408 seq the sequence number. 409 payload_id application specified protocol id. '0' means that 410 no application id is identified. 411 payload_data user data. 412 ============== ===================================================== 413 """ 414 415 _PACK_STR = '!BBHIHHI' 416 _MIN_LEN = struct.calcsize(_PACK_STR) 417 418 @classmethod 419 def chunk_type(cls): 420 return TYPE_DATA 421 422 def __init__(self, unordered=0, begin=0, end=0, length=0, tsn=0, 423 sid=0, seq=0, payload_id=0, payload_data=None): 424 assert (1 == unordered | 1) 425 assert (1 == begin | 1) 426 assert (1 == end | 1) 427 assert (payload_data is not None) 428 super(chunk_data, self).__init__(self.chunk_type(), length) 429 self.unordered = unordered 430 self.begin = begin 431 self.end = end 432 self.tsn = tsn 433 self.sid = sid 434 self.seq = seq 435 self.payload_id = payload_id 436 self.payload_data = payload_data 437 438 @classmethod 439 def parser(cls, buf): 440 (_, flags, length, tsn, sid, seq, payload_id 441 ) = struct.unpack_from(cls._PACK_STR, buf) 442 unordered = (flags >> 2) & 1 443 begin = (flags >> 1) & 1 444 end = (flags >> 0) & 1 445 fmt = '!%ds' % (length - cls._MIN_LEN) 446 (payload_data, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) 447 return cls(unordered, begin, end, length, tsn, sid, seq, 448 payload_id, payload_data) 449 450 def serialize(self): 451 flags = ( 452 (self.unordered << 2) | 453 (self.begin << 1) | 454 (self.end << 0)) 455 buf = bytearray(struct.pack( 456 self._PACK_STR, self.chunk_type(), flags, self.length, 457 self.tsn, self.sid, self.seq, self.payload_id)) 458 buf.extend(self.payload_data) 459 if 0 == self.length: 460 self.length = len(buf) 461 struct.pack_into('!H', buf, 2, self.length) 462 return six.binary_type(buf) 463 464 465@sctp.register_chunk_type 466class chunk_init(chunk_init_base): 467 """Stream Control Transmission Protocol (SCTP) 468 sub encoder/decoder class for Initiation (INIT) chunk (RFC 4960). 469 470 This class is used with the following. 471 472 - ryu.lib.packet.sctp.sctp 473 474 An instance has the following attributes at least. 475 Most of them are same to the on-wire counterparts but in host byte order. 476 __init__ takes the corresponding args in this order. 477 478 .. tabularcolumns:: |l|L| 479 480 ============== ===================================================== 481 Attribute Description 482 ============== ===================================================== 483 flags set to '0'. this field will be ignored. 484 length length of this chunk containing this header. 485 (0 means automatically-calculate when encoding) 486 init_tag the tag that be used as Verification Tag. 487 a_rwnd Advertised Receiver Window Credit. 488 os number of outbound streams. 489 mis number of inbound streams. 490 i_tsn Transmission Sequence Number that the sender will use. 491 params Optional/Variable-Length Parameters. 492 493 a list of derived classes of ryu.lib.packet.sctp.param. 494 ============== ===================================================== 495 """ 496 497 _RECOGNIZED_PARAMS = {} 498 499 @staticmethod 500 def register_param_type(*args): 501 def _register_param_type(cls): 502 chunk_init._RECOGNIZED_PARAMS[cls.param_type()] = cls 503 return cls 504 return _register_param_type(args[0]) 505 506 @classmethod 507 def chunk_type(cls): 508 return TYPE_INIT 509 510 @classmethod 511 def parser(cls, buf): 512 return super(chunk_init, cls).parser_base( 513 buf, cls._RECOGNIZED_PARAMS) 514 515 516@sctp.register_chunk_type 517class chunk_init_ack(chunk_init_base): 518 """Stream Control Transmission Protocol (SCTP) 519 sub encoder/decoder class for Initiation Acknowledgement (INIT ACK) 520 chunk (RFC 4960). 521 522 This class is used with the following. 523 524 - ryu.lib.packet.sctp.sctp 525 526 An instance has the following attributes at least. 527 Most of them are same to the on-wire counterparts but in host byte order. 528 __init__ takes the corresponding args in this order. 529 530 .. tabularcolumns:: |l|L| 531 532 ============== ===================================================== 533 Attribute Description 534 ============== ===================================================== 535 flags set to '0'. this field will be ignored. 536 length length of this chunk containing this header. 537 (0 means automatically-calculate when encoding) 538 init_tag the tag that be used as Verification Tag. 539 a_rwnd Advertised Receiver Window Credit. 540 os number of outbound streams. 541 mis number of inbound streams. 542 i_tsn Transmission Sequence Number that the sender will use. 543 params Optional/Variable-Length Parameters. 544 545 a list of derived classes of ryu.lib.packet.sctp.param. 546 ============== ===================================================== 547 """ 548 549 _RECOGNIZED_PARAMS = {} 550 551 @staticmethod 552 def register_param_type(*args): 553 def _register_param_type(cls): 554 chunk_init_ack._RECOGNIZED_PARAMS[cls.param_type()] = cls 555 return cls 556 return _register_param_type(args[0]) 557 558 @classmethod 559 def chunk_type(cls): 560 return TYPE_INIT_ACK 561 562 @classmethod 563 def parser(cls, buf): 564 return super(chunk_init_ack, cls).parser_base( 565 buf, cls._RECOGNIZED_PARAMS) 566 567 568@sctp.register_chunk_type 569class chunk_sack(chunk): 570 """Stream Control Transmission Protocol (SCTP) 571 sub encoder/decoder class for Selective Acknowledgement (SACK) chunk 572 (RFC 4960). 573 574 This class is used with the following. 575 576 - ryu.lib.packet.sctp.sctp 577 578 An instance has the following attributes at least. 579 Most of them are same to the on-wire counterparts but in host byte order. 580 __init__ takes the corresponding args in this order. 581 582 .. tabularcolumns:: |l|L| 583 584 ============== ===================================================== 585 Attribute Description 586 ============== ===================================================== 587 flags set to '0'. this field will be ignored. 588 length length of this chunk containing this header. 589 (0 means automatically-calculate when encoding) 590 tsn_ack TSN of the last DATA chunk received in sequence 591 before a gap. 592 a_rwnd Advertised Receiver Window Credit. 593 gapack_num number of Gap Ack blocks. 594 duptsn_num number of duplicate TSNs. 595 gapacks a list of Gap Ack blocks. one block is made of a list 596 with the start offset and the end offset from tsn_ack. 597 e.g.) gapacks = [[2, 3], [10, 12], [19, 21]] 598 duptsns a list of duplicate TSN. 599 ============== ===================================================== 600 """ 601 602 _PACK_STR = '!BBHIIHH' 603 _MIN_LEN = struct.calcsize(_PACK_STR) 604 _GAPACK_STR = '!HH' 605 _GAPACK_LEN = struct.calcsize(_GAPACK_STR) 606 _DUPTSN_STR = '!I' 607 _DUPTSN_LEN = struct.calcsize(_DUPTSN_STR) 608 609 @classmethod 610 def chunk_type(cls): 611 return TYPE_SACK 612 613 def __init__(self, flags=0, length=0, tsn_ack=0, a_rwnd=0, 614 gapack_num=0, duptsn_num=0, gapacks=None, duptsns=None): 615 super(chunk_sack, self).__init__(self.chunk_type(), length) 616 self.flags = flags 617 self.tsn_ack = tsn_ack 618 self.a_rwnd = a_rwnd 619 self.gapack_num = gapack_num 620 self.duptsn_num = duptsn_num 621 gapacks = gapacks or [] 622 assert isinstance(gapacks, list) 623 for one in gapacks: 624 assert isinstance(one, list) 625 assert 2 == len(one) 626 self.gapacks = gapacks 627 duptsns = duptsns or [] 628 assert isinstance(duptsns, list) 629 self.duptsns = duptsns 630 631 @classmethod 632 def parser(cls, buf): 633 (_, flags, length, tsn_ack, a_rwnd, gapack_num, duptsn_num 634 ) = struct.unpack_from(cls._PACK_STR, buf) 635 gapacks = [] 636 offset = cls._MIN_LEN 637 for _ in range(gapack_num): 638 (gapack_start, gapack_end) = struct.unpack_from( 639 cls._GAPACK_STR, buf, offset) 640 gapacks.append([gapack_start, gapack_end]) 641 offset += cls._GAPACK_LEN 642 duptsns = [] 643 for _ in range(duptsn_num): 644 (duptsn, ) = struct.unpack_from(cls._DUPTSN_STR, buf, offset) 645 duptsns.append(duptsn) 646 offset += cls._DUPTSN_LEN 647 return cls(flags, length, tsn_ack, a_rwnd, gapack_num, duptsn_num, 648 gapacks, duptsns) 649 650 def serialize(self): 651 buf = bytearray(struct.pack( 652 self._PACK_STR, self.chunk_type(), self.flags, 653 self.length, self.tsn_ack, self.a_rwnd, self.gapack_num, 654 self.duptsn_num)) 655 for one in self.gapacks: 656 buf.extend(struct.pack(chunk_sack._GAPACK_STR, one[0], one[1])) 657 for one in self.duptsns: 658 buf.extend(struct.pack(chunk_sack._DUPTSN_STR, one)) 659 if 0 == self.length: 660 self.length = len(buf) 661 struct.pack_into('!H', buf, 2, self.length) 662 return six.binary_type(buf) 663 664 665@sctp.register_chunk_type 666class chunk_heartbeat(chunk_heartbeat_base): 667 """Stream Control Transmission Protocol (SCTP) 668 sub encoder/decoder class for Heartbeat Request (HEARTBEAT) chunk 669 (RFC 4960). 670 671 This class is used with the following. 672 673 - ryu.lib.packet.sctp.sctp 674 675 An instance has the following attributes at least. 676 Most of them are same to the on-wire counterparts but in host byte order. 677 __init__ takes the corresponding args in this order. 678 679 .. tabularcolumns:: |l|L| 680 681 ============== ===================================================== 682 Attribute Description 683 ============== ===================================================== 684 flags set to '0'. this field will be ignored. 685 length length of this chunk containing this header. 686 (0 means automatically-calculate when encoding) 687 info ryu.lib.packet.sctp.param_heartbeat. 688 ============== ===================================================== 689 """ 690 691 _RECOGNIZED_PARAMS = {} 692 693 @staticmethod 694 def register_param_type(*args): 695 def _register_param_type(cls): 696 chunk_heartbeat._RECOGNIZED_PARAMS[cls.param_type()] = cls 697 return cls 698 return _register_param_type(args[0]) 699 700 @classmethod 701 def chunk_type(cls): 702 return TYPE_HEARTBEAT 703 704 @classmethod 705 def parser(cls, buf): 706 return super(chunk_heartbeat, cls).parser_base( 707 buf, cls._RECOGNIZED_PARAMS) 708 709 710@sctp.register_chunk_type 711class chunk_heartbeat_ack(chunk_heartbeat_base): 712 """Stream Control Transmission Protocol (SCTP) 713 sub encoder/decoder class for Heartbeat Acknowledgement 714 (HEARTBEAT ACK) chunk (RFC 4960). 715 716 This class is used with the following. 717 718 - ryu.lib.packet.sctp.sctp 719 720 An instance has the following attributes at least. 721 Most of them are same to the on-wire counterparts but in host byte order. 722 __init__ takes the corresponding args in this order. 723 724 .. tabularcolumns:: |l|L| 725 726 ============== ===================================================== 727 Attribute Description 728 ============== ===================================================== 729 flags set to '0'. this field will be ignored. 730 length length of this chunk containing this header. 731 (0 means automatically-calculate when encoding) 732 info ryu.lib.packet.sctp.param_heartbeat. 733 ============== ===================================================== 734 """ 735 736 _RECOGNIZED_PARAMS = {} 737 738 @staticmethod 739 def register_param_type(*args): 740 def _register_param_type(cls): 741 chunk_heartbeat_ack._RECOGNIZED_PARAMS[cls.param_type()] = cls 742 return cls 743 return _register_param_type(args[0]) 744 745 @classmethod 746 def chunk_type(cls): 747 return TYPE_HEARTBEAT_ACK 748 749 @classmethod 750 def parser(cls, buf): 751 return super(chunk_heartbeat_ack, cls).parser_base( 752 buf, cls._RECOGNIZED_PARAMS) 753 754 755@sctp.register_chunk_type 756class chunk_abort(chunk): 757 """Stream Control Transmission Protocol (SCTP) 758 sub encoder/decoder class for Abort Association (ABORT) chunk (RFC 4960). 759 760 This class is used with the following. 761 762 - ryu.lib.packet.sctp.sctp 763 764 An instance has the following attributes at least. 765 Most of them are same to the on-wire counterparts but in host byte order. 766 __init__ takes the corresponding args in this order. 767 768 .. tabularcolumns:: |l|L| 769 770 ============== ===================================================== 771 Attribute Description 772 ============== ===================================================== 773 tflag '0' means the Verification tag is normal. '1' means 774 the Verification tag is copy of the sender. 775 length length of this chunk containing this header. 776 (0 means automatically-calculate when encoding) 777 causes a list of derived classes of ryu.lib.packet.sctp.causes. 778 ============== ===================================================== 779 """ 780 781 _class_prefixes = ['cause_'] 782 _RECOGNIZED_CAUSES = {} 783 784 @staticmethod 785 def register_cause_code(*args): 786 def _register_cause_code(cls): 787 chunk_abort._RECOGNIZED_CAUSES[cls.cause_code()] = cls 788 return cls 789 return _register_cause_code(args[0]) 790 791 @classmethod 792 def chunk_type(cls): 793 return TYPE_ABORT 794 795 def __init__(self, tflag=0, length=0, causes=None): 796 super(chunk_abort, self).__init__(self.chunk_type(), length) 797 assert (1 == tflag | 1) 798 self.tflag = tflag 799 causes = causes or [] 800 assert isinstance(causes, list) 801 for one in causes: 802 assert isinstance(one, cause) 803 self.causes = causes 804 805 @classmethod 806 def parser(cls, buf): 807 (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) 808 tflag = (flags >> 0) & 1 809 causes = [] 810 offset = cls._MIN_LEN 811 while offset < length: 812 (ccode, ) = struct.unpack_from('!H', buf, offset) 813 cls_ = cls._RECOGNIZED_CAUSES.get(ccode) 814 if not cls_: 815 break 816 ins = cls_.parser(buf[offset:]) 817 causes.append(ins) 818 offset += len(ins) 819 return cls(tflag, length, causes) 820 821 def serialize(self): 822 flags = (self.tflag << 0) 823 buf = bytearray(struct.pack( 824 self._PACK_STR, self.chunk_type(), flags, self.length)) 825 for one in self.causes: 826 buf.extend(one.serialize()) 827 if 0 == self.length: 828 self.length = len(buf) 829 struct.pack_into('!H', buf, 2, self.length) 830 return six.binary_type(buf) 831 832 833@sctp.register_chunk_type 834class chunk_shutdown(chunk): 835 """Stream Control Transmission Protocol (SCTP) 836 sub encoder/decoder class for Shutdown Association (SHUTDOWN) chunk 837 (RFC 4960). 838 839 This class is used with the following. 840 841 - ryu.lib.packet.sctp.sctp 842 843 An instance has the following attributes at least. 844 Most of them are same to the on-wire counterparts but in host byte order. 845 __init__ takes the corresponding args in this order. 846 847 .. tabularcolumns:: |l|L| 848 849 ============== ===================================================== 850 Attribute Description 851 ============== ===================================================== 852 flags set to '0'. this field will be ignored. 853 length length of this chunk containing this header. 854 (0 means automatically-calculate when encoding) 855 tsn_ack TSN of the last DATA chunk received in sequence 856 before a gap. 857 ============== ===================================================== 858 """ 859 860 _PACK_STR = '!BBHI' 861 _MIN_LEN = struct.calcsize(_PACK_STR) 862 863 @classmethod 864 def chunk_type(cls): 865 return TYPE_SHUTDOWN 866 867 def __init__(self, flags=0, length=0, tsn_ack=0): 868 super(chunk_shutdown, self).__init__(self.chunk_type(), length) 869 self.flags = flags 870 self.tsn_ack = tsn_ack 871 872 @classmethod 873 def parser(cls, buf): 874 (_, flags, length, tsn_ack 875 ) = struct.unpack_from(cls._PACK_STR, buf) 876 msg = cls(flags, length, tsn_ack) 877 return msg 878 879 def serialize(self): 880 if 0 == self.length: 881 self.length = self._MIN_LEN 882 buf = struct.pack( 883 self._PACK_STR, self.chunk_type(), self.flags, 884 self.length, self.tsn_ack) 885 return buf 886 887 888@sctp.register_chunk_type 889class chunk_shutdown_ack(chunk_ack_base): 890 """Stream Control Transmission Protocol (SCTP) 891 sub encoder/decoder class for Shutdown Acknowledgement (SHUTDOWN ACK) 892 chunk (RFC 4960). 893 894 This class is used with the following. 895 896 - ryu.lib.packet.sctp.sctp 897 898 An instance has the following attributes at least. 899 Most of them are same to the on-wire counterparts but in host byte order. 900 __init__ takes the corresponding args in this order. 901 902 .. tabularcolumns:: |l|L| 903 904 ============== ===================================================== 905 Attribute Description 906 ============== ===================================================== 907 flags set to '0'. this field will be ignored. 908 length length of this chunk containing this header. 909 (0 means automatically-calculate when encoding) 910 ============== ===================================================== 911 """ 912 913 @classmethod 914 def chunk_type(cls): 915 return TYPE_SHUTDOWN_ACK 916 917 918@sctp.register_chunk_type 919class chunk_error(chunk): 920 """Stream Control Transmission Protocol (SCTP) 921 sub encoder/decoder class for Operation Error (ERROR) chunk (RFC 4960). 922 923 This class is used with the following. 924 925 - ryu.lib.packet.sctp.sctp 926 927 An instance has the following attributes at least. 928 Most of them are same to the on-wire counterparts but in host byte order. 929 __init__ takes the corresponding args in this order. 930 931 .. tabularcolumns:: |l|L| 932 933 ============== ===================================================== 934 Attribute Description 935 ============== ===================================================== 936 flags set to '0'. this field will be ignored. 937 length length of this chunk containing this header. 938 (0 means automatically-calculate when encoding) 939 causes a list of derived classes of ryu.lib.packet.sctp.causes. 940 ============== ===================================================== 941 """ 942 943 _class_prefixes = ['cause_'] 944 _RECOGNIZED_CAUSES = {} 945 946 @staticmethod 947 def register_cause_code(*args): 948 def _register_cause_code(cls): 949 chunk_error._RECOGNIZED_CAUSES[cls.cause_code()] = cls 950 return cls 951 return _register_cause_code(args[0]) 952 953 @classmethod 954 def chunk_type(cls): 955 return TYPE_ERROR 956 957 def __init__(self, flags=0, length=0, causes=None): 958 super(chunk_error, self).__init__(self.chunk_type(), length) 959 self.flags = flags 960 causes = causes or [] 961 assert isinstance(causes, list) 962 for one in causes: 963 assert isinstance(one, cause) 964 self.causes = causes 965 966 @classmethod 967 def parser(cls, buf): 968 (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) 969 causes = [] 970 offset = cls._MIN_LEN 971 while offset < length: 972 (ccode, ) = struct.unpack_from('!H', buf, offset) 973 cls_ = cls._RECOGNIZED_CAUSES.get(ccode) 974 if not cls_: 975 break 976 ins = cls_.parser(buf[offset:]) 977 causes.append(ins) 978 offset += len(ins) 979 return cls(flags, length, causes) 980 981 def serialize(self): 982 buf = bytearray(struct.pack( 983 self._PACK_STR, self.chunk_type(), self.flags, self.length)) 984 for one in self.causes: 985 buf.extend(one.serialize()) 986 if 0 == self.length: 987 self.length = len(buf) 988 struct.pack_into('!H', buf, 2, self.length) 989 return six.binary_type(buf) 990 991 992@sctp.register_chunk_type 993class chunk_cookie_echo(chunk): 994 """Stream Control Transmission Protocol (SCTP) 995 sub encoder/decoder class for Cookie Echo (COOKIE ECHO) chunk (RFC 4960). 996 997 This class is used with the following. 998 999 - ryu.lib.packet.sctp.sctp 1000 1001 An instance has the following attributes at least. 1002 Most of them are same to the on-wire counterparts but in host byte order. 1003 __init__ takes the corresponding args in this order. 1004 1005 .. tabularcolumns:: |l|L| 1006 1007 ============== ===================================================== 1008 Attribute Description 1009 ============== ===================================================== 1010 flags set to '0'. this field will be ignored. 1011 length length of this chunk containing this header. 1012 (0 means automatically-calculate when encoding) 1013 cookie cookie data. 1014 ============== ===================================================== 1015 """ 1016 1017 _PACK_STR = '!BBH' 1018 _MIN_LEN = struct.calcsize(_PACK_STR) 1019 1020 @classmethod 1021 def chunk_type(cls): 1022 return TYPE_COOKIE_ECHO 1023 1024 def __init__(self, flags=0, length=0, cookie=None): 1025 super(chunk_cookie_echo, self).__init__(self.chunk_type(), length) 1026 self.flags = flags 1027 self.cookie = cookie 1028 1029 @classmethod 1030 def parser(cls, buf): 1031 (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) 1032 _len = length - cls._MIN_LEN 1033 cookie = None 1034 if _len: 1035 fmt = '%ds' % _len 1036 (cookie, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) 1037 return cls(flags, length, cookie) 1038 1039 def serialize(self): 1040 buf = bytearray(struct.pack( 1041 self._PACK_STR, self.chunk_type(), self.flags, 1042 self.length)) 1043 if self.cookie is not None: 1044 buf.extend(self.cookie) 1045 if 0 == self.length: 1046 self.length = len(buf) 1047 struct.pack_into('!H', buf, 2, self.length) 1048 mod = len(buf) % 4 1049 if mod: 1050 buf.extend(bytearray(4 - mod)) 1051 return six.binary_type(buf) 1052 1053 1054@sctp.register_chunk_type 1055class chunk_cookie_ack(chunk_ack_base): 1056 """Stream Control Transmission Protocol (SCTP) 1057 sub encoder/decoder class for Cookie Acknowledgement (COOKIE ACK) 1058 chunk (RFC 4960). 1059 1060 This class is used with the following. 1061 1062 - ryu.lib.packet.sctp.sctp 1063 1064 An instance has the following attributes at least. 1065 Most of them are same to the on-wire counterparts but in host byte order. 1066 __init__ takes the corresponding args in this order. 1067 1068 .. tabularcolumns:: |l|L| 1069 1070 ============== ===================================================== 1071 Attribute Description 1072 ============== ===================================================== 1073 flags set to '0'. this field will be ignored. 1074 length length of this chunk containing this header. 1075 (0 means automatically-calculate when encoding) 1076 ============== ===================================================== 1077 """ 1078 1079 @classmethod 1080 def chunk_type(cls): 1081 return TYPE_COOKIE_ACK 1082 1083 1084@sctp.register_chunk_type 1085class chunk_ecn_echo(chunk_ecn_base): 1086 """Stream Control Transmission Protocol (SCTP) 1087 sub encoder/decoder class for ECN-Echo chunk (RFC 4960 Appendix A.). 1088 1089 This class is used with the following. 1090 1091 - ryu.lib.packet.sctp.sctp 1092 1093 An instance has the following attributes at least. 1094 Most of them are same to the on-wire counterparts but in host byte order. 1095 __init__ takes the corresponding args in this order. 1096 1097 .. tabularcolumns:: |l|L| 1098 1099 ============== ===================================================== 1100 Attribute Description 1101 ============== ===================================================== 1102 flags set to '0'. this field will be ignored. 1103 length length of this chunk containing this header. 1104 (0 means automatically-calculate when encoding) 1105 low_tsn the lowest TSN. 1106 ============== ===================================================== 1107 """ 1108 1109 @classmethod 1110 def chunk_type(cls): 1111 return TYPE_ECN_ECHO 1112 1113 1114@sctp.register_chunk_type 1115class chunk_cwr(chunk_ecn_base): 1116 """Stream Control Transmission Protocol (SCTP) 1117 sub encoder/decoder class for CWR chunk (RFC 4960 Appendix A.). 1118 1119 This class is used with the following. 1120 1121 - ryu.lib.packet.sctp.sctp 1122 1123 An instance has the following attributes at least. 1124 Most of them are same to the on-wire counterparts but in host byte order. 1125 __init__ takes the corresponding args in this order. 1126 1127 .. tabularcolumns:: |l|L| 1128 1129 ============== ===================================================== 1130 Attribute Description 1131 ============== ===================================================== 1132 flags set to '0'. this field will be ignored. 1133 length length of this chunk containing this header. 1134 (0 means automatically-calculate when encoding) 1135 low_tsn the lowest TSN. 1136 ============== ===================================================== 1137 """ 1138 1139 @classmethod 1140 def chunk_type(cls): 1141 return TYPE_CWR 1142 1143 1144@sctp.register_chunk_type 1145class chunk_shutdown_complete(chunk): 1146 """Stream Control Transmission Protocol (SCTP) 1147 sub encoder/decoder class for Shutdown Complete (SHUTDOWN COMPLETE) 1148 chunk (RFC 4960). 1149 1150 This class is used with the following. 1151 1152 - ryu.lib.packet.sctp.sctp 1153 1154 An instance has the following attributes at least. 1155 Most of them are same to the on-wire counterparts but in host byte order. 1156 __init__ takes the corresponding args in this order. 1157 1158 .. tabularcolumns:: |l|L| 1159 1160 ============== ===================================================== 1161 Attribute Description 1162 ============== ===================================================== 1163 tflag '0' means the Verification tag is normal. '1' means 1164 the Verification tag is copy of the sender. 1165 length length of this chunk containing this header. 1166 (0 means automatically-calculate when encoding) 1167 ============== ===================================================== 1168 """ 1169 1170 _PACK_STR = '!BBH' 1171 _MIN_LEN = struct.calcsize(_PACK_STR) 1172 1173 @classmethod 1174 def chunk_type(cls): 1175 return TYPE_SHUTDOWN_COMPLETE 1176 1177 def __init__(self, tflag=0, length=0): 1178 assert (1 == tflag | 1) 1179 super(chunk_shutdown_complete, self).__init__( 1180 self.chunk_type(), length) 1181 self.tflag = tflag 1182 1183 @classmethod 1184 def parser(cls, buf): 1185 (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) 1186 tflag = flags & 1 1187 msg = cls(tflag, length) 1188 return msg 1189 1190 def serialize(self): 1191 if 0 == self.length: 1192 self.length = self._MIN_LEN 1193 buf = struct.pack( 1194 self._PACK_STR, self.chunk_type(), 1195 self.tflag, self.length) 1196 return buf 1197 1198 1199# ======================================================================= 1200# 1201# Cause Code 1202# 1203# ======================================================================= 1204@six.add_metaclass(abc.ABCMeta) 1205class cause(stringify.StringifyMixin): 1206 _PACK_STR = '!HH' 1207 _MIN_LEN = struct.calcsize(_PACK_STR) 1208 1209 @classmethod 1210 @abc.abstractmethod 1211 def cause_code(cls): 1212 pass 1213 1214 def __init__(self, length=0): 1215 self.length = length 1216 1217 @classmethod 1218 @abc.abstractmethod 1219 def parser(cls, buf): 1220 pass 1221 1222 def serialize(self): 1223 if 0 == self.length: 1224 self.length = self._MIN_LEN 1225 buf = struct.pack( 1226 self._PACK_STR, self.cause_code(), self.length) 1227 return buf 1228 1229 def __len__(self): 1230 length = self.length 1231 mod = length % 4 1232 if mod: 1233 length += 4 - mod 1234 return length 1235 1236 1237@six.add_metaclass(abc.ABCMeta) 1238class cause_with_value(cause): 1239 def __init__(self, value=None, length=0): 1240 super(cause_with_value, self).__init__(length) 1241 self.value = value 1242 1243 @classmethod 1244 def parser(cls, buf): 1245 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 1246 value = None 1247 if (cls._MIN_LEN < length): 1248 fmt = '%ds' % (length - cls._MIN_LEN) 1249 (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) 1250 return cls(value, length) 1251 1252 def serialize(self): 1253 buf = bytearray(struct.pack( 1254 self._PACK_STR, self.cause_code(), self.length)) 1255 if self.value is not None: 1256 buf.extend(self.value) 1257 if 0 == self.length: 1258 self.length = len(buf) 1259 struct.pack_into('!H', buf, 2, self.length) 1260 mod = len(buf) % 4 1261 if mod: 1262 buf.extend(bytearray(4 - mod)) 1263 return six.binary_type(buf) 1264 1265 1266@chunk_abort.register_cause_code 1267@chunk_error.register_cause_code 1268class cause_invalid_stream_id(cause_with_value): 1269 """Stream Control Transmission Protocol (SCTP) 1270 sub encoder/decoder class for Invalid Stream Identifier (RFC 4960). 1271 1272 This class is used with the following. 1273 1274 - ryu.lib.packet.sctp.chunk_abort 1275 - ryu.lib.packet.sctp.chunk_error 1276 1277 An instance has the following attributes at least. 1278 Most of them are same to the on-wire counterparts but in host byte order. 1279 __init__ takes the corresponding args in this order. 1280 1281 .. tabularcolumns:: |l|L| 1282 1283 ============== ===================================================== 1284 Attribute Description 1285 ============== ===================================================== 1286 value stream id. 1287 length length of this cause containing this header. 1288 (0 means automatically-calculate when encoding) 1289 ============== ===================================================== 1290 """ 1291 1292 _PACK_STR = '!HHH2x' 1293 _MIN_LEN = struct.calcsize(_PACK_STR) 1294 1295 @classmethod 1296 def cause_code(cls): 1297 return CCODE_INVALID_STREAM_ID 1298 1299 def __init__(self, value=0, length=0): 1300 super(cause_invalid_stream_id, self).__init__(value, length) 1301 1302 @classmethod 1303 def parser(cls, buf): 1304 (_, length, value) = struct.unpack_from(cls._PACK_STR, buf) 1305 return cls(value, length) 1306 1307 def serialize(self): 1308 if 0 == self.length: 1309 self.length = self._MIN_LEN 1310 buf = struct.pack( 1311 self._PACK_STR, self.cause_code(), self.length, self.value) 1312 return buf 1313 1314 1315@chunk_abort.register_cause_code 1316@chunk_error.register_cause_code 1317class cause_missing_param(cause): 1318 """Stream Control Transmission Protocol (SCTP) 1319 sub encoder/decoder class for Missing Mandatory Parameter (RFC 4960). 1320 1321 This class is used with the following. 1322 1323 - ryu.lib.packet.sctp.chunk_abort 1324 - ryu.lib.packet.sctp.chunk_error 1325 1326 An instance has the following attributes at least. 1327 Most of them are same to the on-wire counterparts but in host byte order. 1328 __init__ takes the corresponding args in this order. 1329 1330 .. tabularcolumns:: |l|L| 1331 1332 ============== ===================================================== 1333 Attribute Description 1334 ============== ===================================================== 1335 types a list of missing params. 1336 num Number of missing params. 1337 (0 means automatically-calculate when encoding) 1338 length length of this cause containing this header. 1339 (0 means automatically-calculate when encoding) 1340 ============== ===================================================== 1341 """ 1342 1343 _PACK_STR = '!HHI' 1344 _MIN_LEN = struct.calcsize(_PACK_STR) 1345 1346 @classmethod 1347 def cause_code(cls): 1348 return CCODE_MISSING_PARAM 1349 1350 def __init__(self, types=None, num=0, length=0): 1351 super(cause_missing_param, self).__init__(length) 1352 types = types or [] 1353 assert isinstance(types, list) 1354 for one in types: 1355 assert isinstance(one, int) 1356 self.types = types 1357 self.num = num 1358 1359 @classmethod 1360 def parser(cls, buf): 1361 (_, length, num) = struct.unpack_from(cls._PACK_STR, buf) 1362 types = [] 1363 offset = cls._MIN_LEN 1364 for count in range(num): 1365 offset = cls._MIN_LEN + (struct.calcsize('!H') * count) 1366 (one, ) = struct.unpack_from('!H', buf, offset) 1367 types.append(one) 1368 return cls(types, num, length) 1369 1370 def serialize(self): 1371 buf = bytearray(struct.pack( 1372 self._PACK_STR, self.cause_code(), self.length, self.num)) 1373 for one in self.types: 1374 buf.extend(struct.pack('!H', one)) 1375 if 0 == self.num: 1376 self.num = len(self.types) 1377 struct.pack_into('!I', buf, 4, self.num) 1378 if 0 == self.length: 1379 self.length = len(buf) 1380 struct.pack_into('!H', buf, 2, self.length) 1381 mod = len(buf) % 4 1382 if mod: 1383 buf.extend(bytearray(4 - mod)) 1384 return six.binary_type(buf) 1385 1386 1387@chunk_abort.register_cause_code 1388@chunk_error.register_cause_code 1389class cause_stale_cookie(cause_with_value): 1390 """Stream Control Transmission Protocol (SCTP) 1391 sub encoder/decoder class for Stale Cookie Error (RFC 4960). 1392 1393 This class is used with the following. 1394 1395 - ryu.lib.packet.sctp.chunk_abort 1396 - ryu.lib.packet.sctp.chunk_error 1397 1398 An instance has the following attributes at least. 1399 Most of them are same to the on-wire counterparts but in host byte order. 1400 __init__ takes the corresponding args in this order. 1401 1402 .. tabularcolumns:: |l|L| 1403 1404 ============== ===================================================== 1405 Attribute Description 1406 ============== ===================================================== 1407 value Measure of Staleness. 1408 length length of this cause containing this header. 1409 (0 means automatically-calculate when encoding) 1410 ============== ===================================================== 1411 """ 1412 1413 @classmethod 1414 def cause_code(cls): 1415 return CCODE_STALE_COOKIE 1416 1417 1418@chunk_abort.register_cause_code 1419@chunk_error.register_cause_code 1420class cause_out_of_resource(cause): 1421 """Stream Control Transmission Protocol (SCTP) 1422 sub encoder/decoder class for Out of Resource (RFC 4960). 1423 1424 This class is used with the following. 1425 1426 - ryu.lib.packet.sctp.chunk_abort 1427 - ryu.lib.packet.sctp.chunk_error 1428 1429 An instance has the following attributes at least. 1430 Most of them are same to the on-wire counterparts but in host byte order. 1431 __init__ takes the corresponding args in this order. 1432 1433 .. tabularcolumns:: |l|L| 1434 1435 ============== ===================================================== 1436 Attribute Description 1437 ============== ===================================================== 1438 length length of this cause containing this header. 1439 (0 means automatically-calculate when encoding) 1440 ============== ===================================================== 1441 """ 1442 1443 @classmethod 1444 def cause_code(cls): 1445 return CCODE_OUT_OF_RESOURCE 1446 1447 @classmethod 1448 def parser(cls, buf): 1449 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 1450 return cls(length) 1451 1452 1453@chunk_abort.register_cause_code 1454@chunk_error.register_cause_code 1455class cause_unresolvable_addr(cause_with_value): 1456 """Stream Control Transmission Protocol (SCTP) 1457 sub encoder/decoder class for Unresolvable Address (RFC 4960). 1458 1459 This class is used with the following. 1460 1461 - ryu.lib.packet.sctp.chunk_abort 1462 - ryu.lib.packet.sctp.chunk_error 1463 1464 An instance has the following attributes at least. 1465 Most of them are same to the on-wire counterparts but in host byte order. 1466 __init__ takes the corresponding args in this order. 1467 1468 .. tabularcolumns:: |l|L| 1469 1470 ============== ===================================================== 1471 Attribute Description 1472 ============== ===================================================== 1473 value Unresolvable Address. one of follows: 1474 1475 ryu.lib.packet.sctp.param_host_addr, 1476 1477 ryu.lib.packet.sctp.param_ipv4, or 1478 1479 ryu.lib.packet.sctp.param_ipv6. 1480 length length of this cause containing this header. 1481 (0 means automatically-calculate when encoding) 1482 ============== ===================================================== 1483 """ 1484 1485 _class_prefixes = ['param_'] 1486 _RECOGNIZED_PARAMS = {} 1487 1488 @staticmethod 1489 def register_param_type(*args): 1490 def _register_param_type(cls): 1491 cause_unresolvable_addr._RECOGNIZED_PARAMS[cls.param_type()] = cls 1492 return cls 1493 return _register_param_type(args[0]) 1494 1495 @classmethod 1496 def cause_code(cls): 1497 return CCODE_UNRESOLVABLE_ADDR 1498 1499 @classmethod 1500 def parser(cls, buf): 1501 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 1502 (ptype, ) = struct.unpack_from('!H', buf, cls._MIN_LEN) 1503 cls_ = cls._RECOGNIZED_PARAMS.get(ptype) 1504 value = cls_.parser(buf[cls._MIN_LEN:]) 1505 return cls(value, length) 1506 1507 def serialize(self): 1508 buf = bytearray(struct.pack( 1509 self._PACK_STR, self.cause_code(), self.length)) 1510 buf.extend(self.value.serialize()) 1511 if 0 == self.length: 1512 self.length = len(buf) 1513 struct.pack_into('!H', buf, 2, self.length) 1514 mod = len(buf) % 4 1515 if mod: 1516 buf.extend(bytearray(4 - mod)) 1517 return six.binary_type(buf) 1518 1519 1520@chunk_abort.register_cause_code 1521@chunk_error.register_cause_code 1522class cause_unrecognized_chunk(cause_with_value): 1523 """Stream Control Transmission Protocol (SCTP) 1524 sub encoder/decoder class for Unrecognized Chunk Type (RFC 4960). 1525 1526 This class is used with the following. 1527 1528 - ryu.lib.packet.sctp.chunk_abort 1529 - ryu.lib.packet.sctp.chunk_error 1530 1531 An instance has the following attributes at least. 1532 Most of them are same to the on-wire counterparts but in host byte order. 1533 __init__ takes the corresponding args in this order. 1534 1535 .. tabularcolumns:: |l|L| 1536 1537 ============== ===================================================== 1538 Attribute Description 1539 ============== ===================================================== 1540 value Unrecognized Chunk. 1541 length length of this cause containing this header. 1542 (0 means automatically-calculate when encoding) 1543 ============== ===================================================== 1544 """ 1545 1546 @classmethod 1547 def cause_code(cls): 1548 return CCODE_UNRECOGNIZED_CHUNK 1549 1550 1551@chunk_abort.register_cause_code 1552@chunk_error.register_cause_code 1553class cause_invalid_param(cause): 1554 """Stream Control Transmission Protocol (SCTP) 1555 sub encoder/decoder class for Invalid Mandatory Parameter (RFC 4960). 1556 1557 This class is used with the following. 1558 1559 - ryu.lib.packet.sctp.chunk_abort 1560 - ryu.lib.packet.sctp.chunk_error 1561 1562 An instance has the following attributes at least. 1563 Most of them are same to the on-wire counterparts but in host byte order. 1564 __init__ takes the corresponding args in this order. 1565 1566 .. tabularcolumns:: |l|L| 1567 1568 ============== ===================================================== 1569 Attribute Description 1570 ============== ===================================================== 1571 length length of this cause containing this header. 1572 (0 means automatically-calculate when encoding) 1573 ============== ===================================================== 1574 """ 1575 1576 @classmethod 1577 def cause_code(cls): 1578 return CCODE_INVALID_PARAM 1579 1580 @classmethod 1581 def parser(cls, buf): 1582 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 1583 return cls(length) 1584 1585 1586@chunk_abort.register_cause_code 1587@chunk_error.register_cause_code 1588class cause_unrecognized_param(cause_with_value): 1589 """Stream Control Transmission Protocol (SCTP) 1590 sub encoder/decoder class for Unrecognized Parameters (RFC 4960). 1591 1592 This class is used with the following. 1593 1594 - ryu.lib.packet.sctp.chunk_abort 1595 - ryu.lib.packet.sctp.chunk_error 1596 1597 An instance has the following attributes at least. 1598 Most of them are same to the on-wire counterparts but in host byte order. 1599 __init__ takes the corresponding args in this order. 1600 1601 .. tabularcolumns:: |l|L| 1602 1603 ============== ===================================================== 1604 Attribute Description 1605 ============== ===================================================== 1606 value Unrecognized Parameter. 1607 length length of this cause containing this header. 1608 (0 means automatically-calculate when encoding) 1609 ============== ===================================================== 1610 """ 1611 1612 @classmethod 1613 def cause_code(cls): 1614 return CCODE_UNRECOGNIZED_PARAM 1615 1616 1617@chunk_abort.register_cause_code 1618@chunk_error.register_cause_code 1619class cause_no_userdata(cause_with_value): 1620 """Stream Control Transmission Protocol (SCTP) 1621 sub encoder/decoder class for No User Data (RFC 4960). 1622 1623 This class is used with the following. 1624 1625 - ryu.lib.packet.sctp.chunk_abort 1626 - ryu.lib.packet.sctp.chunk_error 1627 1628 An instance has the following attributes at least. 1629 Most of them are same to the on-wire counterparts but in host byte order. 1630 __init__ takes the corresponding args in this order. 1631 1632 .. tabularcolumns:: |l|L| 1633 1634 ============== ===================================================== 1635 Attribute Description 1636 ============== ===================================================== 1637 value the TSN of the DATA chunk received with no user data 1638 field. 1639 length length of this cause containing this header. 1640 (0 means automatically-calculate when encoding) 1641 ============== ===================================================== 1642 """ 1643 1644 @classmethod 1645 def cause_code(cls): 1646 return CCODE_NO_USERDATA 1647 1648 1649@chunk_abort.register_cause_code 1650@chunk_error.register_cause_code 1651class cause_cookie_while_shutdown(cause): 1652 """Stream Control Transmission Protocol (SCTP) 1653 sub encoder/decoder class for Cookie Received While Shutting Down 1654 (RFC 4960). 1655 1656 This class is used with the following. 1657 1658 - ryu.lib.packet.sctp.chunk_abort 1659 - ryu.lib.packet.sctp.chunk_error 1660 1661 An instance has the following attributes at least. 1662 Most of them are same to the on-wire counterparts but in host byte order. 1663 __init__ takes the corresponding args in this order. 1664 1665 .. tabularcolumns:: |l|L| 1666 1667 ============== ===================================================== 1668 Attribute Description 1669 ============== ===================================================== 1670 length length of this cause containing this header. 1671 (0 means automatically-calculate when encoding) 1672 ============== ===================================================== 1673 """ 1674 1675 @classmethod 1676 def cause_code(cls): 1677 return CCODE_COOKIE_WHILE_SHUTDOWN 1678 1679 @classmethod 1680 def parser(cls, buf): 1681 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 1682 return cls(length) 1683 1684 1685@chunk_abort.register_cause_code 1686@chunk_error.register_cause_code 1687class cause_restart_with_new_addr(cause_with_value): 1688 """Stream Control Transmission Protocol (SCTP) 1689 sub encoder/decoder class for Restart of an Association with New 1690 Addresses (RFC 4960). 1691 1692 This class is used with the following. 1693 1694 - ryu.lib.packet.sctp.chunk_abort 1695 - ryu.lib.packet.sctp.chunk_error 1696 1697 An instance has the following attributes at least. 1698 Most of them are same to the on-wire counterparts but in host byte order. 1699 __init__ takes the corresponding args in this order. 1700 1701 .. tabularcolumns:: |l|L| 1702 1703 ============== ===================================================== 1704 Attribute Description 1705 ============== ===================================================== 1706 value New Address TLVs. 1707 length length of this cause containing this header. 1708 (0 means automatically-calculate when encoding) 1709 ============== ===================================================== 1710 """ 1711 1712 _class_prefixes = ['param_'] 1713 _RECOGNIZED_PARAMS = {} 1714 1715 @staticmethod 1716 def register_param_type(*args): 1717 def _register_param_type(cls): 1718 cause_restart_with_new_addr._RECOGNIZED_PARAMS[ 1719 cls.param_type()] = cls 1720 return cls 1721 return _register_param_type(args[0]) 1722 1723 @classmethod 1724 def cause_code(cls): 1725 return CCODE_RESTART_WITH_NEW_ADDR 1726 1727 def __init__(self, value=None, length=0): 1728 if not isinstance(value, list): 1729 value = [value] 1730 super(cause_restart_with_new_addr, self).__init__(value, length) 1731 1732 @classmethod 1733 def parser(cls, buf): 1734 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 1735 value = [] 1736 offset = cls._MIN_LEN 1737 while offset < length: 1738 (ptype, ) = struct.unpack_from('!H', buf, offset) 1739 cls_ = cls._RECOGNIZED_PARAMS.get(ptype) 1740 if not cls_: 1741 break 1742 ins = cls_.parser(buf[offset:]) 1743 value.append(ins) 1744 offset += len(ins) 1745 return cls(value, length) 1746 1747 def serialize(self): 1748 buf = bytearray(struct.pack( 1749 self._PACK_STR, self.cause_code(), self.length)) 1750 for one in self.value: 1751 buf.extend(one.serialize()) 1752 if 0 == self.length: 1753 self.length = len(buf) 1754 struct.pack_into('!H', buf, 2, self.length) 1755 mod = len(buf) % 4 1756 if mod: 1757 buf.extend(bytearray(4 - mod)) 1758 return six.binary_type(buf) 1759 1760 1761@chunk_abort.register_cause_code 1762@chunk_error.register_cause_code 1763class cause_user_initiated_abort(cause_with_value): 1764 """Stream Control Transmission Protocol (SCTP) 1765 sub encoder/decoder class for User-Initiated Abort (RFC 4960). 1766 1767 This class is used with the following. 1768 1769 - ryu.lib.packet.sctp.chunk_abort 1770 - ryu.lib.packet.sctp.chunk_error 1771 1772 An instance has the following attributes at least. 1773 Most of them are same to the on-wire counterparts but in host byte order. 1774 __init__ takes the corresponding args in this order. 1775 1776 .. tabularcolumns:: |l|L| 1777 1778 ============== ===================================================== 1779 Attribute Description 1780 ============== ===================================================== 1781 value Upper Layer Abort Reason. 1782 length length of this cause containing this header. 1783 (0 means automatically-calculate when encoding) 1784 ============== ===================================================== 1785 """ 1786 1787 @classmethod 1788 def cause_code(cls): 1789 return CCODE_USER_INITIATED_ABORT 1790 1791 1792@chunk_abort.register_cause_code 1793@chunk_error.register_cause_code 1794class cause_protocol_violation(cause_with_value): 1795 """Stream Control Transmission Protocol (SCTP) 1796 sub encoder/decoder class for Protocol Violation (RFC 4960). 1797 1798 This class is used with the following. 1799 1800 - ryu.lib.packet.sctp.chunk_abort 1801 - ryu.lib.packet.sctp.chunk_error 1802 1803 An instance has the following attributes at least. 1804 Most of them are same to the on-wire counterparts but in host byte order. 1805 __init__ takes the corresponding args in this order. 1806 1807 .. tabularcolumns:: |l|L| 1808 1809 ============== ===================================================== 1810 Attribute Description 1811 ============== ===================================================== 1812 value Additional Information. 1813 length length of this cause containing this header. 1814 (0 means automatically-calculate when encoding) 1815 ============== ===================================================== 1816 """ 1817 1818 @classmethod 1819 def cause_code(cls): 1820 return CCODE_PROTOCOL_VIOLATION 1821 1822 1823# ======================================================================= 1824# 1825# Chunk Parameter Types 1826# 1827# ======================================================================= 1828@six.add_metaclass(abc.ABCMeta) 1829class param(stringify.StringifyMixin): 1830 _PACK_STR = '!HH' 1831 _MIN_LEN = struct.calcsize(_PACK_STR) 1832 1833 @classmethod 1834 @abc.abstractmethod 1835 def param_type(cls): 1836 pass 1837 1838 def __init__(self, value=None, length=0): 1839 self.length = length 1840 self.value = value 1841 1842 @classmethod 1843 def parser(cls, buf): 1844 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 1845 value = None 1846 if (cls._MIN_LEN < length): 1847 fmt = '%ds' % (length - cls._MIN_LEN) 1848 (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) 1849 return cls(value, length) 1850 1851 def serialize(self): 1852 buf = bytearray(struct.pack( 1853 self._PACK_STR, self.param_type(), self.length)) 1854 if self.value: 1855 buf.extend(self.value) 1856 if 0 == self.length: 1857 self.length = len(buf) 1858 struct.pack_into('!H', buf, 2, self.length) 1859 mod = len(buf) % 4 1860 if mod: 1861 buf.extend(bytearray(4 - mod)) 1862 return six.binary_type(buf) 1863 1864 def __len__(self): 1865 length = self.length 1866 mod = length % 4 1867 if mod: 1868 length += 4 - mod 1869 return length 1870 1871 1872@chunk_heartbeat.register_param_type 1873@chunk_heartbeat_ack.register_param_type 1874class param_heartbeat(param): 1875 """Stream Control Transmission Protocol (SCTP) 1876 sub encoder/decoder class for Heartbeat Info Parameter (RFC 4960). 1877 1878 This class is used with the following. 1879 1880 - ryu.lib.packet.sctp.chunk_heartbeat 1881 - ryu.lib.packet.sctp.chunk_heartbeat_ack 1882 1883 An instance has the following attributes at least. 1884 Most of them are same to the on-wire counterparts but in host byte order. 1885 __init__ takes the corresponding args in this order. 1886 1887 .. tabularcolumns:: |l|L| 1888 1889 ============== ===================================================== 1890 Attribute Description 1891 ============== ===================================================== 1892 value the sender-specific heartbeat information. 1893 length length of this param containing this header. 1894 (0 means automatically-calculate when encoding) 1895 ============== ===================================================== 1896 """ 1897 1898 @classmethod 1899 def param_type(cls): 1900 return PTYPE_HEARTBEAT 1901 1902 1903@chunk_init_ack.register_param_type 1904class param_state_cookie(param): 1905 """Stream Control Transmission Protocol (SCTP) 1906 sub encoder/decoder class for State Cookie Parameter (RFC 4960). 1907 1908 This class is used with the following. 1909 1910 - ryu.lib.packet.sctp.chunk_init_ack 1911 1912 An instance has the following attributes at least. 1913 Most of them are same to the on-wire counterparts but in host byte order. 1914 __init__ takes the corresponding args in this order. 1915 1916 .. tabularcolumns:: |l|L| 1917 1918 ============== ===================================================== 1919 Attribute Description 1920 ============== ===================================================== 1921 value the state cookie. see Section 5.1.3 in RFC 4960. 1922 length length of this param containing this header. 1923 (0 means automatically-calculate when encoding) 1924 ============== ===================================================== 1925 """ 1926 1927 @classmethod 1928 def param_type(cls): 1929 return PTYPE_STATE_COOKIE 1930 1931 1932@chunk_init_ack.register_param_type 1933class param_unrecognized_param(param): 1934 """Stream Control Transmission Protocol (SCTP) 1935 sub encoder/decoder class for Unrecognized Parameter (RFC 4960). 1936 1937 This class is used with the following. 1938 1939 - ryu.lib.packet.sctp.chunk_init_ack 1940 1941 An instance has the following attributes at least. 1942 Most of them are same to the on-wire counterparts but in host byte order. 1943 __init__ takes the corresponding args in this order. 1944 1945 .. tabularcolumns:: |l|L| 1946 1947 ============== ===================================================== 1948 Attribute Description 1949 ============== ===================================================== 1950 value the unrecognized parameter in the INIT chunk. 1951 length length of this param containing this header. 1952 (0 means automatically-calculate when encoding) 1953 ============== ===================================================== 1954 """ 1955 1956 @classmethod 1957 def param_type(cls): 1958 return PTYPE_UNRECOGNIZED_PARAM 1959 1960 1961@chunk_init.register_param_type 1962class param_cookie_preserve(param): 1963 """Stream Control Transmission Protocol (SCTP) 1964 sub encoder/decoder class for Cookie Preservative Parameter (RFC 4960). 1965 1966 This class is used with the following. 1967 1968 - ryu.lib.packet.sctp.chunk_init 1969 1970 An instance has the following attributes at least. 1971 Most of them are same to the on-wire counterparts but in host byte order. 1972 __init__ takes the corresponding args in this order. 1973 1974 .. tabularcolumns:: |l|L| 1975 1976 ============== ===================================================== 1977 Attribute Description 1978 ============== ===================================================== 1979 value Suggested Cookie Life-Span Increment (msec). 1980 length length of this param containing this header. 1981 (0 means automatically-calculate when encoding) 1982 ============== ===================================================== 1983 """ 1984 1985 _PACK_STR = '!HHI' 1986 _MIN_LEN = struct.calcsize(_PACK_STR) 1987 1988 @classmethod 1989 def param_type(cls): 1990 return PTYPE_COOKIE_PRESERVE 1991 1992 def __init__(self, value=0, length=0): 1993 super(param_cookie_preserve, self).__init__(value, length) 1994 1995 @classmethod 1996 def parser(cls, buf): 1997 (_, length, value) = struct.unpack_from(cls._PACK_STR, buf) 1998 return cls(value, length) 1999 2000 def serialize(self): 2001 if 0 == self.length: 2002 self.length = self._MIN_LEN 2003 buf = struct.pack( 2004 self._PACK_STR, self.param_type(), self.length, self.value) 2005 return buf 2006 2007 2008@chunk_init.register_param_type 2009@chunk_init_ack.register_param_type 2010class param_ecn(param): 2011 """Stream Control Transmission Protocol (SCTP) 2012 sub encoder/decoder class for ECN Parameter (RFC 4960 Appendix A.). 2013 2014 This class is used with the following. 2015 2016 - ryu.lib.packet.sctp.chunk_init 2017 - ryu.lib.packet.sctp.chunk_init_ack 2018 2019 An instance has the following attributes at least. 2020 Most of them are same to the on-wire counterparts but in host byte order. 2021 __init__ takes the corresponding args in this order. 2022 2023 .. tabularcolumns:: |l|L| 2024 2025 ============== ===================================================== 2026 Attribute Description 2027 ============== ===================================================== 2028 value set to None. 2029 length length of this param containing this header. 2030 (0 means automatically-calculate when encoding) 2031 ============== ===================================================== 2032 """ 2033 2034 @classmethod 2035 def param_type(cls): 2036 return PTYPE_ECN 2037 2038 def __init__(self, value=None, length=0): 2039 super(param_ecn, self).__init__(value, length) 2040 assert 4 == length or 0 == length 2041 assert None is value 2042 2043 2044@chunk_init.register_param_type 2045@chunk_init_ack.register_param_type 2046@cause_unresolvable_addr.register_param_type 2047@cause_restart_with_new_addr.register_param_type 2048class param_host_addr(param): 2049 """Stream Control Transmission Protocol (SCTP) 2050 sub encoder/decoder class for Host Name Address Parameter (RFC 4960). 2051 2052 This class is used with the following. 2053 2054 - ryu.lib.packet.sctp.chunk_init 2055 - ryu.lib.packet.sctp.chunk_init_ack 2056 2057 An instance has the following attributes at least. 2058 Most of them are same to the on-wire counterparts but in host byte order. 2059 __init__ takes the corresponding args in this order. 2060 2061 .. tabularcolumns:: |l|L| 2062 2063 ============== ===================================================== 2064 Attribute Description 2065 ============== ===================================================== 2066 value a host name that ends with null terminator. 2067 length length of this param containing this header. 2068 (0 means automatically-calculate when encoding) 2069 ============== ===================================================== 2070 """ 2071 2072 @classmethod 2073 def param_type(cls): 2074 return PTYPE_HOST_ADDR 2075 2076 2077@chunk_init.register_param_type 2078class param_supported_addr(param): 2079 """Stream Control Transmission Protocol (SCTP) 2080 sub encoder/decoder class for Supported Address Types Parameter (RFC 4960). 2081 2082 This class is used with the following. 2083 2084 - ryu.lib.packet.sctp.chunk_init 2085 2086 An instance has the following attributes at least. 2087 Most of them are same to the on-wire counterparts but in host byte order. 2088 __init__ takes the corresponding args in this order. 2089 2090 .. tabularcolumns:: |l|L| 2091 2092 ============== ===================================================== 2093 Attribute Description 2094 ============== ===================================================== 2095 value a list of parameter types. odd cases pad with 0x0000. 2096 length length of this param containing this header. 2097 (0 means automatically-calculate when encoding) 2098 ============== ===================================================== 2099 """ 2100 2101 _VALUE_STR = '!H' 2102 _VALUE_LEN = struct.calcsize(_VALUE_STR) 2103 2104 @classmethod 2105 def param_type(cls): 2106 return PTYPE_SUPPORTED_ADDR 2107 2108 def __init__(self, value=None, length=0): 2109 if not isinstance(value, list): 2110 value = [value] 2111 for one in value: 2112 assert isinstance(one, int) 2113 super(param_supported_addr, self).__init__(value, length) 2114 2115 @classmethod 2116 def parser(cls, buf): 2117 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 2118 value = [] 2119 offset = cls._MIN_LEN 2120 while offset < length: 2121 (one, ) = struct.unpack_from(cls._VALUE_STR, buf, offset) 2122 value.append(one) 2123 offset += cls._VALUE_LEN 2124 return cls(value, length) 2125 2126 def serialize(self): 2127 buf = bytearray(struct.pack( 2128 self._PACK_STR, self.param_type(), self.length)) 2129 for one in self.value: 2130 buf.extend(struct.pack(param_supported_addr._VALUE_STR, one)) 2131 if 0 == self.length: 2132 self.length = len(buf) 2133 struct.pack_into('!H', buf, 2, self.length) 2134 mod = len(buf) % 4 2135 if mod: 2136 buf.extend(bytearray(4 - mod)) 2137 return six.binary_type(buf) 2138 2139 2140@chunk_init.register_param_type 2141@chunk_init_ack.register_param_type 2142@cause_unresolvable_addr.register_param_type 2143@cause_restart_with_new_addr.register_param_type 2144class param_ipv4(param): 2145 """Stream Control Transmission Protocol (SCTP) 2146 sub encoder/decoder class for IPv4 Address Parameter (RFC 4960). 2147 2148 This class is used with the following. 2149 2150 - ryu.lib.packet.sctp.chunk_init 2151 - ryu.lib.packet.sctp.chunk_init_ack 2152 2153 An instance has the following attributes at least. 2154 Most of them are same to the on-wire counterparts but in host byte order. 2155 __init__ takes the corresponding args in this order. 2156 2157 .. tabularcolumns:: |l|L| 2158 2159 ============== ===================================================== 2160 Attribute Description 2161 ============== ===================================================== 2162 value IPv4 address of the sending endpoint. 2163 length length of this param containing this header. 2164 (0 means automatically-calculate when encoding) 2165 ============== ===================================================== 2166 """ 2167 2168 _TYPE = {'ascii': ['value']} 2169 2170 @classmethod 2171 def param_type(cls): 2172 return PTYPE_IPV4 2173 2174 def __init__(self, value='127.0.0.1', length=0): 2175 super(param_ipv4, self).__init__(value, length) 2176 2177 @classmethod 2178 def parser(cls, buf): 2179 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 2180 value = None 2181 if (cls._MIN_LEN < length): 2182 fmt = '%ds' % (length - cls._MIN_LEN) 2183 (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) 2184 return cls(addrconv.ipv4.bin_to_text(value), length) 2185 2186 def serialize(self): 2187 buf = bytearray(struct.pack( 2188 self._PACK_STR, self.param_type(), self.length)) 2189 if self.value: 2190 buf.extend(addrconv.ipv4.text_to_bin(self.value)) 2191 if 0 == self.length: 2192 self.length = len(buf) 2193 struct.pack_into('!H', buf, 2, self.length) 2194 return six.binary_type(buf) 2195 2196 2197@chunk_init.register_param_type 2198@chunk_init_ack.register_param_type 2199@cause_unresolvable_addr.register_param_type 2200@cause_restart_with_new_addr.register_param_type 2201class param_ipv6(param): 2202 """Stream Control Transmission Protocol (SCTP) 2203 sub encoder/decoder class for IPv6 Address Parameter (RFC 4960). 2204 2205 This class is used with the following. 2206 2207 - ryu.lib.packet.sctp.chunk_init 2208 - ryu.lib.packet.sctp.chunk_init_ack 2209 2210 An instance has the following attributes at least. 2211 Most of them are same to the on-wire counterparts but in host byte order. 2212 __init__ takes the corresponding args in this order. 2213 2214 .. tabularcolumns:: |l|L| 2215 2216 ============== ===================================================== 2217 Attribute Description 2218 ============== ===================================================== 2219 value IPv6 address of the sending endpoint. 2220 length length of this param containing this header. 2221 (0 means automatically-calculate when encoding) 2222 ============== ===================================================== 2223 """ 2224 2225 _TYPE = {'ascii': ['value']} 2226 2227 @classmethod 2228 def param_type(cls): 2229 return PTYPE_IPV6 2230 2231 def __init__(self, value='::1', length=0): 2232 super(param_ipv6, self).__init__(value, length) 2233 2234 @classmethod 2235 def parser(cls, buf): 2236 (_, length) = struct.unpack_from(cls._PACK_STR, buf) 2237 value = None 2238 if (cls._MIN_LEN < length): 2239 fmt = '%ds' % (length - cls._MIN_LEN) 2240 (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) 2241 return cls(addrconv.ipv6.bin_to_text(value), length) 2242 2243 def serialize(self): 2244 buf = bytearray(struct.pack( 2245 self._PACK_STR, self.param_type(), self.length)) 2246 if self.value: 2247 buf.extend(addrconv.ipv6.text_to_bin(self.value)) 2248 if 0 == self.length: 2249 self.length = len(buf) 2250 struct.pack_into('!H', buf, 2, self.length) 2251 return six.binary_type(buf) 2252