Coverage for /root/GitHubProjects/impacket/impacket/IP6.py: 74%

# Coverage for /root/GitHubProjects/impacket/impacket/IP6.py : 74%

## 129 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# Impacket - Collection of Python classes for working with network protocols.

2#

3# SECUREAUTH LABS. Copyright (C) 2021 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

10 import struct

11 import array

12

13 from impacket.ImpactPacket import Header, array_frombytes

14 from impacket.IP6_Address import IP6_Address

15 from impacket.IP6_Extension_Headers import IP6_Extension_Header

16

17 from impacket import LOG

18

19

20 class IP6(Header):

21 #Ethertype value for IPv6

22 ethertype = 0x86DD

23 HEADER_SIZE = 40

24 IP_PROTOCOL_VERSION = 6

25

26 def __init__(self, buffer = None):

27 Header.__init__(self, IP6.HEADER_SIZE)

28 self.set_ip_v(IP6.IP_PROTOCOL_VERSION)

29 if (buffer):

30 self.load_header(buffer)

31

32 def contains(self, aHeader):

33 Header.contains(self, aHeader)

34 if isinstance(aHeader, IP6_Extension_Header):

35 self.set_next_header(aHeader.get_header_type())

36

37 def get_header_size(self):

38 return IP6.HEADER_SIZE

39

40 def __str__(self):

41 protocol_version = self.get_ip_v()

42 traffic_class = self.get_traffic_class()

43 flow_label = self.get_flow_label()

44 payload_length = self.get_payload_length()

45 next_header = self.get_next_header()

46 hop_limit = self.get_hop_limit()

47 source_address = self.get_ip_src()

48 destination_address = self.get_ip_dst()

49

50 s = "Protocol version: " + str(protocol_version) + "\n"

51 s += "Traffic class: " + str(traffic_class) + "\n"

52 s += "Flow label: " + str(flow_label) + "\n"

53 s += "Payload length: " + str(payload_length) + "\n"

54 s += "Next header: " + str(next_header) + "\n"

55 s += "Hop limit: " + str(hop_limit) + "\n"

56 s += "Source address: " + source_address.as_string() + "\n"

57 s += "Destination address: " + destination_address.as_string() + "\n"

58 return s

59

60 def get_pseudo_header(self):

61 source_address = self.get_ip_src().as_bytes()

62 #FIXME - Handle Routing header special case

63 destination_address = self.get_ip_dst().as_bytes()

64 reserved_bytes = [ 0x00, 0x00, 0x00 ]

65

66 upper_layer_packet_length = self.get_payload_length()

67 upper_layer_protocol_number = self.get_next_header()

68

69 next_header = self.child()

70 while isinstance(next_header, IP6_Extension_Header): 70 ↛ 73line 70 didn't jump to line 73, because the condition on line 70 was never true

71 # The length used in the pseudo-header is the Payload Length from the IPv6 header, minus

72 # the length of any extension headers present between the IPv6 header and the upper-layer header

73 upper_layer_packet_length -= next_header.get_header_size()

74

75 # If there are extension headers, fetch the correct upper-player protocol number by traversing the list

76 upper_layer_protocol_number = next_header.get_next_header()

77

78 next_header = next_header.child()

79

80 pseudo_header = array.array('B')

81 pseudo_header.extend(source_address)

82 pseudo_header.extend(destination_address)

83 array_frombytes(pseudo_header, struct.pack('!L', upper_layer_packet_length))

84 pseudo_header.fromlist(reserved_bytes)

85 array_frombytes(pseudo_header, struct.pack('B', upper_layer_protocol_number))

86 return pseudo_header

87

88############################################################################

89 def get_ip_v(self):

90 return (self.get_byte(0) & 0xF0) >> 4

91

92 def get_traffic_class(self):

93 return ((self.get_byte(0) & 0x0F) << 4) | ((self.get_byte(1) & 0xF0) >> 4)

94

95 def get_flow_label(self):

96 return (self.get_byte(1) & 0x0F) << 16 | (self.get_byte(2) << 8) | self.get_byte(3)

97

98 def get_payload_length(self):

99 return (self.get_byte(4) << 8) | self.get_byte(5)

100

101 def get_next_header(self):

102 return (self.get_byte(6))

103

104 def get_hop_limit(self):

105 return (self.get_byte(7))

106

107 def get_ip_src(self):

108 address = IP6_Address(self.get_bytes()[8:24])

109 return (address)

110

111 def get_ip_dst(self):

112 address = IP6_Address(self.get_bytes()[24:40])

113 return (address)

114

115############################################################################

116 def set_ip_v(self, version):

117 if (version != 6): 117 ↛ 118line 117 didn't jump to line 118, because the condition on line 117 was never true

118 raise Exception('set_ip_v - version != 6')

119

120 #Fetch byte, clear high nibble

121 b = self.get_byte(0) & 0x0F

122 #Store version number in high nibble

123 b |= (version << 4)

124 #Store byte in buffer

125 #This behaviour is repeated in the rest of the methods

126 self.set_byte(0, b)

127

128

129 def set_traffic_class(self, traffic_class):

130 b0 = self.get_byte(0) & 0xF0

131 b1 = self.get_byte(1) & 0x0F

132 b0 |= (traffic_class & 0xF0) >> 4

133 b1 |= (traffic_class & 0x0F) << 4

134 self.set_byte(0, b0)

135 self.set_byte(1, b1)

136

137

138 def set_flow_label(self, flow_label):

139 b1 = self.get_byte(1) & 0xF0

140 b1 |= (flow_label & 0xF0000) >> 16

141 self.set_byte(1, b1)

142 self.set_byte(2, (flow_label & 0x0FF00) >> 8)

143 self.set_byte(3, (flow_label & 0x000FF))

144

145

146 def set_payload_length(self, payload_length):

147 self.set_byte(4, (payload_length & 0xFF00) >> 8)

148 self.set_byte(5, (payload_length & 0x00FF))

149

150

151 def set_next_header(self, next_header):

152 self.set_byte(6, next_header)

153

154 def set_hop_limit(self, hop_limit):

155 self.set_byte(7, hop_limit)

156

157 def set_ip_src(self, source_address):

158 address = IP6_Address(source_address)

159 bytes = self.get_bytes()

160 bytes[8:24] = address.as_bytes()

161 self.set_bytes(bytes)

162

163 def set_ip_dst(self, destination_address):

164 address = IP6_Address(destination_address)

165 bytes = self.get_bytes()

166 bytes[24:40] = address.as_bytes()

167 self.set_bytes(bytes)

168

169 def get_protocol_version(self):

170 LOG.warning('deprecated soon')

171 return self.get_ip_v()

172

173 def get_source_address(self):

174 LOG.warning('deprecated soon')

175 return self.get_ip_src()

176

177 def get_destination_address(self):

178 LOG.warning('deprecated soon')

179 return self.get_ip_dst()

180

181 def set_protocol_version(self, version):

182 LOG.warning('deprecated soon')

183 self.set_ip_v(version)

184

185 def set_source_address(self, source_address):

186 LOG.warning('deprecated soon')

187 self.set_ip_src(source_address)

188

189 def set_destination_address(self, destination_address):

190 LOG.warning('deprecated soon')

191 self.set_ip_dst(destination_address)