Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Impacket - Collection of Python classes for working with network protocols. 

2# 

3# SECUREAUTH LABS. Copyright (C) 2018 SecureAuth Corporation. All rights reserved. 

4# 

5# This software is provided under a slightly modified version 

6# of the Apache Software License. See the accompanying LICENSE file 

7# for more information. 

8# 

9# Description: 

10# Network packet codecs basic building blocks. 

11# Low-level packet codecs for various Internet protocols. 

12# 

13# Author: 

14# Javier Burroni (javier) 

15# Bruce Leidl (brl) 

16# Javier Kohen (jkohen) 

17# 

18 

19from __future__ import division 

20from __future__ import print_function 

21import array 

22import struct 

23import socket 

24import string 

25import sys 

26from binascii import hexlify 

27from functools import reduce 

28 

29# Alias function for compatibility with both Python <3.2 `tostring` and `fromstring` methods, and 

30# Python >=3.2 `tobytes` and `tostring` 

31if sys.version_info[0] >= 3 and sys.version_info[1] >= 2: 31 ↛ 32line 31 didn't jump to line 32, because the condition on line 31 was never true

32 array_tobytes = lambda array_object: array_object.tobytes() 

33 array_frombytes = lambda array_object, bytes: array_object.frombytes(bytes) 

34else: 

35 array_tobytes = lambda array_object: array_object.tostring() 

36 array_frombytes = lambda array_object, bytes: array_object.fromstring(bytes) 

37 

38 

39"""Classes to build network packets programmatically. 

40 

41Each protocol layer is represented by an object, and these objects are 

42hierarchically structured to form a packet. This list is traversable 

43in both directions: from parent to child and vice versa. 

44 

45All objects can be turned back into a raw buffer ready to be sent over 

46the wire (see method get_packet). 

47""" 

48 

49class ImpactPacketException(Exception): 

50 def __init__(self, value): 

51 self.value = value 

52 def __str__(self): 

53 return repr(self.value) 

54 

55class PacketBuffer(object): 

56 """Implement the basic operations utilized to operate on a 

57 packet's raw buffer. All the packet classes derive from this one. 

58 

59 The byte, word, long and ip_address getters and setters accept 

60 negative indexes, having these the a similar effect as in a 

61 regular Python sequence slice. 

62 """ 

63 

64 def __init__(self, length = None): 

65 "If 'length' is specified the buffer is created with an initial size" 

66 if length: 

67 self.__bytes = array.array('B', b'\0' * length) 

68 else: 

69 self.__bytes = array.array('B') 

70 

71 def set_bytes_from_string(self, data): 

72 "Sets the value of the packet buffer from the string 'data'" 

73 self.__bytes = array.array('B', data) 

74 

75 def get_buffer_as_string(self): 

76 "Returns the packet buffer as a string object" 

77 return array_tobytes(self.__bytes) 

78 

79 def get_bytes(self): 

80 "Returns the packet buffer as an array" 

81 return self.__bytes 

82 

83 def set_bytes(self, bytes): 

84 "Set the packet buffer from an array" 

85 # Make a copy to be safe 

86 self.__bytes = array.array('B', bytes.tolist()) 

87 

88 def set_byte(self, index, value): 

89 "Set byte at 'index' to 'value'" 

90 index = self.__validate_index(index, 1) 

91 self.__bytes[index] = value 

92 

93 def get_byte(self, index): 

94 "Return byte at 'index'" 

95 index = self.__validate_index(index, 1) 

96 return self.__bytes[index] 

97 

98 def set_word(self, index, value, order = '!'): 

99 "Set 2-byte word at 'index' to 'value'. See struct module's documentation to understand the meaning of 'order'." 

100 index = self.__validate_index(index, 2) 

101 ary = array.array("B", struct.pack(order + 'H', value)) 

102 if -2 == index: 102 ↛ 103line 102 didn't jump to line 103, because the condition on line 102 was never true

103 self.__bytes[index:] = ary 

104 else: 

105 self.__bytes[index:index+2] = ary 

106 

107 def get_word(self, index, order = '!'): 

108 "Return 2-byte word at 'index'. See struct module's documentation to understand the meaning of 'order'." 

109 index = self.__validate_index(index, 2) 

110 if -2 == index: 110 ↛ 111line 110 didn't jump to line 111, because the condition on line 110 was never true

111 bytes = self.__bytes[index:] 

112 else: 

113 bytes = self.__bytes[index:index+2] 

114 (value,) = struct.unpack(order + 'H', array_tobytes(bytes)) 

115 return value 

116 

117 def set_long(self, index, value, order = '!'): 

118 "Set 4-byte 'value' at 'index'. See struct module's documentation to understand the meaning of 'order'." 

119 index = self.__validate_index(index, 4) 

120 ary = array.array("B", struct.pack(order + 'L', value)) 

121 if -4 == index: 

122 self.__bytes[index:] = ary 

123 else: 

124 self.__bytes[index:index+4] = ary 

125 

126 def get_long(self, index, order = '!'): 

127 "Return 4-byte value at 'index'. See struct module's documentation to understand the meaning of 'order'." 

128 index = self.__validate_index(index, 4) 

129 if -4 == index: 

130 bytes = self.__bytes[index:] 

131 else: 

132 bytes = self.__bytes[index:index+4] 

133 (value,) = struct.unpack(order + 'L', array_tobytes(bytes)) 

134 return value 

135 

136 def set_long_long(self, index, value, order = '!'): 

137 "Set 8-byte 'value' at 'index'. See struct module's documentation to understand the meaning of 'order'." 

138 index = self.__validate_index(index, 8) 

139 ary = array.array("B", struct.pack(order + 'Q', value)) 

140 if -8 == index: 140 ↛ 141line 140 didn't jump to line 141, because the condition on line 140 was never true

141 self.__bytes[index:] = ary 

142 else: 

143 self.__bytes[index:index+8] = ary 

144 

145 def get_long_long(self, index, order = '!'): 

146 "Return 8-byte value at 'index'. See struct module's documentation to understand the meaning of 'order'." 

147 index = self.__validate_index(index, 8) 

148 if -8 == index: 148 ↛ 149line 148 didn't jump to line 149, because the condition on line 148 was never true

149 bytes = self.__bytes[index:] 

150 else: 

151 bytes = self.__bytes[index:index+8] 

152 (value,) = struct.unpack(order + 'Q', array_tobytes(bytes)) 

153 return value 

154 

155 

156 def get_ip_address(self, index): 

157 "Return 4-byte value at 'index' as an IP string" 

158 index = self.__validate_index(index, 4) 

159 if -4 == index: 159 ↛ 160line 159 didn't jump to line 160, because the condition on line 159 was never true

160 bytes = self.__bytes[index:] 

161 else: 

162 bytes = self.__bytes[index:index+4] 

163 return socket.inet_ntoa(array_tobytes(bytes)) 

164 

165 def set_ip_address(self, index, ip_string): 

166 "Set 4-byte value at 'index' from 'ip_string'" 

167 index = self.__validate_index(index, 4) 

168 raw = socket.inet_aton(ip_string) 

169 (b1,b2,b3,b4) = struct.unpack("BBBB", raw) 

170 self.set_byte(index, b1) 

171 self.set_byte(index + 1, b2) 

172 self.set_byte(index + 2, b3) 

173 self.set_byte(index + 3, b4) 

174 

175 def set_checksum_from_data(self, index, data): 

176 "Set 16-bit checksum at 'index' by calculating checksum of 'data'" 

177 self.set_word(index, self.compute_checksum(data)) 

178 

179 def compute_checksum(self, anArray): 

180 "Return the one's complement of the one's complement sum of all the 16-bit words in 'anArray'" 

181 nleft = len(anArray) 

182 sum = 0 

183 pos = 0 

184 while nleft > 1: 

185 sum = anArray[pos] * 256 + (anArray[pos + 1] + sum) 

186 pos = pos + 2 

187 nleft = nleft - 2 

188 if nleft == 1: 

189 sum = sum + anArray[pos] * 256 

190 return self.normalize_checksum(sum) 

191 

192 def normalize_checksum(self, aValue): 

193 sum = aValue 

194 sum = (sum >> 16) + (sum & 0xFFFF) 

195 sum += (sum >> 16) 

196 sum = (~sum & 0xFFFF) 

197 return sum 

198 

199 def __validate_index(self, index, size): 

200 """This method performs two tasks: to allocate enough space to 

201 fit the elements at positions index through index+size, and to 

202 adjust negative indexes to their absolute equivalent. 

203 """ 

204 

205 orig_index = index 

206 

207 curlen = len(self.__bytes) 

208 if index < 0: 

209 index = curlen + index 

210 

211 diff = index + size - curlen 

212 if diff > 0: 

213 array_frombytes(self.__bytes, b'\0' * diff) 

214 if orig_index < 0: 214 ↛ 215line 214 didn't jump to line 215, because the condition on line 214 was never true

215 orig_index -= diff 

216 

217 return orig_index 

218 

219class ProtocolLayer(): 

220 "Protocol Layer Manager for insertion and removal of protocol layers." 

221 

222 __child = None 

223 __parent = None 

224 

225 def contains(self, aHeader): 

226 "Set 'aHeader' as the child of this protocol layer" 

227 self.__child = aHeader 

228 aHeader.set_parent(self) 

229 

230 def set_parent(self, my_parent): 

231 "Set the header 'my_parent' as the parent of this protocol layer" 

232 self.__parent = my_parent 

233 

234 def child(self): 

235 "Return the child of this protocol layer" 

236 return self.__child 

237 

238 def parent(self): 

239 "Return the parent of this protocol layer" 

240 return self.__parent 

241 

242 def unlink_child(self): 

243 "Break the hierarchy parent/child child/parent" 

244 if self.__child: 

245 self.__child.set_parent(None) 

246 self.__child = None 

247 

248class ProtocolPacket(ProtocolLayer): 

249 __HEADER_SIZE = 0 

250 __BODY_SIZE = 0 

251 __TAIL_SIZE = 0 

252 

253 __header = None 

254 __body = None 

255 __tail = None 

256 

257 def __init__(self, header_size, tail_size): 

258 self.__HEADER_SIZE = header_size 

259 self.__TAIL_SIZE = tail_size 

260 self.__header=PacketBuffer(self.__HEADER_SIZE) 

261 self.__body=PacketBuffer() 

262 self.__tail=PacketBuffer(self.__TAIL_SIZE) 

263 

264 def __update_body_from_child(self): 

265 # Update child raw packet in my body 

266 if self.child(): 

267 body=self.child().get_packet() 

268 self.__BODY_SIZE=len(body) 

269 self.__body.set_bytes_from_string(body) 

270 

271 def __get_header(self): 

272 return self.__header 

273 

274 header = property(__get_header) 

275 

276 def __get_body(self): 

277 self.__update_body_from_child() 

278 return self.__body 

279 

280 body = property(__get_body) 

281 

282 def __get_tail(self): 

283 return self.__tail 

284 

285 tail = property(__get_tail) 

286 

287 def get_header_size(self): 

288 "Return frame header size" 

289 return self.__HEADER_SIZE 

290 

291 def get_tail_size(self): 

292 "Return frame tail size" 

293 return self.__TAIL_SIZE 

294 

295 def get_body_size(self): 

296 "Return frame body size" 

297 self.__update_body_from_child() 

298 return self.__BODY_SIZE 

299 

300 def get_size(self): 

301 "Return frame total size" 

302 return self.get_header_size()+self.get_body_size()+self.get_tail_size() 

303 

304 def load_header(self, aBuffer): 

305 self.__HEADER_SIZE=len(aBuffer) 

306 self.__header.set_bytes_from_string(aBuffer) 

307 

308 def load_body(self, aBuffer): 

309 "Load the packet body from string. "\ 

310 "WARNING: Using this function will break the hierarchy of preceding protocol layer" 

311 self.unlink_child() 

312 self.__BODY_SIZE=len(aBuffer) 

313 self.__body.set_bytes_from_string(aBuffer) 

314 

315 def load_tail(self, aBuffer): 

316 self.__TAIL_SIZE=len(aBuffer) 

317 self.__tail.set_bytes_from_string(aBuffer) 

318 

319 def __extract_header(self, aBuffer): 

320 self.load_header(aBuffer[:self.__HEADER_SIZE]) 

321 

322 def __extract_body(self, aBuffer): 

323 if self.__TAIL_SIZE<=0: 

324 end=None 

325 else: 

326 end=-self.__TAIL_SIZE 

327 self.__BODY_SIZE=len(aBuffer[self.__HEADER_SIZE:end]) 

328 self.__body.set_bytes_from_string(aBuffer[self.__HEADER_SIZE:end]) 

329 

330 def __extract_tail(self, aBuffer): 

331 if self.__TAIL_SIZE<=0: 

332 # leave the array empty 

333 return 

334 else: 

335 start=-self.__TAIL_SIZE 

336 self.__tail.set_bytes_from_string(aBuffer[start:]) 

337 

338 def load_packet(self, aBuffer): 

339 "Load the whole packet from a string" \ 

340 "WARNING: Using this function will break the hierarchy of preceding protocol layer" 

341 self.unlink_child() 

342 

343 self.__extract_header(aBuffer) 

344 self.__extract_body(aBuffer) 

345 self.__extract_tail(aBuffer) 

346 

347 def get_header_as_string(self): 

348 return self.__header.get_buffer_as_string() 

349 

350 def get_body_as_string(self): 

351 self.__update_body_from_child() 

352 return self.__body.get_buffer_as_string() 

353 body_string = property(get_body_as_string) 

354 

355 def get_tail_as_string(self): 

356 return self.__tail.get_buffer_as_string() 

357 tail_string = property(get_tail_as_string) 

358 

359 def get_packet(self): 

360 self.__update_body_from_child() 

361 

362 ret = b'' 

363 

364 header = self.get_header_as_string() 

365 if header: 

366 ret += header 

367 

368 body = self.get_body_as_string() 

369 if body: 

370 ret += body 

371 

372 tail = self.get_tail_as_string() 

373 if tail: 

374 ret += tail 

375 

376 return ret 

377 

378class Header(PacketBuffer,ProtocolLayer): 

379 "This is the base class from which all protocol definitions extend." 

380 

381 packet_printable = [c for c in string.printable if c not in string.whitespace] + [' '] 

382 

383 ethertype = None 

384 protocol = None 

385 def __init__(self, length = None): 

386 PacketBuffer.__init__(self, length) 

387 self.auto_checksum = 1 

388 

389 def get_data_as_string(self): 

390 "Returns all data from children of this header as string" 

391 

392 if self.child(): 

393 return self.child().get_packet() 

394 else: 

395 return None 

396 

397 def get_packet(self): 

398 """Returns the raw representation of this packet and its 

399 children as a string. The output from this method is a packet 

400 ready to be transmitted over the wire. 

401 """ 

402 self.calculate_checksum() 

403 

404 data = self.get_data_as_string() 

405 if data: 

406 return self.get_buffer_as_string() + data 

407 else: 

408 return self.get_buffer_as_string() 

409 

410 def get_size(self): 

411 "Return the size of this header and all of it's children" 

412 tmp_value = self.get_header_size() 

413 if self.child(): 

414 tmp_value = tmp_value + self.child().get_size() 

415 return tmp_value 

416 

417 def calculate_checksum(self): 

418 "Calculate and set the checksum for this header" 

419 pass 

420 

421 def get_pseudo_header(self): 

422 "Pseudo headers can be used to limit over what content will the checksums be calculated." 

423 # default implementation returns empty array 

424 return array.array('B') 

425 

426 def load_header(self, aBuffer): 

427 "Properly set the state of this instance to reflect that of the raw packet passed as argument." 

428 self.set_bytes_from_string(aBuffer) 

429 hdr_len = self.get_header_size() 

430 if(len(aBuffer) < hdr_len): #we must do something like this 430 ↛ 431line 430 didn't jump to line 431, because the condition on line 430 was never true

431 diff = hdr_len - len(aBuffer) 

432 for i in range(0, diff): 

433 aBuffer += '\x00' 

434 self.set_bytes_from_string(aBuffer[:hdr_len]) 

435 

436 def get_header_size(self): 

437 "Return the size of this header, that is, not counting neither the size of the children nor of the parents." 

438 raise RuntimeError("Method %s.get_header_size must be overridden." % self.__class__) 

439 

440 def list_as_hex(self, aList): 

441 if len(aList): 

442 ltmp = [] 

443 line = [] 

444 count = 0 

445 for byte in aList: 

446 if not (count % 2): 

447 if (count % 16): 

448 ltmp.append(' ') 

449 else: 

450 ltmp.append(' '*4) 

451 ltmp.append(''.join(line)) 

452 ltmp.append('\n') 

453 line = [] 

454 if chr(byte) in Header.packet_printable: 

455 line.append(chr(byte)) 

456 else: 

457 line.append('.') 

458 ltmp.append('%.2x' % byte) 

459 count += 1 

460 if (count%16): 

461 left = 16 - (count%16) 

462 ltmp.append(' ' * (4+(left // 2) + (left*2))) 

463 ltmp.append(''.join(line)) 

464 ltmp.append('\n') 

465 return ltmp 

466 else: 

467 return [] 

468 

469 def __str__(self): 

470 ltmp = self.list_as_hex(self.get_bytes().tolist()) 

471 

472 if self.child(): 

473 ltmp.append(['\n', str(self.child())]) 

474 

475 if len(ltmp)>0: 

476 return ''.join(ltmp) 

477 else: 

478 return '' 

479 

480 

481 

482class Data(Header): 

483 """This packet type can hold raw data. It's normally employed to 

484 hold a packet's innermost layer's contents in those cases for 

485 which the protocol details are unknown, and there's a copy of a 

486 valid packet available. 

487 

488 For instance, if all that's known about a certain protocol is that 

489 a UDP packet with its contents set to "HELLO" initiate a new 

490 session, creating such packet is as simple as in the following code 

491 fragment: 

492 packet = UDP() 

493 packet.contains('HELLO') 

494 """ 

495 

496 def __init__(self, aBuffer = None): 

497 Header.__init__(self) 

498 if aBuffer: 

499 self.set_data(aBuffer) 

500 

501 def set_data(self, data): 

502 self.set_bytes_from_string(data) 

503 

504 def get_size(self): 

505 return len(self.get_bytes()) 

506 

507 

508class EthernetTag(PacketBuffer): 

509 """Represents a VLAN header specified in IEEE 802.1Q and 802.1ad. 

510 Provides methods for convenient manipulation with header fields.""" 

511 

512 def __init__(self, value=0x81000000): 

513 PacketBuffer.__init__(self, 4) 

514 self.set_long(0, value) 

515 

516 def get_tpid(self): 

517 """Returns Tag Protocol Identifier""" 

518 return self.get_word(0) 

519 

520 def set_tpid(self, value): 

521 """Sets Tag Protocol Identifier""" 

522 return self.set_word(0, value) 

523 

524 def get_pcp(self): 

525 """Returns Priority Code Point""" 

526 return (self.get_byte(2) & 0xE0) >> 5 

527 

528 def set_pcp(self, value): 

529 """Sets Priority Code Point""" 

530 orig_value = self.get_byte(2) 

531 self.set_byte(2, (orig_value & 0x1F) | ((value & 0x07) << 5)) 

532 

533 def get_dei(self): 

534 """Returns Drop Eligible Indicator""" 

535 return (self.get_byte(2) & 0x10) >> 4 

536 

537 def set_dei(self, value): 

538 """Sets Drop Eligible Indicator""" 

539 orig_value = self.get_byte(2) 

540 self.set_byte(2, orig_value | 0x10 if value else orig_value & 0xEF) 

541 

542 def get_vid(self): 

543 """Returns VLAN Identifier""" 

544 return self.get_word(2) & 0x0FFF 

545 

546 def set_vid(self, value): 

547 """Sets VLAN Identifier""" 

548 orig_value = self.get_word(2) 

549 self.set_word(2, (orig_value & 0xF000) | (value & 0x0FFF)) 

550 

551 def __str__(self): 

552 priorities = ( 

553 'Best Effort', 

554 'Background', 

555 'Excellent Effort', 

556 'Critical Applications', 

557 'Video, < 100 ms latency and jitter', 

558 'Voice, < 10 ms latency and jitter', 

559 'Internetwork Control', 

560 'Network Control') 

561 

562 pcp = self.get_pcp() 

563 return '\n'.join(( 

564 '802.1Q header: 0x{0:08X}'.format(self.get_long(0)), 

565 'Priority Code Point: {0} ({1})'.format(pcp, priorities[pcp]), 

566 'Drop Eligible Indicator: {0}'.format(self.get_dei()), 

567 'VLAN Identifier: {0}'.format(self.get_vid()))) 

568 

569 

570class Ethernet(Header): 

571 def __init__(self, aBuffer = None): 

572 Header.__init__(self, 14) 

573 self.tag_cnt = 0 

574 if(aBuffer): 574 ↛ exitline 574 didn't return from function '__init__', because the condition on line 574 was never false

575 self.load_header(aBuffer) 

576 

577 def set_ether_type(self, aValue): 

578 "Set ethernet data type field to 'aValue'" 

579 self.set_word(12 + 4*self.tag_cnt, aValue) 

580 

581 def get_ether_type(self): 

582 "Return ethernet data type field" 

583 return self.get_word(12 + 4*self.tag_cnt) 

584 

585 def get_tag(self, index): 

586 """Returns an EthernetTag initialized from index-th VLAN tag. 

587 The tags are numbered from 0 to self.tag_cnt-1 as they appear in the frame. 

588 It is possible to use negative indexes as well.""" 

589 index = self.__validate_tag_index(index) 

590 return EthernetTag(self.get_long(12+4*index)) 

591 

592 def set_tag(self, index, tag): 

593 """Sets the index-th VLAN tag to contents of an EthernetTag object. 

594 The tags are numbered from 0 to self.tag_cnt-1 as they appear in the frame. 

595 It is possible to use negative indexes as well.""" 

596 index = self.__validate_tag_index(index) 

597 pos = 12 + 4*index 

598 for i,val in enumerate(tag.get_bytes()): 

599 self.set_byte(pos+i, val) 

600 

601 def push_tag(self, tag, index=0): 

602 """Inserts contents of an EthernetTag object before the index-th VLAN tag. 

603 Index defaults to 0 (the top of the stack).""" 

604 if index < 0: 604 ↛ 605line 604 didn't jump to line 605, because the condition on line 604 was never true

605 index += self.tag_cnt 

606 pos = 12 + 4*max(0, min(index, self.tag_cnt)) 

607 data = self.get_bytes() 

608 data[pos:pos] = tag.get_bytes() 

609 self.set_bytes(data) 

610 self.tag_cnt += 1 

611 

612 def pop_tag(self, index=0): 

613 """Removes the index-th VLAN tag and returns it as an EthernetTag object. 

614 Index defaults to 0 (the top of the stack).""" 

615 index = self.__validate_tag_index(index) 

616 pos = 12 + 4*index 

617 tag = self.get_long(pos) 

618 data = self.get_bytes() 

619 del data[pos:pos+4] 

620 self.set_bytes(data) 

621 self.tag_cnt -= 1 

622 return EthernetTag(tag) 

623 

624 def load_header(self, aBuffer): 

625 self.tag_cnt = 0 

626 while aBuffer[12+4*self.tag_cnt:14+4*self.tag_cnt] in (b'\x81\x00', b'\x88\xa8', b'\x91\x00'): 

627 self.tag_cnt += 1 

628 

629 hdr_len = self.get_header_size() 

630 diff = hdr_len - len(aBuffer) 

631 if diff > 0: 631 ↛ 632line 631 didn't jump to line 632, because the condition on line 631 was never true

632 aBuffer += b'\x00'*diff 

633 self.set_bytes_from_string(aBuffer[:hdr_len]) 

634 

635 def get_header_size(self): 

636 "Return size of Ethernet header" 

637 return 14 + 4*self.tag_cnt 

638 

639 def get_packet(self): 

640 

641 if self.child(): 641 ↛ 642line 641 didn't jump to line 642, because the condition on line 641 was never true

642 try: 

643 self.set_ether_type(self.child().ethertype) 

644 except: 

645 " an Ethernet packet may have a Data() " 

646 pass 

647 return Header.get_packet(self) 

648 

649 def get_ether_dhost(self): 

650 "Return 48 bit destination ethernet address as a 6 byte array" 

651 return self.get_bytes()[0:6] 

652 

653 def set_ether_dhost(self, aValue): 

654 "Set destination ethernet address from 6 byte array 'aValue'" 

655 for i in range(0, 6): 

656 self.set_byte(i, aValue[i]) 

657 

658 def get_ether_shost(self): 

659 "Return 48 bit source ethernet address as a 6 byte array" 

660 return self.get_bytes()[6:12] 

661 

662 def set_ether_shost(self, aValue): 

663 "Set source ethernet address from 6 byte array 'aValue'" 

664 for i in range(0, 6): 

665 self.set_byte(i + 6, aValue[i]) 

666 

667 @staticmethod 

668 def as_eth_addr(anArray): 

669 tmp_list = [x > 15 and '%x'%x or '0%x'%x for x in anArray] 

670 return '' + reduce(lambda x, y: x+':'+y, tmp_list) 

671 

672 def __str__(self): 

673 tmp_str = 'Ether: ' + self.as_eth_addr(self.get_ether_shost()) + ' -> ' 

674 tmp_str += self.as_eth_addr(self.get_ether_dhost()) 

675 if self.child(): 

676 tmp_str += '\n' + str( self.child()) 

677 return tmp_str 

678 

679 def __validate_tag_index(self, index): 

680 """Adjusts negative indices to their absolute equivalents. 

681 Raises IndexError when out of range <0, self.tag_cnt-1>.""" 

682 if index < 0: 

683 index += self.tag_cnt 

684 if index < 0 or index >= self.tag_cnt: 

685 raise IndexError("Tag index out of range") 

686 return index 

687 

688# Linux "cooked" capture encapsulation. 

689# Used, for instance, for packets returned by the "any" interface. 

690class LinuxSLL(Header): 

691 type_descriptions = [ 

692 "sent to us by somebody else", 

693 "broadcast by somebody else", 

694 "multicast by somebody else", 

695 "sent to somebody else to somebody else", 

696 "sent by us", 

697 ] 

698 

699 def __init__(self, aBuffer = None): 

700 Header.__init__(self, 16) 

701 if (aBuffer): 

702 self.load_header(aBuffer) 

703 

704 def set_type(self, type): 

705 "Sets the packet type field to type" 

706 self.set_word(0, type) 

707 

708 def get_type(self): 

709 "Returns the packet type field" 

710 return self.get_word(0) 

711 

712 def set_arphdr(self, value): 

713 "Sets the ARPHDR value for the link layer device type" 

714 self.set_word(2, type) 

715 

716 def get_arphdr(self): 

717 "Returns the ARPHDR value for the link layer device type" 

718 return self.get_word(2) 

719 

720 def set_addr_len(self, len): 

721 "Sets the length of the sender's address field to len" 

722 self.set_word(4, len) 

723 

724 def get_addr_len(self): 

725 "Returns the length of the sender's address field" 

726 return self.get_word(4) 

727 

728 def set_addr(self, addr): 

729 "Sets the sender's address field to addr. Addr must be at most 8-byte long." 

730 if (len(addr) < 8): 

731 addr += b'\0' * (8 - len(addr)) 

732 self.get_bytes()[6:14] = addr 

733 

734 def get_addr(self): 

735 "Returns the sender's address field" 

736 return array_tobytes(self.get_bytes()[6:14]) 

737 

738 def set_ether_type(self, aValue): 

739 "Set ethernet data type field to 'aValue'" 

740 self.set_word(14, aValue) 

741 

742 def get_ether_type(self): 

743 "Return ethernet data type field" 

744 return self.get_word(14) 

745 

746 def get_header_size(self): 

747 "Return size of packet header" 

748 return 16 

749 

750 def get_packet(self): 

751 if self.child(): 

752 self.set_ether_type(self.child().ethertype) 

753 return Header.get_packet(self) 

754 

755 def get_type_desc(self): 

756 type = self.get_type() 

757 if type < len(LinuxSLL.type_descriptions): 

758 return LinuxSLL.type_descriptions[type] 

759 else: 

760 return "Unknown" 

761 

762 def __str__(self): 

763 ss = [] 

764 alen = self.get_addr_len() 

765 addr = hexlify(self.get_addr()[0:alen]) 

766 ss.append("Linux SLL: addr=%s type=`%s'" % (addr, self.get_type_desc())) 

767 if self.child(): 

768 ss.append(str(self.child())) 

769 

770 return '\n'.join(ss) 

771 

772 

773class IP(Header): 

774 ethertype = 0x800 

775 def __init__(self, aBuffer = None): 

776 Header.__init__(self, 20) 

777 self.set_ip_v(4) 

778 self.set_ip_hl(5) 

779 self.set_ip_ttl(255) 

780 self.__option_list = [] 

781 if(aBuffer): 

782 # When decoding, checksum shouldn't be modified 

783 self.auto_checksum = 0 

784 self.load_header(aBuffer) 

785 

786 if sys.platform.count('bsd'): 786 ↛ 787line 786 didn't jump to line 787, because the condition on line 786 was never true

787 self.is_BSD = True 

788 else: 

789 self.is_BSD = False 

790 

791 

792 def get_packet(self): 

793 # set protocol 

794 if self.get_ip_p() == 0 and self.child(): 794 ↛ 795line 794 didn't jump to line 795, because the condition on line 794 was never true

795 self.set_ip_p(self.child().protocol) 

796 

797 # set total length 

798 if self.get_ip_len() == 0: 

799 self.set_ip_len(self.get_size()) 

800 

801 child_data = self.get_data_as_string() 

802 

803 if self.auto_checksum: 

804 self.reset_ip_sum() 

805 

806 my_bytes = self.get_bytes() 

807 

808 for op in self.__option_list: 808 ↛ 809line 808 didn't jump to line 809, because the loop on line 808 never started

809 my_bytes.extend(op.get_bytes()) 

810 

811 # Pad to a multiple of 4 bytes 

812 num_pad = (4 - (len(my_bytes) % 4)) % 4 

813 if num_pad: 813 ↛ 814line 813 didn't jump to line 814, because the condition on line 813 was never true

814 array_frombytes(my_bytes, b"\0" * num_pad) 

815 

816 # only change ip_hl value if options are present 

817 if len(self.__option_list): 817 ↛ 818line 817 didn't jump to line 818, because the condition on line 817 was never true

818 self.set_ip_hl(len(my_bytes) // 4) 

819 

820 

821 # set the checksum if the user hasn't modified it 

822 if self.auto_checksum: 

823 self.set_ip_sum(self.compute_checksum(my_bytes)) 

824 

825 if child_data is None: 825 ↛ 826line 825 didn't jump to line 826, because the condition on line 825 was never true

826 return array_tobytes(my_bytes) 

827 else: 

828 return array_tobytes(my_bytes) + child_data 

829 

830 

831 

832 # def calculate_checksum(self, buffer = None): 

833 # tmp_value = self.get_ip_sum() 

834 # if self.auto_checksum and (not tmp_value): 

835 # if buffer: 

836 # tmp_bytes = buffer 

837 # else: 

838 # tmp_bytes = self.bytes[0:self.get_header_size()] 

839 # 

840 # self.set_ip_sum(self.compute_checksum(tmp_bytes)) 

841 

842 

843 def get_pseudo_header(self): 

844 pseudo_buf = array.array("B") 

845 pseudo_buf.extend(self.get_bytes()[12:20]) 

846 pseudo_buf.fromlist([0]) 

847 pseudo_buf.extend(self.get_bytes()[9:10]) 

848 tmp_size = self.child().get_size() 

849 

850 size_str = struct.pack("!H", tmp_size) 

851 

852 array_frombytes(pseudo_buf, size_str) 

853 return pseudo_buf 

854 

855 def add_option(self, option): 

856 self.__option_list.append(option) 

857 sum = 0 

858 for op in self.__option_list: 

859 sum += op.get_len() 

860 if sum > 40: 

861 raise ImpactPacketException("Options overflowed in IP packet with length: %d" % sum) 

862 

863 

864 def get_ip_v(self): 

865 n = self.get_byte(0) 

866 return (n >> 4) 

867 

868 def set_ip_v(self, value): 

869 n = self.get_byte(0) 

870 version = value & 0xF 

871 n = n & 0xF 

872 n = n | (version << 4) 

873 self.set_byte(0, n) 

874 

875 def get_ip_hl(self): 

876 n = self.get_byte(0) 

877 return (n & 0xF) 

878 

879 def set_ip_hl(self, value): 

880 n = self.get_byte(0) 

881 len = value & 0xF 

882 n = n & 0xF0 

883 n = (n | len) 

884 self.set_byte(0, n) 

885 

886 def get_ip_tos(self): 

887 return self.get_byte(1) 

888 

889 def set_ip_tos(self,value): 

890 self.set_byte(1, value) 

891 

892 def get_ip_len(self): 

893 if self.is_BSD: 893 ↛ 894line 893 didn't jump to line 894, because the condition on line 893 was never true

894 return self.get_word(2, order = '=') 

895 else: 

896 return self.get_word(2) 

897 

898 def set_ip_len(self, value): 

899 if self.is_BSD: 899 ↛ 900line 899 didn't jump to line 900, because the condition on line 899 was never true

900 self.set_word(2, value, order = '=') 

901 else: 

902 self.set_word(2, value) 

903 

904 def get_ip_id(self): 

905 return self.get_word(4) 

906 def set_ip_id(self, value): 

907 return self.set_word(4, value) 

908 

909 def get_ip_off(self): 

910 if self.is_BSD: 910 ↛ 911line 910 didn't jump to line 911, because the condition on line 910 was never true

911 return self.get_word(6, order = '=') 

912 else: 

913 return self.get_word(6) 

914 

915 def set_ip_off(self, aValue): 

916 if self.is_BSD: 916 ↛ 917line 916 didn't jump to line 917, because the condition on line 916 was never true

917 self.set_word(6, aValue, order = '=') 

918 else: 

919 self.set_word(6, aValue) 

920 

921 def get_ip_offmask(self): 

922 return self.get_ip_off() & 0x1FFF 

923 

924 def set_ip_offmask(self, aValue): 

925 tmp_value = self.get_ip_off() & 0xD000 

926 tmp_value |= aValue 

927 self.set_ip_off(tmp_value) 

928 

929 def get_ip_rf(self): 

930 return self.get_ip_off() & 0x8000 

931 

932 def set_ip_rf(self, aValue): 

933 tmp_value = self.get_ip_off() 

934 if aValue: 934 ↛ 935line 934 didn't jump to line 935, because the condition on line 934 was never true

935 tmp_value |= 0x8000 

936 else: 

937 my_not = 0xFFFF ^ 0x8000 

938 tmp_value &= my_not 

939 self.set_ip_off(tmp_value) 

940 

941 def get_ip_df(self): 

942 return self.get_ip_off() & 0x4000 

943 

944 def set_ip_df(self, aValue): 

945 tmp_value = self.get_ip_off() 

946 if aValue: 946 ↛ 947line 946 didn't jump to line 947, because the condition on line 946 was never true

947 tmp_value |= 0x4000 

948 else: 

949 my_not = 0xFFFF ^ 0x4000 

950 tmp_value &= my_not 

951 self.set_ip_off(tmp_value) 

952 

953 def get_ip_mf(self): 

954 return self.get_ip_off() & 0x2000 

955 

956 def set_ip_mf(self, aValue): 

957 tmp_value = self.get_ip_off() 

958 if aValue: 958 ↛ 959line 958 didn't jump to line 959, because the condition on line 958 was never true

959 tmp_value |= 0x2000 

960 else: 

961 my_not = 0xFFFF ^ 0x2000 

962 tmp_value &= my_not 

963 self.set_ip_off(tmp_value) 

964 

965 

966 def fragment_by_list(self, aList): 

967 if self.child(): 

968 proto = self.child().protocol 

969 else: 

970 proto = 0 

971 

972 child_data = self.get_data_as_string() 

973 if not child_data: 

974 return [self] 

975 

976 ip_header_bytes = self.get_bytes() 

977 current_offset = 0 

978 fragment_list = [] 

979 

980 for frag_size in aList: 

981 ip = IP() 

982 ip.set_bytes(ip_header_bytes) # copy of original header 

983 ip.set_ip_p(proto) 

984 

985 

986 if frag_size % 8: # round this fragment size up to next multiple of 8 

987 frag_size += 8 - (frag_size % 8) 

988 

989 

990 ip.set_ip_offmask(current_offset // 8) 

991 current_offset += frag_size 

992 

993 data = Data(child_data[:frag_size]) 

994 child_data = child_data[frag_size:] 

995 

996 ip.set_ip_len(20 + data.get_size()) 

997 ip.contains(data) 

998 

999 

1000 if child_data: 

1001 

1002 ip.set_ip_mf(1) 

1003 

1004 fragment_list.append(ip) 

1005 else: # no more data bytes left to add to fragments 

1006 

1007 ip.set_ip_mf(0) 

1008 

1009 fragment_list.append(ip) 

1010 return fragment_list 

1011 

1012 if child_data: # any remaining data? 

1013 # create a fragment containing all of the remaining child_data 

1014 ip = IP() 

1015 ip.set_bytes(ip_header_bytes) 

1016 ip.set_ip_offmask(current_offset) 

1017 ip.set_ip_len(20 + len(child_data)) 

1018 data = Data(child_data) 

1019 ip.contains(data) 

1020 fragment_list.append(ip) 

1021 

1022 return fragment_list 

1023 

1024 

1025 def fragment_by_size(self, aSize): 

1026 data_len = len(self.get_data_as_string()) 

1027 num_frags = data_len // aSize 

1028 

1029 if data_len % aSize: 

1030 num_frags += 1 

1031 

1032 size_list = [] 

1033 for i in range(0, num_frags): 

1034 size_list.append(aSize) 

1035 return self.fragment_by_list(size_list) 

1036 

1037 

1038 def get_ip_ttl(self): 

1039 return self.get_byte(8) 

1040 def set_ip_ttl(self, value): 

1041 self.set_byte(8, value) 

1042 

1043 def get_ip_p(self): 

1044 return self.get_byte(9) 

1045 

1046 def set_ip_p(self, value): 

1047 self.set_byte(9, value) 

1048 

1049 def get_ip_sum(self): 

1050 return self.get_word(10) 

1051 def set_ip_sum(self, value): 

1052 self.auto_checksum = 0 

1053 self.set_word(10, value) 

1054 

1055 def reset_ip_sum(self): 

1056 self.set_ip_sum(0x0000) 

1057 self.auto_checksum = 1 

1058 

1059 def get_ip_src(self): 

1060 return self.get_ip_address(12) 

1061 def set_ip_src(self, value): 

1062 self.set_ip_address(12, value) 

1063 

1064 def get_ip_dst(self): 

1065 return self.get_ip_address(16) 

1066 

1067 def set_ip_dst(self, value): 

1068 self.set_ip_address(16, value) 

1069 

1070 def get_header_size(self): 

1071 op_len = 0 

1072 for op in self.__option_list: 1072 ↛ 1073line 1072 didn't jump to line 1073, because the loop on line 1072 never started

1073 op_len += op.get_len() 

1074 

1075 num_pad = (4 - (op_len % 4)) % 4 

1076 

1077 return 20 + op_len + num_pad 

1078 

1079 def load_header(self, aBuffer): 

1080 self.set_bytes_from_string(aBuffer[:20]) 

1081 opt_left = (self.get_ip_hl() - 5) * 4 

1082 opt_bytes = array.array('B', aBuffer[20:(20 + opt_left)]) 

1083 if len(opt_bytes) != opt_left: 1083 ↛ 1084line 1083 didn't jump to line 1084, because the condition on line 1083 was never true

1084 raise ImpactPacketException("Cannot load options from truncated packet") 

1085 

1086 

1087 while opt_left: 1087 ↛ 1088line 1087 didn't jump to line 1088, because the condition on line 1087 was never true

1088 op_type = opt_bytes[0] 

1089 if op_type == IPOption.IPOPT_EOL or op_type == IPOption.IPOPT_NOP: 

1090 new_option = IPOption(op_type) 

1091 op_len = 1 

1092 else: 

1093 op_len = opt_bytes[1] 

1094 if op_len > len(opt_bytes): 

1095 raise ImpactPacketException("IP Option length is too high") 

1096 

1097 new_option = IPOption(op_type, op_len) 

1098 new_option.set_bytes(opt_bytes[:op_len]) 

1099 

1100 opt_bytes = opt_bytes[op_len:] 

1101 opt_left -= op_len 

1102 self.add_option(new_option) 

1103 if op_type == IPOption.IPOPT_EOL: 

1104 break 

1105 

1106 

1107 def __str__(self): 

1108 flags = ' ' 

1109 if self.get_ip_df(): 

1110 flags += 'DF ' 

1111 if self.get_ip_mf(): 

1112 flags += 'MF ' 

1113 if self.get_ip_rf(): 

1114 flags += 'RF ' 

1115 tmp_str = 'IP%s%s -> %s ' % (flags, self.get_ip_src(),self.get_ip_dst()) 

1116 for op in self.__option_list: 

1117 tmp_str += '\n' + str(op) 

1118 if self.child(): 

1119 tmp_str += '\n' + str(self.child()) 

1120 return tmp_str 

1121 

1122 

1123class IPOption(PacketBuffer): 

1124 IPOPT_EOL = 0 

1125 IPOPT_NOP = 1 

1126 IPOPT_RR = 7 

1127 IPOPT_TS = 68 

1128 IPOPT_LSRR = 131 

1129 IPOPT_SSRR = 137 

1130 

1131 def __init__(self, opcode = 0, size = None): 

1132 if size and (size < 3 or size > 40): 

1133 raise ImpactPacketException("IP Options must have a size between 3 and 40 bytes") 

1134 

1135 if(opcode == IPOption.IPOPT_EOL): 

1136 PacketBuffer.__init__(self, 1) 

1137 self.set_code(IPOption.IPOPT_EOL) 

1138 elif(opcode == IPOption.IPOPT_NOP): 

1139 PacketBuffer.__init__(self, 1) 

1140 self.set_code(IPOption.IPOPT_NOP) 

1141 elif(opcode == IPOption.IPOPT_RR): 

1142 if not size: 

1143 size = 39 

1144 PacketBuffer.__init__(self, size) 

1145 self.set_code(IPOption.IPOPT_RR) 

1146 self.set_len(size) 

1147 self.set_ptr(4) 

1148 

1149 elif(opcode == IPOption.IPOPT_LSRR): 

1150 if not size: 

1151 size = 39 

1152 PacketBuffer.__init__(self, size) 

1153 self.set_code(IPOption.IPOPT_LSRR) 

1154 self.set_len(size) 

1155 self.set_ptr(4) 

1156 

1157 elif(opcode == IPOption.IPOPT_SSRR): 

1158 if not size: 

1159 size = 39 

1160 PacketBuffer.__init__(self, size) 

1161 self.set_code(IPOption.IPOPT_SSRR) 

1162 self.set_len(size) 

1163 self.set_ptr(4) 

1164 

1165 elif(opcode == IPOption.IPOPT_TS): 

1166 if not size: 

1167 size = 40 

1168 PacketBuffer.__init__(self, size) 

1169 self.set_code(IPOption.IPOPT_TS) 

1170 self.set_len(size) 

1171 self.set_ptr(5) 

1172 self.set_flags(0) 

1173 else: 

1174 if not size: 

1175 raise ImpactPacketException("Size required for this type") 

1176 PacketBuffer.__init__(self,size) 

1177 self.set_code(opcode) 

1178 self.set_len(size) 

1179 

1180 

1181 def append_ip(self, ip): 

1182 op = self.get_code() 

1183 if not (op == IPOption.IPOPT_RR or op == IPOption.IPOPT_LSRR or op == IPOption.IPOPT_SSRR or op == IPOption.IPOPT_TS): 

1184 raise ImpactPacketException("append_ip() not support for option type %d" % self.opt_type) 

1185 

1186 p = self.get_ptr() 

1187 if not p: 

1188 raise ImpactPacketException("append_ip() failed, option ptr uninitialized") 

1189 

1190 if (p + 4) > self.get_len(): 

1191 raise ImpactPacketException("append_ip() would overflow option") 

1192 

1193 self.set_ip_address(p - 1, ip) 

1194 p += 4 

1195 self.set_ptr(p) 

1196 

1197 

1198 def set_code(self, value): 

1199 self.set_byte(0, value) 

1200 

1201 def get_code(self): 

1202 return self.get_byte(0) 

1203 

1204 

1205 def set_flags(self, flags): 

1206 if not (self.get_code() == IPOption.IPOPT_TS): 

1207 raise ImpactPacketException("Operation only supported on Timestamp option") 

1208 self.set_byte(3, flags) 

1209 

1210 def get_flags(self, flags): 

1211 if not (self.get_code() == IPOption.IPOPT_TS): 

1212 raise ImpactPacketException("Operation only supported on Timestamp option") 

1213 return self.get_byte(3) 

1214 

1215 

1216 def set_len(self, len): 

1217 self.set_byte(1, len) 

1218 

1219 

1220 def set_ptr(self, ptr): 

1221 self.set_byte(2, ptr) 

1222 

1223 def get_ptr(self): 

1224 return self.get_byte(2) 

1225 

1226 def get_len(self): 

1227 return len(self.get_bytes()) 

1228 

1229 

1230 def __str__(self): 

1231 map = {IPOption.IPOPT_EOL : "End of List ", 

1232 IPOption.IPOPT_NOP : "No Operation ", 

1233 IPOption.IPOPT_RR : "Record Route ", 

1234 IPOption.IPOPT_TS : "Timestamp ", 

1235 IPOption.IPOPT_LSRR : "Loose Source Route ", 

1236 IPOption.IPOPT_SSRR : "Strict Source Route "} 

1237 

1238 tmp_str = "\tIP Option: " 

1239 op = self.get_code() 

1240 if op in map: 

1241 tmp_str += map[op] 

1242 else: 

1243 tmp_str += "Code: %d " % op 

1244 

1245 if op == IPOption.IPOPT_RR or op == IPOption.IPOPT_LSRR or op ==IPOption.IPOPT_SSRR: 

1246 tmp_str += self.print_addresses() 

1247 

1248 

1249 return tmp_str 

1250 

1251 

1252 def print_addresses(self): 

1253 p = 3 

1254 tmp_str = "[" 

1255 if self.get_len() >= 7: # at least one complete IP address 

1256 while 1: 

1257 if p + 1 == self.get_ptr(): 

1258 tmp_str += "#" 

1259 tmp_str += self.get_ip_address(p) 

1260 p += 4 

1261 if p >= self.get_len(): 

1262 break 

1263 else: 

1264 tmp_str += ", " 

1265 tmp_str += "] " 

1266 if self.get_ptr() % 4: # ptr field should be a multiple of 4 

1267 tmp_str += "nonsense ptr field: %d " % self.get_ptr() 

1268 return tmp_str 

1269 

1270 

1271class UDP(Header): 

1272 protocol = 17 

1273 def __init__(self, aBuffer = None): 

1274 Header.__init__(self, 8) 

1275 if(aBuffer): 1275 ↛ 1276line 1275 didn't jump to line 1276, because the condition on line 1275 was never true

1276 self.load_header(aBuffer) 

1277 

1278 def get_uh_sport(self): 

1279 return self.get_word(0) 

1280 def set_uh_sport(self, value): 

1281 self.set_word(0, value) 

1282 

1283 def get_uh_dport(self): 

1284 return self.get_word(2) 

1285 def set_uh_dport(self, value): 

1286 self.set_word(2, value) 

1287 

1288 def get_uh_ulen(self): 

1289 return self.get_word(4) 

1290 

1291 def set_uh_ulen(self, value): 

1292 self.set_word(4, value) 

1293 

1294 def get_uh_sum(self): 

1295 return self.get_word(6) 

1296 

1297 def set_uh_sum(self, value): 

1298 self.set_word(6, value) 

1299 self.auto_checksum = 0 

1300 

1301 def calculate_checksum(self): 

1302 if self.auto_checksum and (not self.get_uh_sum()): 

1303 # if there isn't a parent to grab a pseudo-header from we'll assume the user knows what they're doing 

1304 # and won't meddle with the checksum or throw an exception 

1305 if not self.parent(): 

1306 return 

1307 

1308 buffer = self.parent().get_pseudo_header() 

1309 

1310 buffer += self.get_bytes() 

1311 data = self.get_data_as_string() 

1312 if(data): 

1313 array_frombytes(buffer, data) 

1314 self.set_uh_sum(self.compute_checksum(buffer)) 

1315 

1316 def get_header_size(self): 

1317 return 8 

1318 

1319 def __str__(self): 

1320 tmp_str = 'UDP %d -> %d' % (self.get_uh_sport(), self.get_uh_dport()) 

1321 if self.child(): 

1322 tmp_str += '\n' + str(self.child()) 

1323 return tmp_str 

1324 

1325 def get_packet(self): 

1326 # set total length 

1327 if(self.get_uh_ulen() == 0): 

1328 self.set_uh_ulen(self.get_size()) 

1329 return Header.get_packet(self) 

1330 

1331class TCP(Header): 

1332 protocol = 6 

1333 TCP_FLAGS_MASK = 0x00FF # lowest 16 bits are the flags 

1334 def __init__(self, aBuffer = None): 

1335 Header.__init__(self, 20) 

1336 self.set_th_off(5) 

1337 self.__option_list = [] 

1338 if aBuffer: 1338 ↛ exitline 1338 didn't return from function '__init__', because the condition on line 1338 was never false

1339 self.load_header(aBuffer) 

1340 

1341 def add_option(self, option): 

1342 self.__option_list.append(option) 

1343 

1344 sum = 0 

1345 for op in self.__option_list: 

1346 sum += op.get_size() 

1347 

1348 if sum > 40: 1348 ↛ 1349line 1348 didn't jump to line 1349, because the condition on line 1348 was never true

1349 raise ImpactPacketException("Cannot add TCP option, would overflow option space") 

1350 

1351 def get_options(self): 

1352 return self.__option_list 

1353 

1354 def swapSourceAndDestination(self): 

1355 oldSource = self.get_th_sport() 

1356 self.set_th_sport(self.get_th_dport()) 

1357 self.set_th_dport(oldSource) 

1358 

1359 # 

1360 # Header field accessors 

1361 # 

1362 

1363 def set_th_sport(self, aValue): 

1364 self.set_word(0, aValue) 

1365 

1366 def get_th_sport(self): 

1367 return self.get_word(0) 

1368 

1369 def get_th_dport(self): 

1370 return self.get_word(2) 

1371 

1372 def set_th_dport(self, aValue): 

1373 self.set_word(2, aValue) 

1374 

1375 def get_th_seq(self): 

1376 return self.get_long(4) 

1377 

1378 def set_th_seq(self, aValue): 

1379 self.set_long(4, aValue) 

1380 

1381 def get_th_ack(self): 

1382 return self.get_long(8) 

1383 

1384 def set_th_ack(self, aValue): 

1385 self.set_long(8, aValue) 

1386 

1387 def get_th_flags(self): 

1388 return self.get_word(12) & self.TCP_FLAGS_MASK 

1389 

1390 def set_th_flags(self, aValue): 

1391 masked = self.get_word(12) & (~self.TCP_FLAGS_MASK) 

1392 nb = masked | (aValue & self.TCP_FLAGS_MASK) 

1393 return self.set_word(12, nb, ">") 

1394 

1395 def get_th_win(self): 

1396 return self.get_word(14) 

1397 

1398 def set_th_win(self, aValue): 

1399 self.set_word(14, aValue) 

1400 

1401 def set_th_sum(self, aValue): 

1402 self.set_word(16, aValue) 

1403 self.auto_checksum = 0 

1404 

1405 def get_th_sum(self): 

1406 return self.get_word(16) 

1407 

1408 def get_th_urp(self): 

1409 return self.get_word(18) 

1410 

1411 def set_th_urp(self, aValue): 

1412 return self.set_word(18, aValue) 

1413 

1414 # Flag accessors 

1415 

1416 def get_th_reserved(self): 

1417 tmp_value = self.get_byte(12) & 0x0f 

1418 return tmp_value 

1419 

1420 

1421 def get_th_off(self): 

1422 tmp_value = self.get_byte(12) >> 4 

1423 return tmp_value 

1424 

1425 def set_th_off(self, aValue): 

1426 mask = 0xF0 

1427 masked = self.get_byte(12) & (~mask) 

1428 nb = masked | ( (aValue << 4) & mask) 

1429 return self.set_byte(12, nb) 

1430 

1431 def get_CWR(self): 

1432 return self.get_flag(128) 

1433 def set_CWR(self): 

1434 return self.set_flags(128) 

1435 def reset_CWR(self): 

1436 return self.reset_flags(128) 

1437 

1438 def get_ECE(self): 

1439 return self.get_flag(64) 

1440 def set_ECE(self): 

1441 return self.set_flags(64) 

1442 def reset_ECE(self): 

1443 return self.reset_flags(64) 

1444 

1445 def get_URG(self): 

1446 return self.get_flag(32) 

1447 def set_URG(self): 

1448 return self.set_flags(32) 

1449 def reset_URG(self): 

1450 return self.reset_flags(32) 

1451 

1452 def get_ACK(self): 

1453 return self.get_flag(16) 

1454 def set_ACK(self): 

1455 return self.set_flags(16) 

1456 def reset_ACK(self): 

1457 return self.reset_flags(16) 

1458 

1459 def get_PSH(self): 

1460 return self.get_flag(8) 

1461 def set_PSH(self): 

1462 return self.set_flags(8) 

1463 def reset_PSH(self): 

1464 return self.reset_flags(8) 

1465 

1466 def get_RST(self): 

1467 return self.get_flag(4) 

1468 def set_RST(self): 

1469 return self.set_flags(4) 

1470 def reset_RST(self): 

1471 return self.reset_flags(4) 

1472 

1473 def get_SYN(self): 

1474 return self.get_flag(2) 

1475 def set_SYN(self): 

1476 return self.set_flags(2) 

1477 def reset_SYN(self): 

1478 return self.reset_flags(2) 

1479 

1480 def get_FIN(self): 

1481 return self.get_flag(1) 

1482 def set_FIN(self): 

1483 return self.set_flags(1) 

1484 def reset_FIN(self): 

1485 return self.reset_flags(1) 

1486 

1487 # Overridden Methods 

1488 

1489 def get_header_size(self): 

1490 return 20 + len(self.get_padded_options()) 

1491 

1492 def calculate_checksum(self): 

1493 if not self.auto_checksum or not self.parent(): 1493 ↛ 1496line 1493 didn't jump to line 1496, because the condition on line 1493 was never false

1494 return 

1495 

1496 self.set_th_sum(0) 

1497 buffer = self.parent().get_pseudo_header() 

1498 buffer += self.get_bytes() 

1499 buffer += self.get_padded_options() 

1500 

1501 data = self.get_data_as_string() 

1502 if(data): 

1503 array_frombytes(buffer, data) 

1504 

1505 res = self.compute_checksum(buffer) 

1506 

1507 self.set_th_sum(self.compute_checksum(buffer)) 

1508 

1509 def get_packet(self): 

1510 "Returns entire packet including child data as a string. This is the function used to extract the final packet" 

1511 

1512 # only change th_off value if options are present 

1513 if len(self.__option_list): 1513 ↛ 1516line 1513 didn't jump to line 1516, because the condition on line 1513 was never false

1514 self.set_th_off(self.get_header_size() // 4) 

1515 

1516 self.calculate_checksum() 

1517 

1518 bytes = self.get_bytes() + self.get_padded_options() 

1519 data = self.get_data_as_string() 

1520 

1521 if data: 1521 ↛ 1522line 1521 didn't jump to line 1522, because the condition on line 1521 was never true

1522 return array_tobytes(bytes) + data 

1523 else: 

1524 return array_tobytes(bytes) 

1525 

1526 def load_header(self, aBuffer): 

1527 self.set_bytes_from_string(aBuffer[:20]) 

1528 opt_left = (self.get_th_off() - 5) * 4 

1529 opt_bytes = array.array('B', aBuffer[20:(20 + opt_left)]) 

1530 if len(opt_bytes) != opt_left: 1530 ↛ 1531line 1530 didn't jump to line 1531, because the condition on line 1530 was never true

1531 raise ImpactPacketException("Cannot load options from truncated packet") 

1532 

1533 while opt_left: 

1534 op_kind = opt_bytes[0] 

1535 if op_kind == TCPOption.TCPOPT_EOL or op_kind == TCPOption.TCPOPT_NOP: 

1536 new_option = TCPOption(op_kind) 

1537 op_len = 1 

1538 else: 

1539 op_len = opt_bytes[1] 

1540 if op_len > len(opt_bytes): 1540 ↛ 1541line 1540 didn't jump to line 1541, because the condition on line 1540 was never true

1541 raise ImpactPacketException("TCP Option length is too high") 

1542 if op_len < 2: 

1543 raise ImpactPacketException("TCP Option length is too low") 

1544 

1545 new_option = TCPOption(op_kind) 

1546 new_option.set_bytes(opt_bytes[:op_len]) 

1547 

1548 opt_bytes = opt_bytes[op_len:] 

1549 opt_left -= op_len 

1550 self.add_option(new_option) 

1551 if op_kind == TCPOption.TCPOPT_EOL: 1551 ↛ 1552line 1551 didn't jump to line 1552, because the condition on line 1551 was never true

1552 break 

1553 

1554 # 

1555 # Private 

1556 # 

1557 

1558 def get_flag(self, bit): 

1559 if self.get_th_flags() & bit: 

1560 return 1 

1561 else: 

1562 return 0 

1563 

1564 def reset_flags(self, aValue): 

1565 tmp_value = self.get_th_flags() & (~aValue) 

1566 return self.set_th_flags(tmp_value) 

1567 

1568 def set_flags(self, aValue): 

1569 tmp_value = self.get_th_flags() | aValue 

1570 return self.set_th_flags(tmp_value) 

1571 

1572 def get_padded_options(self): 

1573 "Return an array containing all options padded to a 4 byte boundary" 

1574 op_buf = array.array('B') 

1575 for op in self.__option_list: 

1576 op_buf += op.get_bytes() 

1577 num_pad = (4 - (len(op_buf) % 4)) % 4 

1578 if num_pad: 1578 ↛ 1579line 1578 didn't jump to line 1579, because the condition on line 1578 was never true

1579 array_frombytes(op_buf, "\0" * num_pad) 

1580 return op_buf 

1581 

1582 def __str__(self): 

1583 tmp_str = 'TCP ' 

1584 if self.get_ECE(): 

1585 tmp_str += 'ece ' 

1586 if self.get_CWR(): 

1587 tmp_str += 'cwr ' 

1588 if self.get_ACK(): 

1589 tmp_str += 'ack ' 

1590 if self.get_FIN(): 

1591 tmp_str += 'fin ' 

1592 if self.get_PSH(): 

1593 tmp_str += 'push ' 

1594 if self.get_RST(): 

1595 tmp_str += 'rst ' 

1596 if self.get_SYN(): 

1597 tmp_str += 'syn ' 

1598 if self.get_URG(): 

1599 tmp_str += 'urg ' 

1600 tmp_str += '%d -> %d' % (self.get_th_sport(), self.get_th_dport()) 

1601 for op in self.__option_list: 

1602 tmp_str += '\n' + str(op) 

1603 

1604 if self.child(): 

1605 tmp_str += '\n' + str(self.child()) 

1606 return tmp_str 

1607 

1608 

1609class TCPOption(PacketBuffer): 

1610 TCPOPT_EOL = 0 

1611 TCPOPT_NOP = 1 

1612 TCPOPT_MAXSEG = 2 

1613 TCPOPT_WINDOW = 3 

1614 TCPOPT_SACK_PERMITTED = 4 

1615 TCPOPT_SACK = 5 

1616 TCPOPT_TIMESTAMP = 8 

1617 TCPOPT_SIGNATURE = 19 

1618 

1619 

1620 def __init__(self, kind, data = None): 

1621 

1622 if kind == TCPOption.TCPOPT_EOL: 1622 ↛ 1623line 1622 didn't jump to line 1623, because the condition on line 1622 was never true

1623 PacketBuffer.__init__(self, 1) 

1624 self.set_kind(TCPOption.TCPOPT_EOL) 

1625 elif kind == TCPOption.TCPOPT_NOP: 

1626 PacketBuffer.__init__(self, 1) 

1627 self.set_kind(TCPOption.TCPOPT_NOP) 

1628 elif kind == TCPOption.TCPOPT_MAXSEG: 

1629 PacketBuffer.__init__(self, 4) 

1630 self.set_kind(TCPOption.TCPOPT_MAXSEG) 

1631 self.set_len(4) 

1632 if data: 1632 ↛ 1633line 1632 didn't jump to line 1633, because the condition on line 1632 was never true

1633 self.set_mss(data) 

1634 else: 

1635 self.set_mss(512) 

1636 elif kind == TCPOption.TCPOPT_WINDOW: 

1637 PacketBuffer.__init__(self, 3) 

1638 self.set_kind(TCPOption.TCPOPT_WINDOW) 

1639 self.set_len(3) 

1640 if data: 1640 ↛ 1641line 1640 didn't jump to line 1641, because the condition on line 1640 was never true

1641 self.set_shift_cnt(data) 

1642 else: 

1643 self.set_shift_cnt(0) 

1644 elif kind == TCPOption.TCPOPT_TIMESTAMP: 

1645 PacketBuffer.__init__(self, 10) 

1646 self.set_kind(TCPOption.TCPOPT_TIMESTAMP) 

1647 self.set_len(10) 

1648 if data: 1648 ↛ 1649line 1648 didn't jump to line 1649, because the condition on line 1648 was never true

1649 self.set_ts(data) 

1650 else: 

1651 self.set_ts(0) 

1652 elif kind == TCPOption.TCPOPT_SACK_PERMITTED: 1652 ↛ 1657line 1652 didn't jump to line 1657, because the condition on line 1652 was never false

1653 PacketBuffer.__init__(self, 2) 

1654 self.set_kind(TCPOption.TCPOPT_SACK_PERMITTED) 

1655 self.set_len(2) 

1656 

1657 elif kind == TCPOption.TCPOPT_SACK: 

1658 PacketBuffer.__init__(self, 2) 

1659 self.set_kind(TCPOption.TCPOPT_SACK) 

1660 

1661 def set_left_edge(self, aValue): 

1662 self.set_long (2, aValue) 

1663 

1664 def set_right_edge(self, aValue): 

1665 self.set_long (6, aValue) 

1666 

1667 def set_kind(self, kind): 

1668 self.set_byte(0, kind) 

1669 

1670 

1671 def get_kind(self): 

1672 return self.get_byte(0) 

1673 

1674 

1675 def set_len(self, len): 

1676 if self.get_size() < 2: 1676 ↛ 1677line 1676 didn't jump to line 1677, because the condition on line 1676 was never true

1677 raise ImpactPacketException("Cannot set length field on an option having a size smaller than 2 bytes") 

1678 self.set_byte(1, len) 

1679 

1680 def get_len(self): 

1681 if self.get_size() < 2: 

1682 raise ImpactPacketException("Cannot retrieve length field from an option having a size smaller than 2 bytes") 

1683 return self.get_byte(1) 

1684 

1685 def get_size(self): 

1686 return len(self.get_bytes()) 

1687 

1688 

1689 def set_mss(self, len): 

1690 if self.get_kind() != TCPOption.TCPOPT_MAXSEG: 1690 ↛ 1691line 1690 didn't jump to line 1691, because the condition on line 1690 was never true

1691 raise ImpactPacketException("Can only set MSS on TCPOPT_MAXSEG option") 

1692 self.set_word(2, len) 

1693 

1694 def get_mss(self): 

1695 if self.get_kind() != TCPOption.TCPOPT_MAXSEG: 

1696 raise ImpactPacketException("Can only retrieve MSS from TCPOPT_MAXSEG option") 

1697 return self.get_word(2) 

1698 

1699 def set_shift_cnt(self, cnt): 

1700 if self.get_kind() != TCPOption.TCPOPT_WINDOW: 1700 ↛ 1701line 1700 didn't jump to line 1701, because the condition on line 1700 was never true

1701 raise ImpactPacketException("Can only set Shift Count on TCPOPT_WINDOW option") 

1702 self.set_byte(2, cnt) 

1703 

1704 def get_shift_cnt(self): 

1705 if self.get_kind() != TCPOption.TCPOPT_WINDOW: 

1706 raise ImpactPacketException("Can only retrieve Shift Count from TCPOPT_WINDOW option") 

1707 return self.get_byte(2) 

1708 

1709 def get_ts(self): 

1710 if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP: 

1711 raise ImpactPacketException("Can only retrieve timestamp from TCPOPT_TIMESTAMP option") 

1712 return self.get_long(2) 

1713 

1714 def set_ts(self, ts): 

1715 if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP: 1715 ↛ 1716line 1715 didn't jump to line 1716, because the condition on line 1715 was never true

1716 raise ImpactPacketException("Can only set timestamp on TCPOPT_TIMESTAMP option") 

1717 self.set_long(2, ts) 

1718 

1719 def get_ts_echo(self): 

1720 if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP: 

1721 raise ImpactPacketException("Can only retrieve timestamp from TCPOPT_TIMESTAMP option") 

1722 return self.get_long(6) 

1723 

1724 def set_ts_echo(self, ts): 

1725 if self.get_kind() != TCPOption.TCPOPT_TIMESTAMP: 

1726 raise ImpactPacketException("Can only set timestamp on TCPOPT_TIMESTAMP option") 

1727 self.set_long(6, ts) 

1728 

1729 def __str__(self): 

1730 map = { TCPOption.TCPOPT_EOL : "End of List ", 

1731 TCPOption.TCPOPT_NOP : "No Operation ", 

1732 TCPOption.TCPOPT_MAXSEG : "Maximum Segment Size ", 

1733 TCPOption.TCPOPT_WINDOW : "Window Scale ", 

1734 TCPOption.TCPOPT_TIMESTAMP : "Timestamp " } 

1735 

1736 tmp_str = "\tTCP Option: " 

1737 op = self.get_kind() 

1738 if op in map: 

1739 tmp_str += map[op] 

1740 else: 

1741 tmp_str += " kind: %d " % op 

1742 if op == TCPOption.TCPOPT_MAXSEG: 

1743 tmp_str += " MSS : %d " % self.get_mss() 

1744 elif op == TCPOption.TCPOPT_WINDOW: 

1745 tmp_str += " Shift Count: %d " % self.get_shift_cnt() 

1746 elif op == TCPOption.TCPOPT_TIMESTAMP: 

1747 pass # TODO 

1748 return tmp_str 

1749 

1750class ICMP(Header): 

1751 protocol = 1 

1752 ICMP_ECHOREPLY = 0 

1753 ICMP_UNREACH = 3 

1754 ICMP_UNREACH_NET = 0 

1755 ICMP_UNREACH_HOST = 1 

1756 ICMP_UNREACH_PROTOCOL = 2 

1757 ICMP_UNREACH_PORT = 3 

1758 ICMP_UNREACH_NEEDFRAG = 4 

1759 ICMP_UNREACH_SRCFAIL = 5 

1760 ICMP_UNREACH_NET_UNKNOWN = 6 

1761 ICMP_UNREACH_HOST_UNKNOWN = 7 

1762 ICMP_UNREACH_ISOLATED = 8 

1763 ICMP_UNREACH_NET_PROHIB = 9 

1764 ICMP_UNREACH_HOST_PROHIB = 10 

1765 ICMP_UNREACH_TOSNET = 11 

1766 ICMP_UNREACH_TOSHOST = 12 

1767 ICMP_UNREACH_FILTERPROHIB = 13 

1768 ICMP_UNREACH_HOST_PRECEDENCE = 14 

1769 ICMP_UNREACH_PRECEDENCE_CUTOFF = 15 

1770 ICMP_SOURCEQUENCH = 4 

1771 ICMP_REDIRECT = 5 

1772 ICMP_REDIRECT_NET = 0 

1773 ICMP_REDIRECT_HOST = 1 

1774 ICMP_REDIRECT_TOSNET = 2 

1775 ICMP_REDIRECT_TOSHOST = 3 

1776 ICMP_ALTHOSTADDR = 6 

1777 ICMP_ECHO = 8 

1778 ICMP_ROUTERADVERT = 9 

1779 ICMP_ROUTERSOLICIT = 10 

1780 ICMP_TIMXCEED = 11 

1781 ICMP_TIMXCEED_INTRANS = 0 

1782 ICMP_TIMXCEED_REASS = 1 

1783 ICMP_PARAMPROB = 12 

1784 ICMP_PARAMPROB_ERRATPTR = 0 

1785 ICMP_PARAMPROB_OPTABSENT = 1 

1786 ICMP_PARAMPROB_LENGTH = 2 

1787 ICMP_TSTAMP = 13 

1788 ICMP_TSTAMPREPLY = 14 

1789 ICMP_IREQ = 15 

1790 ICMP_IREQREPLY = 16 

1791 ICMP_MASKREQ = 17 

1792 ICMP_MASKREPLY = 18 

1793 

1794 def __init__(self, aBuffer = None): 

1795 Header.__init__(self, 8) 

1796 if aBuffer: 

1797 self.load_header(aBuffer) 

1798 

1799 def get_header_size(self): 

1800 anamolies = { ICMP.ICMP_TSTAMP : 20, ICMP.ICMP_TSTAMPREPLY : 20, ICMP.ICMP_MASKREQ : 12, ICMP.ICMP_MASKREPLY : 12 } 

1801 if self.get_icmp_type() in anamolies: 1801 ↛ 1802line 1801 didn't jump to line 1802, because the condition on line 1801 was never true

1802 return anamolies[self.get_icmp_type()] 

1803 else: 

1804 return 8 

1805 

1806 def get_icmp_type(self): 

1807 return self.get_byte(0) 

1808 

1809 def set_icmp_type(self, aValue): 

1810 self.set_byte(0, aValue) 

1811 

1812 def get_icmp_code(self): 

1813 return self.get_byte(1) 

1814 

1815 def set_icmp_code(self, aValue): 

1816 self.set_byte(1, aValue) 

1817 

1818 def get_icmp_cksum(self): 

1819 return self.get_word(2) 

1820 

1821 def set_icmp_cksum(self, aValue): 

1822 self.set_word(2, aValue) 

1823 self.auto_checksum = 0 

1824 

1825 def get_icmp_gwaddr(self): 

1826 return self.get_ip_address(4) 

1827 

1828 def set_icmp_gwaddr(self, ip): 

1829 self.set_ip_address(4, ip) 

1830 

1831 def get_icmp_id(self): 

1832 return self.get_word(4) 

1833 

1834 def set_icmp_id(self, aValue): 

1835 self.set_word(4, aValue) 

1836 

1837 def get_icmp_seq(self): 

1838 return self.get_word(6) 

1839 

1840 def set_icmp_seq(self, aValue): 

1841 self.set_word(6, aValue) 

1842 

1843 def get_icmp_void(self): 

1844 return self.get_long(4) 

1845 

1846 def set_icmp_void(self, aValue): 

1847 self.set_long(4, aValue) 

1848 

1849 

1850 def get_icmp_nextmtu(self): 

1851 return self.get_word(6) 

1852 

1853 def set_icmp_nextmtu(self, aValue): 

1854 self.set_word(6, aValue) 

1855 

1856 def get_icmp_num_addrs(self): 

1857 return self.get_byte(4) 

1858 

1859 def set_icmp_num_addrs(self, aValue): 

1860 self.set_byte(4, aValue) 

1861 

1862 def get_icmp_wpa(self): 

1863 return self.get_byte(5) 

1864 

1865 def set_icmp_wpa(self, aValue): 

1866 self.set_byte(5, aValue) 

1867 

1868 def get_icmp_lifetime(self): 

1869 return self.get_word(6) 

1870 

1871 def set_icmp_lifetime(self, aValue): 

1872 self.set_word(6, aValue) 

1873 

1874 def get_icmp_otime(self): 

1875 return self.get_long(8) 

1876 

1877 def set_icmp_otime(self, aValue): 

1878 self.set_long(8, aValue) 

1879 

1880 def get_icmp_rtime(self): 

1881 return self.get_long(12) 

1882 

1883 def set_icmp_rtime(self, aValue): 

1884 self.set_long(12, aValue) 

1885 

1886 def get_icmp_ttime(self): 

1887 return self.get_long(16) 

1888 

1889 def set_icmp_ttime(self, aValue): 

1890 self.set_long(16, aValue) 

1891 

1892 def get_icmp_mask(self): 

1893 return self.get_ip_address(8) 

1894 

1895 def set_icmp_mask(self, mask): 

1896 self.set_ip_address(8, mask) 

1897 

1898 

1899 def calculate_checksum(self): 

1900 if self.auto_checksum and (not self.get_icmp_cksum()): 

1901 buffer = self.get_buffer_as_string() 

1902 data = self.get_data_as_string() 

1903 if data: 1903 ↛ 1906line 1903 didn't jump to line 1906, because the condition on line 1903 was never false

1904 buffer += data 

1905 

1906 tmp_array = array.array('B', buffer) 

1907 self.set_icmp_cksum(self.compute_checksum(tmp_array)) 

1908 

1909 def get_type_name(self, aType): 

1910 tmp_type = {0:'ECHOREPLY', 3:'UNREACH', 4:'SOURCEQUENCH',5:'REDIRECT', 6:'ALTHOSTADDR', 8:'ECHO', 9:'ROUTERADVERT', 10:'ROUTERSOLICIT', 11:'TIMXCEED', 12:'PARAMPROB', 13:'TSTAMP', 14:'TSTAMPREPLY', 15:'IREQ', 16:'IREQREPLY', 17:'MASKREQ', 18:'MASKREPLY', 30:'TRACEROUTE', 31:'DATACONVERR', 32:'MOBILE REDIRECT', 33:'IPV6 WHEREAREYOU', 34:'IPV6 IAMHERE', 35:'MOBILE REGREQUEST', 36:'MOBILE REGREPLY', 39:'SKIP', 40:'PHOTURIS'} 

1911 answer = tmp_type.get(aType, 'UNKNOWN') 

1912 return answer 

1913 

1914 def get_code_name(self, aType, aCode): 

1915 tmp_code = {3:['UNREACH NET', 'UNREACH HOST', 'UNREACH PROTOCOL', 'UNREACH PORT', 'UNREACH NEEDFRAG', 'UNREACH SRCFAIL', 'UNREACH NET UNKNOWN', 'UNREACH HOST UNKNOWN', 'UNREACH ISOLATED', 'UNREACH NET PROHIB', 'UNREACH HOST PROHIB', 'UNREACH TOSNET', 'UNREACH TOSHOST', 'UNREACH FILTER PROHIB', 'UNREACH HOST PRECEDENCE', 'UNREACH PRECEDENCE CUTOFF', 'UNKNOWN ICMP UNREACH']} 

1916 tmp_code[5] = ['REDIRECT NET', 'REDIRECT HOST', 'REDIRECT TOSNET', 'REDIRECT TOSHOST'] 

1917 tmp_code[9] = ['ROUTERADVERT NORMAL', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,'ROUTERADVERT NOROUTE COMMON'] 

1918 tmp_code[11] = ['TIMXCEED INTRANS ', 'TIMXCEED REASS'] 

1919 tmp_code[12] = ['PARAMPROB ERRATPTR ', 'PARAMPROB OPTABSENT', 'PARAMPROB LENGTH'] 

1920 tmp_code[40] = [None, 'PHOTURIS UNKNOWN INDEX', 'PHOTURIS AUTH FAILED', 'PHOTURIS DECRYPT FAILED'] 

1921 if aType in tmp_code: 

1922 tmp_list = tmp_code[aType] 

1923 if ((aCode + 1) > len(tmp_list)) or (not tmp_list[aCode]): 

1924 return 'UNKNOWN' 

1925 else: 

1926 return tmp_list[aCode] 

1927 else: 

1928 return 'UNKNOWN' 

1929 

1930 def __str__(self): 

1931 tmp_type = self.get_icmp_type() 

1932 tmp_code = self.get_icmp_code() 

1933 tmp_str = 'ICMP type: ' + self.get_type_name(tmp_type) 

1934 tmp_str+= ' code: ' + self.get_code_name(tmp_type, tmp_code) 

1935 if self.child(): 

1936 tmp_str += '\n' + str( self.child() ) 

1937 return tmp_str 

1938 

1939 def isDestinationUnreachable(self): 

1940 return self.get_icmp_type() == 3 

1941 

1942 def isError(self): 

1943 return not self.isQuery() 

1944 

1945 def isHostUnreachable(self): 

1946 return self.isDestinationUnreachable() and (self.get_icmp_code() == 1) 

1947 

1948 def isNetUnreachable(self): 

1949 return self.isDestinationUnreachable() and (self.get_icmp_code() == 0) 

1950 

1951 def isPortUnreachable(self): 

1952 return self.isDestinationUnreachable() and (self.get_icmp_code() == 3) 

1953 

1954 def isProtocolUnreachable(self): 

1955 return self.isDestinationUnreachable() and (self.get_icmp_code() == 2) 

1956 

1957 def isQuery(self): 

1958 tmp_dict = {8:'', 9:'', 10:'', 13:'', 14:'', 15:'', 16:'', 17:'', 18:''} 

1959 return self.get_icmp_type() in tmp_dict 

1960 

1961class IGMP(Header): 

1962 protocol = 2 

1963 def __init__(self, aBuffer = None): 

1964 Header.__init__(self, 8) 

1965 if aBuffer: 

1966 self.load_header(aBuffer) 

1967 

1968 def get_igmp_type(self): 

1969 return self.get_byte(0) 

1970 

1971 def set_igmp_type(self, aValue): 

1972 self.set_byte(0, aValue) 

1973 

1974 def get_igmp_code(self): 

1975 return self.get_byte(1) 

1976 

1977 def set_igmp_code(self, aValue): 

1978 self.set_byte(1, aValue) 

1979 

1980 def get_igmp_cksum(self): 

1981 return self.get_word(2) 

1982 

1983 def set_igmp_cksum(self, aValue): 

1984 self.set_word(2, aValue) 

1985 

1986 def get_igmp_group(self): 

1987 return self.get_long(4) 

1988 

1989 def set_igmp_group(self, aValue): 

1990 self.set_long(4, aValue) 

1991 

1992 def get_header_size(self): 

1993 return 8 

1994 

1995 def get_type_name(self, aType): 

1996 tmp_dict = {0x11:'HOST MEMBERSHIP QUERY ', 0x12:'v1 HOST MEMBERSHIP REPORT ', 0x13:'IGMP DVMRP ', 0x14:' PIM ', 0x16:'v2 HOST MEMBERSHIP REPORT ', 0x17:'HOST LEAVE MESSAGE ', 0x1e:'MTRACE REPLY ', 0X1f:'MTRACE QUERY '} 

1997 answer = tmp_dict.get(aType, 'UNKNOWN TYPE OR VERSION ') 

1998 return answer 

1999 

2000 def calculate_checksum(self): 

2001 if self.auto_checksum and (not self.get_igmp_cksum()): 

2002 self.set_igmp_cksum(self.compute_checksum(self.get_bytes())) 

2003 

2004 def __str__(self): 

2005 tmp_str = 'IGMP: ' + self.get_type_name(self.get_igmp_type()) 

2006 tmp_str += 'Group: ' + socket.inet_ntoa(struct.pack('!L',self.get_igmp_group())) 

2007 if self.child(): 

2008 tmp_str += '\n' + str(self.child()) 

2009 return tmp_str 

2010 

2011 

2012 

2013class ARP(Header): 

2014 ethertype = 0x806 

2015 def __init__(self, aBuffer = None): 

2016 Header.__init__(self, 7) 

2017 if aBuffer: 2017 ↛ exitline 2017 didn't return from function '__init__', because the condition on line 2017 was never false

2018 self.load_header(aBuffer) 

2019 

2020 def get_ar_hrd(self): 

2021 return self.get_word(0) 

2022 

2023 def set_ar_hrd(self, aValue): 

2024 self.set_word(0, aValue) 

2025 

2026 def get_ar_pro(self): 

2027 return self.get_word(2) 

2028 

2029 def set_ar_pro(self, aValue): 

2030 self.set_word(2, aValue) 

2031 

2032 def get_ar_hln(self): 

2033 return self.get_byte(4) 

2034 

2035 def set_ar_hln(self, aValue): 

2036 self.set_byte(4, aValue) 

2037 

2038 def get_ar_pln(self): 

2039 return self.get_byte(5) 

2040 

2041 def set_ar_pln(self, aValue): 

2042 self.set_byte(5, aValue) 

2043 

2044 def get_ar_op(self): 

2045 return self.get_word(6) 

2046 

2047 def set_ar_op(self, aValue): 

2048 self.set_word(6, aValue) 

2049 

2050 def get_ar_sha(self): 

2051 tmp_size = self.get_ar_hln() 

2052 return self.get_bytes().tolist()[8: 8 + tmp_size] 

2053 

2054 def set_ar_sha(self, aValue): 

2055 for i in range(0, self.get_ar_hln()): 

2056 self.set_byte(i + 8, aValue[i]) 

2057 

2058 def get_ar_spa(self): 

2059 tmp_size = self.get_ar_pln() 

2060 return self.get_bytes().tolist()[8 + self.get_ar_hln(): 8 + self.get_ar_hln() + tmp_size] 

2061 

2062 def set_ar_spa(self, aValue): 

2063 for i in range(0, self.get_ar_pln()): 

2064 self.set_byte(i + 8 + self.get_ar_hln(), aValue[i]) 

2065 

2066 def get_ar_tha(self): 

2067 tmp_size = self.get_ar_hln() 

2068 tmp_from = 8 + self.get_ar_hln() + self.get_ar_pln() 

2069 return self.get_bytes().tolist()[tmp_from: tmp_from + tmp_size] 

2070 

2071 def set_ar_tha(self, aValue): 

2072 tmp_from = 8 + self.get_ar_hln() + self.get_ar_pln() 

2073 for i in range(0, self.get_ar_hln()): 

2074 self.set_byte(i + tmp_from, aValue[i]) 

2075 

2076 def get_ar_tpa(self): 

2077 tmp_size = self.get_ar_pln() 

2078 tmp_from = 8 + ( 2 * self.get_ar_hln()) + self.get_ar_pln() 

2079 return self.get_bytes().tolist()[tmp_from: tmp_from + tmp_size] 

2080 

2081 def set_ar_tpa(self, aValue): 

2082 tmp_from = 8 + (2 * self.get_ar_hln()) + self.get_ar_pln() 

2083 for i in range(0, self.get_ar_pln()): 

2084 self.set_byte(i + tmp_from, aValue[i]) 

2085 

2086 def get_header_size(self): 

2087 return 8 + (2 * self.get_ar_hln()) + (2 * self.get_ar_pln()) 

2088 

2089 def get_op_name(self, ar_op): 

2090 tmp_dict = {1:'REQUEST', 2:'REPLY', 3:'REVREQUEST', 4:'REVREPLY', 8:'INVREQUEST', 9:'INVREPLY'} 

2091 answer = tmp_dict.get(ar_op, 'UNKNOWN') 

2092 return answer 

2093 

2094 def get_hrd_name(self, ar_hrd): 

2095 tmp_dict = { 1:'ARPHRD ETHER', 6:'ARPHRD IEEE802', 15:'ARPHRD FRELAY'} 

2096 answer = tmp_dict.get(ar_hrd, 'UNKNOWN') 

2097 return answer 

2098 

2099 

2100 def as_hrd(self, anArray): 

2101 if not anArray: 

2102 return '' 

2103 tmp_str = '%x' % anArray[0] 

2104 for i in range(1, len(anArray)): 

2105 tmp_str += ':%x' % anArray[i] 

2106 return tmp_str 

2107 

2108 def as_pro(self, anArray): 

2109 if not anArray: 

2110 return '' 

2111 tmp_str = '%d' % anArray[0] 

2112 for i in range(1, len(anArray)): 

2113 tmp_str += '.%d' % anArray[i] 

2114 return tmp_str 

2115 

2116 def __str__(self): 

2117 tmp_op = self.get_ar_op() 

2118 tmp_str = 'ARP format: ' + self.get_hrd_name(self.get_ar_hrd()) + ' ' 

2119 tmp_str += 'opcode: ' + self.get_op_name(tmp_op) 

2120 tmp_str += '\n' + self.as_hrd(self.get_ar_sha()) + ' -> ' 

2121 tmp_str += self.as_hrd(self.get_ar_tha()) 

2122 tmp_str += '\n' + self.as_pro(self.get_ar_spa()) + ' -> ' 

2123 tmp_str += self.as_pro(self.get_ar_tpa()) 

2124 if self.child(): 

2125 tmp_str += '\n' + str(self.child()) 

2126 return tmp_str 

2127 

2128def example(): #To execute an example, remove this line 

2129 a = Ethernet() 

2130 b = ARP() 

2131 c = Data('Hola loco!!!') 

2132 b.set_ar_hln(6) 

2133 b.set_ar_pln(4) 

2134 #a.set_ip_dst('192.168.22.6') 

2135 #a.set_ip_src('1.1.1.2') 

2136 a.contains(b) 

2137 b.contains(c) 

2138 b.set_ar_op(2) 

2139 b.set_ar_hrd(1) 

2140 b.set_ar_spa((192, 168, 22, 6)) 

2141 b.set_ar_tpa((192, 168, 66, 171)) 

2142 a.set_ether_shost((0x0, 0xe0, 0x7d, 0x8a, 0xef, 0x3d)) 

2143 a.set_ether_dhost((0x0, 0xc0, 0xdf, 0x6, 0x5, 0xe)) 

2144 print("beto %s" % a)