Coverage for /root/GitHubProjects/impacket/impacket/ImpactPacket.py: 55%

# Coverage for /root/GitHubProjects/impacket/impacket/ImpactPacket.py : 55%

## 1455 statements

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# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.

2#

3# This software is provided under under a slightly modified version

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

5# for more information.

6#

7# Description:

8# Network packet codecs basic building blocks.

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

10#

11# Author:

12# Javier Burroni (javier)

13# Bruce Leidl (brl)

14# Javier Kohen (jkohen)

15 from __future__ import division

16 from __future__ import print_function

17 import array

18 import struct

19 import socket

20 import string

21 import sys

22 from binascii import hexlify

23 from functools import reduce

24

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

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

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

28 array_tobytes = lambda array_object: array_object.tobytes()

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

30 else:

31 array_tobytes = lambda array_object: array_object.tostring()

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

33

34

35"""Classes to build network packets programmatically.

36

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

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

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

40

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

42 the wire (see method get_packet).

43"""

44

45 class ImpactPacketException(Exception):

46 def __init__(self, value):

47 self.value = value

48 def __str__(self):

49 return repr(self.value)

50

51 class PacketBuffer(object):

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

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

54

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

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

57 regular Python sequence slice.

58 """

59

60 def __init__(self, length = None):

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

62 if length:

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

64 else:

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

66

67 def set_bytes_from_string(self, data):

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

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

70

71 def get_buffer_as_string(self):

72 "Returns the packet buffer as a string object"

73 return array_tobytes(self.__bytes)

74

75 def get_bytes(self):

76 "Returns the packet buffer as an array"

77 return self.__bytes

78

79 def set_bytes(self, bytes):

80 "Set the packet buffer from an array"

81 # Make a copy to be safe

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

83

84 def set_byte(self, index, value):

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

86 index = self.__validate_index(index, 1)

87 self.__bytes[index] = value

88

89 def get_byte(self, index):

90 "Return byte at 'index'"

91 index = self.__validate_index(index, 1)

92 return self.__bytes[index]

93

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

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

96 index = self.__validate_index(index, 2)

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

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

99 self.__bytes[index:] = ary

100 else:

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

102

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

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

105 index = self.__validate_index(index, 2)

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

107 bytes = self.__bytes[index:]

108 else:

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

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

111 return value

112

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

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

115 index = self.__validate_index(index, 4)

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

117 if -4 == index:

118 self.__bytes[index:] = ary

119 else:

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

121

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

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

124 index = self.__validate_index(index, 4)

125 if -4 == index:

126 bytes = self.__bytes[index:]

127 else:

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

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

130 return value

131

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

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

134 index = self.__validate_index(index, 8)

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

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

137 self.__bytes[index:] = ary

138 else:

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

140

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

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

143 index = self.__validate_index(index, 8)

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

145 bytes = self.__bytes[index:]

146 else:

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

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

149 return value

150

151

152 def get_ip_address(self, index):

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

154 index = self.__validate_index(index, 4)

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

156 bytes = self.__bytes[index:]

157 else:

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

159 return socket.inet_ntoa(array_tobytes(bytes))

160

161 def set_ip_address(self, index, ip_string):

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

163 index = self.__validate_index(index, 4)

164 raw = socket.inet_aton(ip_string)

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

166 self.set_byte(index, b1)

167 self.set_byte(index + 1, b2)

168 self.set_byte(index + 2, b3)

169 self.set_byte(index + 3, b4)

170

171 def set_checksum_from_data(self, index, data):

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

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

174

175 def compute_checksum(self, anArray):

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

177 nleft = len(anArray)

178 sum = 0

179 pos = 0

180 while nleft > 1:

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

182 pos = pos + 2

183 nleft = nleft - 2

184 if nleft == 1:

185 sum = sum + anArray[pos] * 256

186 return self.normalize_checksum(sum)

187

188 def normalize_checksum(self, aValue):

189 sum = aValue

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

191 sum += (sum >> 16)

192 sum = (~sum & 0xFFFF)

193 return sum

194

195 def __validate_index(self, index, size):

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

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

198 adjust negative indexes to their absolute equivalent.

199 """

200

201 orig_index = index

202

203 curlen = len(self.__bytes)

204 if index < 0:

205 index = curlen + index

206

207 diff = index + size - curlen

208 if diff > 0:

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

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

211 orig_index -= diff

212

213 return orig_index

214

215 class ProtocolLayer():

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

217

218 __child = None

219 __parent = None

220

221 def contains(self, aHeader):

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

223 self.__child = aHeader

224 aHeader.set_parent(self)

225

226 def set_parent(self, my_parent):

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

228 self.__parent = my_parent

229

230 def child(self):

231 "Return the child of this protocol layer"

232 return self.__child

233

234 def parent(self):

235 "Return the parent of this protocol layer"

236 return self.__parent

237

238 def unlink_child(self):

239 "Break the hierarchy parent/child child/parent"

240 if self.__child:

241 self.__child.set_parent(None)

242 self.__child = None

243

244 class ProtocolPacket(ProtocolLayer):

245 __HEADER_SIZE = 0

246 __BODY_SIZE = 0

247 __TAIL_SIZE = 0

248

249 __header = None

250 __body = None

251 __tail = None

252

253 def __init__(self, header_size, tail_size):

254 self.__HEADER_SIZE = header_size

255 self.__TAIL_SIZE = tail_size

256 self.__header=PacketBuffer(self.__HEADER_SIZE)

257 self.__body=PacketBuffer()

258 self.__tail=PacketBuffer(self.__TAIL_SIZE)

259

260 def __update_body_from_child(self):

261 # Update child raw packet in my body

262 if self.child():

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

264 self.__BODY_SIZE=len(body)

265 self.__body.set_bytes_from_string(body)

266

267 def __get_header(self):

268 return self.__header

269

270 header = property(__get_header)

271

272 def __get_body(self):

273 self.__update_body_from_child()

274 return self.__body

275

276 body = property(__get_body)

277

278 def __get_tail(self):

279 return self.__tail

280

281 tail = property(__get_tail)

282

283 def get_header_size(self):

284 "Return frame header size"

285 return self.__HEADER_SIZE

286

287 def get_tail_size(self):

288 "Return frame tail size"

289 return self.__TAIL_SIZE

290

291 def get_body_size(self):

292 "Return frame body size"

293 self.__update_body_from_child()

294 return self.__BODY_SIZE

295

296 def get_size(self):

297 "Return frame total size"

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

299

300 def load_header(self, aBuffer):

301 self.__HEADER_SIZE=len(aBuffer)

302 self.__header.set_bytes_from_string(aBuffer)

303

304 def load_body(self, aBuffer):

305 "Load the packet body from string. "\

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

307 self.unlink_child()

308 self.__BODY_SIZE=len(aBuffer)

309 self.__body.set_bytes_from_string(aBuffer)

310

311 def load_tail(self, aBuffer):

312 self.__TAIL_SIZE=len(aBuffer)

313 self.__tail.set_bytes_from_string(aBuffer)

314

315 def __extract_header(self, aBuffer):

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

317

318 def __extract_body(self, aBuffer):

319 if self.__TAIL_SIZE<=0:

320 end=None

321 else:

322 end=-self.__TAIL_SIZE

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

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

325

326 def __extract_tail(self, aBuffer):

327 if self.__TAIL_SIZE<=0:

328 # leave the array empty

329 return

330 else:

331 start=-self.__TAIL_SIZE

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

333

334 def load_packet(self, aBuffer):

335 "Load the whole packet from a string" \

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

337 self.unlink_child()

338

339 self.__extract_header(aBuffer)

340 self.__extract_body(aBuffer)

341 self.__extract_tail(aBuffer)

342

343 def get_header_as_string(self):

344 return self.__header.get_buffer_as_string()

345

346 def get_body_as_string(self):

347 self.__update_body_from_child()

348 return self.__body.get_buffer_as_string()

349 body_string = property(get_body_as_string)

350

351 def get_tail_as_string(self):

352 return self.__tail.get_buffer_as_string()

353 tail_string = property(get_tail_as_string)

354

355 def get_packet(self):

356 self.__update_body_from_child()

357

358 ret = b''

359

360 header = self.get_header_as_string()

361 if header:

362 ret += header

363

364 body = self.get_body_as_string()

365 if body:

366 ret += body

367

368 tail = self.get_tail_as_string()

369 if tail:

370 ret += tail

371

372 return ret

373

374 class Header(PacketBuffer,ProtocolLayer):

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

376

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

378

379 ethertype = None

380 protocol = None

381 def __init__(self, length = None):

382 PacketBuffer.__init__(self, length)

383 self.auto_checksum = 1

384

385 def get_data_as_string(self):

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

387

388 if self.child():

389 return self.child().get_packet()

390 else:

391 return None

392

393 def get_packet(self):

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

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

396 ready to be transmitted over the wire.

397 """

398 self.calculate_checksum()

399

400 data = self.get_data_as_string()

401 if data:

402 return self.get_buffer_as_string() + data

403 else:

404 return self.get_buffer_as_string()

405

406 def get_size(self):

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

408 tmp_value = self.get_header_size()

409 if self.child():

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

411 return tmp_value

412

413 def calculate_checksum(self):

414 "Calculate and set the checksum for this header"

415 pass

416

417 def get_pseudo_header(self):

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

419 # default implementation returns empty array

420 return array.array('B')

421

422 def load_header(self, aBuffer):

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

424 self.set_bytes_from_string(aBuffer)

425 hdr_len = self.get_header_size()

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

427 diff = hdr_len - len(aBuffer)

428 for i in range(0, diff):

429 aBuffer += '\x00'

430 self.set_bytes_from_string(aBuffer[:hdr_len])

431

432 def get_header_size(self):

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

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

435

436 def list_as_hex(self, aList):

437 if len(aList):

438 ltmp = []

439 line = []

440 count = 0

441 for byte in aList:

442 if not (count % 2):

443 if (count % 16):

444 ltmp.append(' ')

445 else:

446 ltmp.append(' '*4)

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

448 ltmp.append('\n')

449 line = []

450 if chr(byte) in Header.packet_printable:

451 line.append(chr(byte))

452 else:

453 line.append('.')

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

455 count += 1

456 if (count%16):

457 left = 16 - (count%16)

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

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

460 ltmp.append('\n')

461 return ltmp

462 else:

463 return []

464

465 def __str__(self):

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

467

468 if self.child():

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

470

471 if len(ltmp)>0:

472 return ''.join(ltmp)

473 else:

474 return ''

475

476

477

478 class Data(Header):

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

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

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

482 valid packet available.

483

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

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

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

487 fragment:

488 packet = UDP()

489 packet.contains('HELLO')

490 """

491

492 def __init__(self, aBuffer = None):

493 Header.__init__(self)

494 if aBuffer:

495 self.set_data(aBuffer)

496

497 def set_data(self, data):

498 self.set_bytes_from_string(data)

499

500 def get_size(self):

501 return len(self.get_bytes())

502

503

504 class EthernetTag(PacketBuffer):

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

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

507

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

509 PacketBuffer.__init__(self, 4)

510 self.set_long(0, value)

511

512 def get_tpid(self):

513 """Returns Tag Protocol Identifier"""

514 return self.get_word(0)

515

516 def set_tpid(self, value):

517 """Sets Tag Protocol Identifier"""

518 return self.set_word(0, value)

519

520 def get_pcp(self):

521 """Returns Priority Code Point"""

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

523

524 def set_pcp(self, value):

525 """Sets Priority Code Point"""

526 orig_value = self.get_byte(2)

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

528

529 def get_dei(self):

530 """Returns Drop Eligible Indicator"""

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

532

533 def set_dei(self, value):

534 """Sets Drop Eligible Indicator"""

535 orig_value = self.get_byte(2)

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

537

538 def get_vid(self):

539 """Returns VLAN Identifier"""

540 return self.get_word(2) & 0x0FFF

541

542 def set_vid(self, value):

543 """Sets VLAN Identifier"""

544 orig_value = self.get_word(2)

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

546

547 def __str__(self):

548 priorities = (

549 'Best Effort',

550 'Background',

551 'Excellent Effort',

552 'Critical Applications',

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

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

555 'Internetwork Control',

556 'Network Control')

557

558 pcp = self.get_pcp()

559 return '\n'.join((

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

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

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

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

564

565

566 class Ethernet(Header):

567 def __init__(self, aBuffer = None):

568 Header.__init__(self, 14)

569 self.tag_cnt = 0

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

571 self.load_header(aBuffer)

572

573 def set_ether_type(self, aValue):

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

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

576

577 def get_ether_type(self):

578 "Return ethernet data type field"

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

580

581 def get_tag(self, index):

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

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

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

585 index = self.__validate_tag_index(index)

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

587

588 def set_tag(self, index, tag):

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

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

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

592 index = self.__validate_tag_index(index)

593 pos = 12 + 4*index

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

595 self.set_byte(pos+i, val)

596

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

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

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

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

601 index += self.tag_cnt

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

603 data = self.get_bytes()

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

605 self.set_bytes(data)

606 self.tag_cnt += 1

607

608 def pop_tag(self, index=0):

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

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

611 index = self.__validate_tag_index(index)

612 pos = 12 + 4*index

613 tag = self.get_long(pos)

614 data = self.get_bytes()

615 del data[pos: pos+4]

616 self.set_bytes(data)

617 self.tag_cnt -= 1

618 return EthernetTag(tag)

619

620 def load_header(self, aBuffer):

621 self.tag_cnt = 0

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

623 self.tag_cnt += 1

624

625 hdr_len = self.get_header_size()

626 diff = hdr_len - len(aBuffer)

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

628 aBuffer += b'\x00'*diff

629 self.set_bytes_from_string(aBuffer[:hdr_len])

630

631 def get_header_size(self):

632 "Return size of Ethernet header"

633 return 14 + 4*self.tag_cnt

634

635 def get_packet(self):

636

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

638 try:

639 self.set_ether_type(self.child().ethertype)

640 except:

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

642 pass

643 return Header.get_packet(self)

644

645 def get_ether_dhost(self):

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

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

648

649 def set_ether_dhost(self, aValue):

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

651 for i in range(0, 6):

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

653

654 def get_ether_shost(self):

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

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

657

658 def set_ether_shost(self, aValue):

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

660 for i in range(0, 6):

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

662

663 @staticmethod

664 def as_eth_addr(anArray):

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

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

667

668 def __str__(self):

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

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

671 if self.child():

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

673 return tmp_str

674

675 def __validate_tag_index(self, index):

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

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

678 if index < 0:

679 index += self.tag_cnt

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

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

682 return index

683

684# Linux "cooked" capture encapsulation.

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

686 class LinuxSLL(Header):

687 type_descriptions = [

688 "sent to us by somebody else",

689 "broadcast by somebody else",

690 "multicast by somebody else",

691 "sent to somebody else to somebody else",

692 "sent by us",

693 ]

694

695 def __init__(self, aBuffer = None):

696 Header.__init__(self, 16)

697 if (aBuffer):

698 self.load_header(aBuffer)

699

700 def set_type(self, type):

701 "Sets the packet type field to type"

702 self.set_word(0, type)

703

704 def get_type(self):

705 "Returns the packet type field"

706 return self.get_word(0)

707

708 def set_arphdr(self, value):

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

710 self.set_word(2, type)

711

712 def get_arphdr(self):

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

714 return self.get_word(2)

715

716 def set_addr_len(self, len):

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

718 self.set_word(4, len)

719

720 def get_addr_len(self):

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

722 return self.get_word(4)

723

724 def set_addr(self, addr):

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

726 if (len(addr) < 8):

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

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

729

730 def get_addr(self):

731 "Returns the sender's address field"

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

733

734 def set_ether_type(self, aValue):

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

736 self.set_word(14, aValue)

737

738 def get_ether_type(self):

739 "Return ethernet data type field"

740 return self.get_word(14)

741

742 def get_header_size(self):

743 "Return size of packet header"

744 return 16

745

746 def get_packet(self):

747 if self.child():

748 self.set_ether_type(self.child().ethertype)

749 return Header.get_packet(self)

750

751 def get_type_desc(self):

752 type = self.get_type()

753 if type < len(LinuxSLL.type_descriptions):

754 return LinuxSLL.type_descriptions[type]

755 else:

756 return "Unknown"

757

758 def __str__(self):

759 ss = []

760 alen = self.get_addr_len()

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

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

763 if self.child():

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

765

766 return '\n'.join(ss)

767

768

769 class IP(Header):

770 ethertype = 0x800

771 def __init__(self, aBuffer = None):

772 Header.__init__(self, 20)

773 self.set_ip_v(4)

774 self.set_ip_hl(5)

775 self.set_ip_ttl(255)

776 self.__option_list = []

777 if(aBuffer):

778 # When decoding, checksum shouldn't be modified

779 self.auto_checksum = 0

780 self.load_header(aBuffer)

781

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

783 self.is_BSD = True

784 else:

785 self.is_BSD = False

786

787

788 def get_packet(self):

789 # set protocol

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

791 self.set_ip_p(self.child().protocol)

792

793 # set total length

794 if self.get_ip_len() == 0:

795 self.set_ip_len(self.get_size())

796

797 child_data = self.get_data_as_string()

798

799 if self.auto_checksum:

800 self.reset_ip_sum()

801

802 my_bytes = self.get_bytes()

803

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

805 my_bytes.extend(op.get_bytes())

806

807 # Pad to a multiple of 4 bytes

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

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

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

811

812 # only change ip_hl value if options are present

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

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

815

816

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

818 if self.auto_checksum:

819 self.set_ip_sum(self.compute_checksum(my_bytes))

820

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

822 return array_tobytes(my_bytes)

823 else:

824 return array_tobytes(my_bytes) + child_data

825

826

827

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

829 # tmp_value = self.get_ip_sum()

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

831 # if buffer:

832 # tmp_bytes = buffer

833 # else:

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

835 #

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

837

838

839 def get_pseudo_header(self):

840 pseudo_buf = array.array("B")

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

842 pseudo_buf.fromlist([0])

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

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

845

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

847

848 array_frombytes(pseudo_buf, size_str)

849 return pseudo_buf

850

851 def add_option(self, option):

852 self.__option_list.append(option)

853 sum = 0

854 for op in self.__option_list:

855 sum += op.get_len()

856 if sum > 40:

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

858

859

860 def get_ip_v(self):

861 n = self.get_byte(0)

862 return (n >> 4)

863

864 def set_ip_v(self, value):

865 n = self.get_byte(0)

866 version = value & 0xF

867 n = n & 0xF

868 n = n | (version << 4)

869 self.set_byte(0, n)

870

871 def get_ip_hl(self):

872 n = self.get_byte(0)

873 return (n & 0xF)

874

875 def set_ip_hl(self, value):

876 n = self.get_byte(0)

877 len = value & 0xF

878 n = n & 0xF0

879 n = (n | len)

880 self.set_byte(0, n)

881

882 def get_ip_tos(self):

883 return self.get_byte(1)

884

885 def set_ip_tos(self,value):

886 self.set_byte(1, value)

887

888 def get_ip_len(self):

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

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

891 else:

892 return self.get_word(2)

893

894 def set_ip_len(self, value):

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

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

897 else:

898 self.set_word(2, value)

899

900 def get_ip_id(self):

901 return self.get_word(4)

902 def set_ip_id(self, value):

903 return self.set_word(4, value)

904

905 def get_ip_off(self):

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

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

908 else:

909 return self.get_word(6)

910

911 def set_ip_off(self, aValue):

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

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

914 else:

915 self.set_word(6, aValue)

916

917 def get_ip_offmask(self):

918 return self.get_ip_off() & 0x1FFF

919

920 def set_ip_offmask(self, aValue):

921 tmp_value = self.get_ip_off() & 0xD000

922 tmp_value |= aValue

923 self.set_ip_off(tmp_value)

924

925 def get_ip_rf(self):

926 return self.get_ip_off() & 0x8000

927

928 def set_ip_rf(self, aValue):

929 tmp_value = self.get_ip_off()

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

931 tmp_value |= 0x8000

932 else:

933 my_not = 0xFFFF ^ 0x8000

934 tmp_value &= my_not

935 self.set_ip_off(tmp_value)

936

937 def get_ip_df(self):

938 return self.get_ip_off() & 0x4000

939

940 def set_ip_df(self, aValue):

941 tmp_value = self.get_ip_off()

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

943 tmp_value |= 0x4000

944 else:

945 my_not = 0xFFFF ^ 0x4000

946 tmp_value &= my_not

947 self.set_ip_off(tmp_value)

948

949 def get_ip_mf(self):

950 return self.get_ip_off() & 0x2000

951

952 def set_ip_mf(self, aValue):

953 tmp_value = self.get_ip_off()

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

955 tmp_value |= 0x2000

956 else:

957 my_not = 0xFFFF ^ 0x2000

958 tmp_value &= my_not

959 self.set_ip_off(tmp_value)

960

961

962 def fragment_by_list(self, aList):

963 if self.child():

964 proto = self.child().protocol

965 else:

966 proto = 0

967

968 child_data = self.get_data_as_string()

969 if not child_data:

970 return [self]

971

972 ip_header_bytes = self.get_bytes()

973 current_offset = 0

974 fragment_list = []

975

976 for frag_size in aList:

977 ip = IP()

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

979 ip.set_ip_p(proto)

980

981

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

983 frag_size += 8 - (frag_size % 8)

984

985

986 ip.set_ip_offmask(current_offset // 8)

987 current_offset += frag_size

988

989 data = Data(child_data[:frag_size])

990 child_data = child_data[frag_size:]

991

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

993 ip.contains(data)

994

995

996 if child_data:

997

998 ip.set_ip_mf(1)

999

1000 fragment_list.append(ip)

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

1002

1003 ip.set_ip_mf(0)

1004

1005 fragment_list.append(ip)

1006 return fragment_list

1007

1008 if child_data: # any remaining data?

1009 # create a fragment containing all of the remaining child_data

1010 ip = IP()

1011 ip.set_bytes(ip_header_bytes)

1012 ip.set_ip_offmask(current_offset)

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

1014 data = Data(child_data)

1015 ip.contains(data)

1016 fragment_list.append(ip)

1017

1018 return fragment_list

1019

1020

1021 def fragment_by_size(self, aSize):

1022 data_len = len(self.get_data_as_string())

1023 num_frags = data_len // aSize

1024

1025 if data_len % aSize:

1026 num_frags += 1

1027

1028 size_list = []

1029 for i in range(0, num_frags):

1030 size_list.append(aSize)

1031 return self.fragment_by_list(size_list)

1032

1033

1034 def get_ip_ttl(self):

1035 return self.get_byte(8)

1036 def set_ip_ttl(self, value):

1037 self.set_byte(8, value)

1038

1039 def get_ip_p(self):

1040 return self.get_byte(9)

1041

1042 def set_ip_p(self, value):

1043 self.set_byte(9, value)

1044

1045 def get_ip_sum(self):

1046 return self.get_word(10)

1047 def set_ip_sum(self, value):

1048 self.auto_checksum = 0

1049 self.set_word(10, value)

1050

1051 def reset_ip_sum(self):

1052 self.set_ip_sum(0x0000)

1053 self.auto_checksum = 1

1054

1055 def get_ip_src(self):

1056 return self.get_ip_address(12)

1057 def set_ip_src(self, value):

1058 self.set_ip_address(12, value)

1059

1060 def get_ip_dst(self):

1061 return self.get_ip_address(16)

1062

1063 def set_ip_dst(self, value):

1064 self.set_ip_address(16, value)

1065

1066 def get_header_size(self):

1067 op_len = 0

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

1069 op_len += op.get_len()

1070

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

1072

1073 return 20 + op_len + num_pad

1074

1075 def load_header(self, aBuffer):

1076 self.set_bytes_from_string(aBuffer[:20])

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

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

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

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

1081

1082

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

1084 op_type = opt_bytes[0]

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

1086 new_option = IPOption(op_type)

1087 op_len = 1

1088 else:

1089 op_len = opt_bytes[1]

1090 if op_len > len(opt_bytes):

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

1092

1093 new_option = IPOption(op_type, op_len)

1094 new_option.set_bytes(opt_bytes[:op_len])

1095

1096 opt_bytes = opt_bytes[op_len:]

1097 opt_left -= op_len

1098 self.add_option(new_option)

1099 if op_type == IPOption.IPOPT_EOL:

1100 break

1101

1102

1103 def __str__(self):

1104 flags = ' '

1105 if self.get_ip_df():

1106 flags += 'DF '

1107 if self.get_ip_mf():

1108 flags += 'MF '

1109 if self.get_ip_rf():

1110 flags += 'RF '

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

1112 for op in self.__option_list:

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

1114 if self.child():

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

1116 return tmp_str

1117

1118

1119 class IPOption(PacketBuffer):

1120 IPOPT_EOL = 0

1121 IPOPT_NOP = 1

1122 IPOPT_RR = 7

1123 IPOPT_TS = 68

1124 IPOPT_LSRR = 131

1125 IPOPT_SSRR = 137

1126

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

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

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

1130

1131 if(opcode == IPOption.IPOPT_EOL):

1132 PacketBuffer.__init__(self, 1)

1133 self.set_code(IPOption.IPOPT_EOL)

1134 elif(opcode == IPOption.IPOPT_NOP):

1135 PacketBuffer.__init__(self, 1)

1136 self.set_code(IPOption.IPOPT_NOP)

1137 elif(opcode == IPOption.IPOPT_RR):

1138 if not size:

1139 size = 39

1140 PacketBuffer.__init__(self, size)

1141 self.set_code(IPOption.IPOPT_RR)

1142 self.set_len(size)

1143 self.set_ptr(4)

1144

1145 elif(opcode == IPOption.IPOPT_LSRR):

1146 if not size:

1147 size = 39

1148 PacketBuffer.__init__(self, size)

1149 self.set_code(IPOption.IPOPT_LSRR)

1150 self.set_len(size)

1151 self.set_ptr(4)

1152

1153 elif(opcode == IPOption.IPOPT_SSRR):

1154 if not size:

1155 size = 39

1156 PacketBuffer.__init__(self, size)

1157 self.set_code(IPOption.IPOPT_SSRR)

1158 self.set_len(size)

1159 self.set_ptr(4)

1160

1161 elif(opcode == IPOption.IPOPT_TS):

1162 if not size:

1163 size = 40

1164 PacketBuffer.__init__(self, size)

1165 self.set_code(IPOption.IPOPT_TS)

1166 self.set_len(size)

1167 self.set_ptr(5)

1168 self.set_flags(0)

1169 else:

1170 if not size:

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

1172 PacketBuffer.__init__(self,size)

1173 self.set_code(opcode)

1174 self.set_len(size)

1175

1176

1177 def append_ip(self, ip):

1178 op = self.get_code()

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

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

1181

1182 p = self.get_ptr()

1183 if not p:

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

1185

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

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

1188

1189 self.set_ip_address(p - 1, ip)

1190 p += 4

1191 self.set_ptr(p)

1192

1193

1194 def set_code(self, value):

1195 self.set_byte(0, value)

1196

1197 def get_code(self):

1198 return self.get_byte(0)

1199

1200

1201 def set_flags(self, flags):

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

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

1204 self.set_byte(3, flags)

1205

1206 def get_flags(self, flags):

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

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

1209 return self.get_byte(3)

1210

1211

1212 def set_len(self, len):

1213 self.set_byte(1, len)

1214

1215

1216 def set_ptr(self, ptr):

1217 self.set_byte(2, ptr)

1218

1219 def get_ptr(self):

1220 return self.get_byte(2)

1221

1222 def get_len(self):

1223 return len(self.get_bytes())

1224

1225

1226 def __str__(self):

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

1228 IPOption.IPOPT_NOP : "No Operation ",

1229 IPOption.IPOPT_RR : "Record Route ",

1230 IPOption.IPOPT_TS : "Timestamp ",

1231 IPOption.IPOPT_LSRR : "Loose Source Route ",

1232 IPOption.IPOPT_SSRR : "Strict Source Route "}

1233

1234 tmp_str = "\tIP Option: "

1235 op = self.get_code()

1236 if op in map:

1237 tmp_str += map[op]

1238 else:

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

1240

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

1242 tmp_str += self.print_addresses()

1243

1244

1245 return tmp_str

1246

1247

1248 def print_addresses(self):

1249 p = 3

1250 tmp_str = "["

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

1252 while 1:

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

1254 tmp_str += "#"

1255 tmp_str += self.get_ip_address(p)

1256 p += 4

1257 if p >= self.get_len():

1258 break

1259 else:

1260 tmp_str += ", "

1261 tmp_str += "] "

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

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

1264 return tmp_str

1265

1266

1267 class UDP(Header):

1268 protocol = 17

1269 def __init__(self, aBuffer = None):

1270 Header.__init__(self, 8)

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

1272 self.load_header(aBuffer)

1273

1274 def get_uh_sport(self):

1275 return self.get_word(0)

1276 def set_uh_sport(self, value):

1277 self.set_word(0, value)

1278

1279 def get_uh_dport(self):

1280 return self.get_word(2)

1281 def set_uh_dport(self, value):

1282 self.set_word(2, value)

1283

1284 def get_uh_ulen(self):

1285 return self.get_word(4)

1286

1287 def set_uh_ulen(self, value):

1288 self.set_word(4, value)

1289

1290 def get_uh_sum(self):

1291 return self.get_word(6)

1292

1293 def set_uh_sum(self, value):

1294 self.set_word(6, value)

1295 self.auto_checksum = 0

1296

1297 def calculate_checksum(self):

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

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

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

1301 if not self.parent():

1302 return

1303

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

1305

1306 buffer += self.get_bytes()

1307 data = self.get_data_as_string()

1308 if(data):

1309 array_frombytes(buffer, data)

1310 self.set_uh_sum(self.compute_checksum(buffer))

1311

1312 def get_header_size(self):

1313 return 8

1314

1315 def __str__(self):

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

1317 if self.child():

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

1319 return tmp_str

1320

1321 def get_packet(self):

1322 # set total length

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

1324 self.set_uh_ulen(self.get_size())

1325 return Header.get_packet(self)

1326

1327 class TCP(Header):

1328 protocol = 6

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

1330 def __init__(self, aBuffer = None):

1331 Header.__init__(self, 20)

1332 self.set_th_off(5)

1333 self.__option_list = []

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

1335 self.load_header(aBuffer)

1336

1337 def add_option(self, option):

1338 self.__option_list.append(option)

1339

1340 sum = 0

1341 for op in self.__option_list:

1342 sum += op.get_size()

1343

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

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

1346

1347 def get_options(self):

1348 return self.__option_list

1349

1350 def swapSourceAndDestination(self):

1351 oldSource = self.get_th_sport()

1352 self.set_th_sport(self.get_th_dport())

1353 self.set_th_dport(oldSource)

1354

1355 #

1356 # Header field accessors

1357 #

1358

1359 def set_th_sport(self, aValue):

1360 self.set_word(0, aValue)

1361

1362 def get_th_sport(self):

1363 return self.get_word(0)

1364

1365 def get_th_dport(self):

1366 return self.get_word(2)

1367

1368 def set_th_dport(self, aValue):

1369 self.set_word(2, aValue)

1370

1371 def get_th_seq(self):

1372 return self.get_long(4)

1373

1374 def set_th_seq(self, aValue):

1375 self.set_long(4, aValue)

1376

1377 def get_th_ack(self):

1378 return self.get_long(8)

1379

1380 def set_th_ack(self, aValue):

1381 self.set_long(8, aValue)

1382

1383 def get_th_flags(self):

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

1385

1386 def set_th_flags(self, aValue):

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

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

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

1390

1391 def get_th_win(self):

1392 return self.get_word(14)

1393

1394 def set_th_win(self, aValue):

1395 self.set_word(14, aValue)

1396

1397 def set_th_sum(self, aValue):

1398 self.set_word(16, aValue)

1399 self.auto_checksum = 0

1400

1401 def get_th_sum(self):

1402 return self.get_word(16)

1403

1404 def get_th_urp(self):

1405 return self.get_word(18)

1406

1407 def set_th_urp(self, aValue):

1408 return self.set_word(18, aValue)

1409

1410 # Flag accessors

1411

1412 def get_th_reserved(self):

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

1414 return tmp_value

1415

1416

1417 def get_th_off(self):

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

1419 return tmp_value

1420

1421 def set_th_off(self, aValue):

1422 mask = 0xF0

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

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

1425 return self.set_byte(12, nb)

1426

1427 def get_CWR(self):

1428 return self.get_flag(128)

1429 def set_CWR(self):

1430 return self.set_flags(128)

1431 def reset_CWR(self):

1432 return self.reset_flags(128)

1433

1434 def get_ECE(self):

1435 return self.get_flag(64)

1436 def set_ECE(self):

1437 return self.set_flags(64)

1438 def reset_ECE(self):

1439 return self.reset_flags(64)

1440

1441 def get_URG(self):

1442 return self.get_flag(32)

1443 def set_URG(self):

1444 return self.set_flags(32)

1445 def reset_URG(self):

1446 return self.reset_flags(32)

1447

1448 def get_ACK(self):

1449 return self.get_flag(16)

1450 def set_ACK(self):

1451 return self.set_flags(16)

1452 def reset_ACK(self):

1453 return self.reset_flags(16)

1454

1455 def get_PSH(self):

1456 return self.get_flag(8)

1457 def set_PSH(self):

1458 return self.set_flags(8)

1459 def reset_PSH(self):

1460 return self.reset_flags(8)

1461

1462 def get_RST(self):

1463 return self.get_flag(4)

1464 def set_RST(self):

1465 return self.set_flags(4)

1466 def reset_RST(self):

1467 return self.reset_flags(4)

1468

1469 def get_SYN(self):

1470 return self.get_flag(2)

1471 def set_SYN(self):

1472 return self.set_flags(2)

1473 def reset_SYN(self):

1474 return self.reset_flags(2)

1475

1476 def get_FIN(self):

1477 return self.get_flag(1)

1478 def set_FIN(self):

1479 return self.set_flags(1)

1480 def reset_FIN(self):

1481 return self.reset_flags(1)

1482

1483 # Overridden Methods

1484

1485 def get_header_size(self):

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

1487

1488 def calculate_checksum(self):

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

1490 return

1491

1492 self.set_th_sum(0)

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

1494 buffer += self.get_bytes()

1495 buffer += self.get_padded_options()

1496

1497 data = self.get_data_as_string()

1498 if(data):

1499 array_frombytes(buffer, data)

1500

1501 res = self.compute_checksum(buffer)

1502

1503 self.set_th_sum(self.compute_checksum(buffer))

1504

1505 def get_packet(self):

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

1507

1508 # only change th_off value if options are present

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

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

1511

1512 self.calculate_checksum()

1513

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

1515 data = self.get_data_as_string()

1516

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

1518 return array_tobytes(bytes) + data

1519 else:

1520 return array_tobytes(bytes)

1521

1522 def load_header(self, aBuffer):

1523 self.set_bytes_from_string(aBuffer[:20])

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

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

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

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

1528

1529 while opt_left:

1530 op_kind = opt_bytes[0]

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

1532 new_option = TCPOption(op_kind)

1533 op_len = 1

1534 else:

1535 op_len = opt_bytes[1]

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

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

1538 if op_len < 2: 1538 ↛ 1539line 1538 didn't jump to line 1539, because the condition on line 1538 was never true

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

1540

1541 new_option = TCPOption(op_kind)

1542 new_option.set_bytes(opt_bytes[:op_len])

1543

1544 opt_bytes = opt_bytes[op_len:]

1545 opt_left -= op_len

1546 self.add_option(new_option)

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

1548 break

1549

1550 #

1551 # Private

1552 #

1553

1554 def get_flag(self, bit):

1555 if self.get_th_flags() & bit:

1556 return 1

1557 else:

1558 return 0

1559

1560 def reset_flags(self, aValue):

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

1562 return self.set_th_flags(tmp_value)

1563

1564 def set_flags(self, aValue):

1565 tmp_value = self.get_th_flags() | aValue

1566 return self.set_th_flags(tmp_value)

1567

1568 def get_padded_options(self):

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

1570 op_buf = array.array('B')

1571 for op in self.__option_list:

1572 op_buf += op.get_bytes()

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

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

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

1576 return op_buf

1577

1578 def __str__(self):

1579 tmp_str = 'TCP '

1580 if self.get_ECE():

1581 tmp_str += 'ece '

1582 if self.get_CWR():

1583 tmp_str += 'cwr '

1584 if self.get_ACK():

1585 tmp_str += 'ack '

1586 if self.get_FIN():

1587 tmp_str += 'fin '

1588 if self.get_PSH():

1589 tmp_str += 'push '

1590 if self.get_RST():

1591 tmp_str += 'rst '

1592 if self.get_SYN():

1593 tmp_str += 'syn '

1594 if self.get_URG():

1595 tmp_str += 'urg '

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

1597 for op in self.__option_list:

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

1599

1600 if self.child():

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

1602 return tmp_str

1603

1604

1605 class TCPOption(PacketBuffer):

1606 TCPOPT_EOL = 0

1607 TCPOPT_NOP = 1

1608 TCPOPT_MAXSEG = 2

1609 TCPOPT_WINDOW = 3

1610 TCPOPT_SACK_PERMITTED = 4

1611 TCPOPT_SACK = 5

1612 TCPOPT_TIMESTAMP = 8

1613 TCPOPT_SIGNATURE = 19

1614

1615

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

1617

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

1619 PacketBuffer.__init__(self, 1)

1620 self.set_kind(TCPOption.TCPOPT_EOL)

1621 elif kind == TCPOption.TCPOPT_NOP:

1622 PacketBuffer.__init__(self, 1)

1623 self.set_kind(TCPOption.TCPOPT_NOP)

1624 elif kind == TCPOption.TCPOPT_MAXSEG:

1625 PacketBuffer.__init__(self, 4)

1626 self.set_kind(TCPOption.TCPOPT_MAXSEG)

1627 self.set_len(4)

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

1629 self.set_mss(data)

1630 else:

1631 self.set_mss(512)

1632 elif kind == TCPOption.TCPOPT_WINDOW:

1633 PacketBuffer.__init__(self, 3)

1634 self.set_kind(TCPOption.TCPOPT_WINDOW)

1635 self.set_len(3)

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

1637 self.set_shift_cnt(data)

1638 else:

1639 self.set_shift_cnt(0)

1640 elif kind == TCPOption.TCPOPT_TIMESTAMP:

1641 PacketBuffer.__init__(self, 10)

1642 self.set_kind(TCPOption.TCPOPT_TIMESTAMP)

1643 self.set_len(10)

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

1645 self.set_ts(data)

1646 else:

1647 self.set_ts(0)

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

1649 PacketBuffer.__init__(self, 2)

1650 self.set_kind(TCPOption.TCPOPT_SACK_PERMITTED)

1651 self.set_len(2)

1652

1653 elif kind == TCPOption.TCPOPT_SACK:

1654 PacketBuffer.__init__(self, 2)

1655 self.set_kind(TCPOption.TCPOPT_SACK)

1656

1657 def set_left_edge(self, aValue):

1658 self.set_long (2, aValue)

1659

1660 def set_right_edge(self, aValue):

1661 self.set_long (6, aValue)

1662

1663 def set_kind(self, kind):

1664 self.set_byte(0, kind)

1665

1666

1667 def get_kind(self):

1668 return self.get_byte(0)

1669

1670

1671 def set_len(self, len):

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

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

1674 self.set_byte(1, len)

1675

1676 def get_len(self):

1677 if self.get_size() < 2:

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

1679 return self.get_byte(1)

1680

1681 def get_size(self):

1682 return len(self.get_bytes())

1683

1684

1685 def set_mss(self, len):

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

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

1688 self.set_word(2, len)

1689

1690 def get_mss(self):

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

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

1693 return self.get_word(2)

1694

1695 def set_shift_cnt(self, cnt):

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

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

1698 self.set_byte(2, cnt)

1699

1700 def get_shift_cnt(self):

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

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

1703 return self.get_byte(2)

1704

1705 def get_ts(self):

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

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

1708 return self.get_long(2)

1709

1710 def set_ts(self, ts):

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

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

1713 self.set_long(2, ts)

1714

1715 def get_ts_echo(self):

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

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

1718 return self.get_long(6)

1719

1720 def set_ts_echo(self, ts):

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

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

1723 self.set_long(6, ts)

1724

1725 def __str__(self):

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

1727 TCPOption.TCPOPT_NOP : "No Operation ",

1728 TCPOption.TCPOPT_MAXSEG : "Maximum Segment Size ",

1729 TCPOption.TCPOPT_WINDOW : "Window Scale ",

1730 TCPOption.TCPOPT_TIMESTAMP : "Timestamp " }

1731

1732 tmp_str = "\tTCP Option: "

1733 op = self.get_kind()

1734 if op in map:

1735 tmp_str += map[op]

1736 else:

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

1738 if op == TCPOption.TCPOPT_MAXSEG:

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

1740 elif op == TCPOption.TCPOPT_WINDOW:

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

1742 elif op == TCPOption.TCPOPT_TIMESTAMP:

1743 pass # TODO

1744 return tmp_str

1745

1746 class ICMP(Header):

1747 protocol = 1

1748 ICMP_ECHOREPLY = 0

1749 ICMP_UNREACH = 3

1750 ICMP_UNREACH_NET = 0

1751 ICMP_UNREACH_HOST = 1

1752 ICMP_UNREACH_PROTOCOL = 2

1753 ICMP_UNREACH_PORT = 3

1754 ICMP_UNREACH_NEEDFRAG = 4

1755 ICMP_UNREACH_SRCFAIL = 5

1756 ICMP_UNREACH_NET_UNKNOWN = 6

1757 ICMP_UNREACH_HOST_UNKNOWN = 7

1758 ICMP_UNREACH_ISOLATED = 8

1759 ICMP_UNREACH_NET_PROHIB = 9

1760 ICMP_UNREACH_HOST_PROHIB = 10

1761 ICMP_UNREACH_TOSNET = 11

1762 ICMP_UNREACH_TOSHOST = 12

1763 ICMP_UNREACH_FILTERPROHIB = 13

1764 ICMP_UNREACH_HOST_PRECEDENCE = 14

1765 ICMP_UNREACH_PRECEDENCE_CUTOFF = 15

1766 ICMP_SOURCEQUENCH = 4

1767 ICMP_REDIRECT = 5

1768 ICMP_REDIRECT_NET = 0

1769 ICMP_REDIRECT_HOST = 1

1770 ICMP_REDIRECT_TOSNET = 2

1771 ICMP_REDIRECT_TOSHOST = 3

1772 ICMP_ALTHOSTADDR = 6

1773 ICMP_ECHO = 8

1774 ICMP_ROUTERADVERT = 9

1775 ICMP_ROUTERSOLICIT = 10

1776 ICMP_TIMXCEED = 11

1777 ICMP_TIMXCEED_INTRANS = 0

1778 ICMP_TIMXCEED_REASS = 1

1779 ICMP_PARAMPROB = 12

1780 ICMP_PARAMPROB_ERRATPTR = 0

1781 ICMP_PARAMPROB_OPTABSENT = 1

1782 ICMP_PARAMPROB_LENGTH = 2

1783 ICMP_TSTAMP = 13

1784 ICMP_TSTAMPREPLY = 14

1785 ICMP_IREQ = 15

1786 ICMP_IREQREPLY = 16

1787 ICMP_MASKREQ = 17

1788 ICMP_MASKREPLY = 18

1789

1790 def __init__(self, aBuffer = None):

1791 Header.__init__(self, 8)

1792 if aBuffer:

1793 self.load_header(aBuffer)

1794

1795 def get_header_size(self):

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

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

1798 return anamolies[self.get_icmp_type()]

1799 else:

1800 return 8

1801

1802 def get_icmp_type(self):

1803 return self.get_byte(0)

1804

1805 def set_icmp_type(self, aValue):

1806 self.set_byte(0, aValue)

1807

1808 def get_icmp_code(self):

1809 return self.get_byte(1)

1810

1811 def set_icmp_code(self, aValue):

1812 self.set_byte(1, aValue)

1813

1814 def get_icmp_cksum(self):

1815 return self.get_word(2)

1816

1817 def set_icmp_cksum(self, aValue):

1818 self.set_word(2, aValue)

1819 self.auto_checksum = 0

1820

1821 def get_icmp_gwaddr(self):

1822 return self.get_ip_address(4)

1823

1824 def set_icmp_gwaddr(self, ip):

1825 self.set_ip_address(4, ip)

1826

1827 def get_icmp_id(self):

1828 return self.get_word(4)

1829

1830 def set_icmp_id(self, aValue):

1831 self.set_word(4, aValue)

1832

1833 def get_icmp_seq(self):

1834 return self.get_word(6)

1835

1836 def set_icmp_seq(self, aValue):

1837 self.set_word(6, aValue)

1838

1839 def get_icmp_void(self):

1840 return self.get_long(4)

1841

1842 def set_icmp_void(self, aValue):

1843 self.set_long(4, aValue)

1844

1845

1846 def get_icmp_nextmtu(self):

1847 return self.get_word(6)

1848

1849 def set_icmp_nextmtu(self, aValue):

1850 self.set_word(6, aValue)

1851

1852 def get_icmp_num_addrs(self):

1853 return self.get_byte(4)

1854

1855 def set_icmp_num_addrs(self, aValue):

1856 self.set_byte(4, aValue)

1857

1858 def get_icmp_wpa(self):

1859 return self.get_byte(5)

1860

1861 def set_icmp_wpa(self, aValue):

1862 self.set_byte(5, aValue)

1863

1864 def get_icmp_lifetime(self):

1865 return self.get_word(6)

1866

1867 def set_icmp_lifetime(self, aValue):

1868 self.set_word(6, aValue)

1869

1870 def get_icmp_otime(self):

1871 return self.get_long(8)

1872

1873 def set_icmp_otime(self, aValue):

1874 self.set_long(8, aValue)

1875

1876 def get_icmp_rtime(self):

1877 return self.get_long(12)

1878

1879 def set_icmp_rtime(self, aValue):

1880 self.set_long(12, aValue)

1881

1882 def get_icmp_ttime(self):

1883 return self.get_long(16)

1884

1885 def set_icmp_ttime(self, aValue):

1886 self.set_long(16, aValue)

1887

1888 def get_icmp_mask(self):

1889 return self.get_ip_address(8)

1890

1891 def set_icmp_mask(self, mask):

1892 self.set_ip_address(8, mask)

1893

1894

1895 def calculate_checksum(self):

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

1897 buffer = self.get_buffer_as_string()

1898 data = self.get_data_as_string()

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

1900 buffer += data

1901

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

1903 self.set_icmp_cksum(self.compute_checksum(tmp_array))

1904

1905 def get_type_name(self, aType):

1906 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'}

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

1908 return answer

1909

1910 def get_code_name(self, aType, aCode):

1911 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']}

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

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

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

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

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

1917 if aType in tmp_code:

1918 tmp_list = tmp_code[aType]

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

1920 return 'UNKNOWN'

1921 else:

1922 return tmp_list[aCode]

1923 else:

1924 return 'UNKNOWN'

1925

1926 def __str__(self):

1927 tmp_type = self.get_icmp_type()

1928 tmp_code = self.get_icmp_code()

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

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

1931 if self.child():

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

1933 return tmp_str

1934

1935 def isDestinationUnreachable(self):

1936 return self.get_icmp_type() == 3

1937

1938 def isError(self):

1939 return not self.isQuery()

1940

1941 def isHostUnreachable(self):

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

1943

1944 def isNetUnreachable(self):

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

1946

1947 def isPortUnreachable(self):

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

1949

1950 def isProtocolUnreachable(self):

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

1952

1953 def isQuery(self):

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

1955 return self.get_icmp_type() in tmp_dict

1956

1957 class IGMP(Header):

1958 protocol = 2

1959 def __init__(self, aBuffer = None):

1960 Header.__init__(self, 8)

1961 if aBuffer:

1962 self.load_header(aBuffer)

1963

1964 def get_igmp_type(self):

1965 return self.get_byte(0)

1966

1967 def set_igmp_type(self, aValue):

1968 self.set_byte(0, aValue)

1969

1970 def get_igmp_code(self):

1971 return self.get_byte(1)

1972

1973 def set_igmp_code(self, aValue):

1974 self.set_byte(1, aValue)

1975

1976 def get_igmp_cksum(self):

1977 return self.get_word(2)

1978

1979 def set_igmp_cksum(self, aValue):

1980 self.set_word(2, aValue)

1981

1982 def get_igmp_group(self):

1983 return self.get_long(4)

1984

1985 def set_igmp_group(self, aValue):

1986 self.set_long(4, aValue)

1987

1988 def get_header_size(self):

1989 return 8

1990

1991 def get_type_name(self, aType):

1992 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 '}

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

1994 return answer

1995

1996 def calculate_checksum(self):

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

1998 self.set_igmp_cksum(self.compute_checksum(self.get_bytes()))

1999

2000 def __str__(self):

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

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

2003 if self.child():

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

2005 return tmp_str

2006

2007

2008

2009 class ARP(Header):

2010 ethertype = 0x806

2011 def __init__(self, aBuffer = None):

2012 Header.__init__(self, 7)

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

2014 self.load_header(aBuffer)

2015

2016 def get_ar_hrd(self):

2017 return self.get_word(0)

2018

2019 def set_ar_hrd(self, aValue):

2020 self.set_word(0, aValue)

2021

2022 def get_ar_pro(self):

2023 return self.get_word(2)

2024

2025 def set_ar_pro(self, aValue):

2026 self.set_word(2, aValue)

2027

2028 def get_ar_hln(self):

2029 return self.get_byte(4)

2030

2031 def set_ar_hln(self, aValue):

2032 self.set_byte(4, aValue)

2033

2034 def get_ar_pln(self):

2035 return self.get_byte(5)

2036

2037 def set_ar_pln(self, aValue):

2038 self.set_byte(5, aValue)

2039

2040 def get_ar_op(self):

2041 return self.get_word(6)

2042

2043 def set_ar_op(self, aValue):

2044 self.set_word(6, aValue)

2045

2046 def get_ar_sha(self):

2047 tmp_size = self.get_ar_hln()

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

2049

2050 def set_ar_sha(self, aValue):

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

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

2053

2054 def get_ar_spa(self):

2055 tmp_size = self.get_ar_pln()

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

2057

2058 def set_ar_spa(self, aValue):

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

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

2061

2062 def get_ar_tha(self):

2063 tmp_size = self.get_ar_hln()

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

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

2066

2067 def set_ar_tha(self, aValue):

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

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

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

2071

2072 def get_ar_tpa(self):

2073 tmp_size = self.get_ar_pln()

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

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

2076

2077 def set_ar_tpa(self, aValue):

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

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

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

2081

2082 def get_header_size(self):

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

2084

2085 def get_op_name(self, ar_op):

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

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

2088 return answer

2089

2090 def get_hrd_name(self, ar_hrd):

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

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

2093 return answer

2094

2095

2096 def as_hrd(self, anArray):

2097 if not anArray:

2098 return ''

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

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

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

2102 return tmp_str

2103

2104 def as_pro(self, anArray):

2105 if not anArray:

2106 return ''

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

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

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

2110 return tmp_str

2111

2112 def __str__(self):

2113 tmp_op = self.get_ar_op()

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

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

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

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

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

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

2120 if self.child():

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

2122 return tmp_str

2123

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

2125 a = Ethernet()

2126 b = ARP()

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

2128 b.set_ar_hln(6)

2129 b.set_ar_pln(4)

2130 #a.set_ip_dst('192.168.22.6')

2131 #a.set_ip_src('1.1.1.2')

2132 a.contains(b)

2133 b.contains(c)

2134 b.set_ar_op(2)

2135 b.set_ar_hrd(1)

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

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

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

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

2140 print("beto %s" % a)