| 131 | |
| 132 | |
| 133 | class BTH(Packet): |
| 134 | name = "BTH" |
| 135 | fields_desc = [ |
| 136 | ByteEnumField("opcode", 0, _bth_opcodes), |
| 137 | BitField("solicited", 0, 1), |
| 138 | BitField("migreq", 0, 1), |
| 139 | BitField("padcount", 0, 2), |
| 140 | BitField("version", 0, 4), |
| 141 | XShortField("pkey", 0xffff), |
| 142 | BitField("fecn", 0, 1), |
| 143 | BitField("becn", 0, 1), |
| 144 | BitField("resv6", 0, 6), |
| 145 | BitField("dqpn", 0, 24), |
| 146 | BitField("ackreq", 0, 1), |
| 147 | BitField("resv7", 0, 7), |
| 148 | BitField("psn", 0, 24), |
| 149 | |
| 150 | FCSField("icrc", None, fmt="!I")] |
| 151 | |
| 152 | @staticmethod |
| 153 | def pack_icrc(icrc): |
| 154 | # type: (int) -> bytes |
| 155 | return struct.pack("!I", icrc & 0xffffffff)[::-1] |
| 156 | |
| 157 | def compute_icrc(self, p): |
| 158 | # type: (bytes) -> bytes |
| 159 | udp = self.underlayer |
| 160 | if udp is None or not isinstance(udp, UDP): |
| 161 | warning("Expecting UDP underlayer to compute checksum. Got %s.", |
| 162 | udp and udp.name) |
| 163 | return self.pack_icrc(0) |
| 164 | ip = udp.underlayer |
| 165 | if isinstance(ip, IP): |
| 166 | # pseudo-LRH / IP / UDP / BTH / payload |
| 167 | pshdr = Raw(b'\xff' * 8) / ip.copy() |
| 168 | pshdr.chksum = 0xffff |
| 169 | pshdr.ttl = 0xff |
| 170 | pshdr.tos = 0xff |
| 171 | pshdr[UDP].chksum = 0xffff |
| 172 | pshdr[BTH].fecn = 1 |
| 173 | pshdr[BTH].becn = 1 |
| 174 | pshdr[BTH].resv6 = 0xff |
| 175 | bth = pshdr[BTH].self_build() |
| 176 | payload = raw(pshdr[BTH].payload) |
| 177 | # add ICRC placeholder just to get the right IP.totlen and |
| 178 | # UDP.length |
| 179 | icrc_placeholder = b'\xff\xff\xff\xff' |
| 180 | pshdr[UDP].payload = Raw(bth + payload + icrc_placeholder) |
| 181 | icrc = crc32(raw(pshdr)[:-4]) & 0xffffffff |
| 182 | return self.pack_icrc(icrc) |
| 183 | elif isinstance(ip, IPv6): |
| 184 | # pseudo-LRH / IPv6 / UDP / BTH / payload |
| 185 | pshdr = Raw(b'\xff' * 8) / ip.copy() |
| 186 | pshdr.hlim = 0xff |
| 187 | pshdr.fl = 0xfffff |
| 188 | pshdr.tc = 0xff |
| 189 | pshdr[UDP].chksum = 0xffff |
| 190 | pshdr[BTH].fecn = 1 |
no test coverage detected