def interp(plugin, nuin): family = nuin.value(0) res_id = nuin.value(1); pattrs = (ctypes.POINTER(mnl.Attr) * (nfqnl.NFQA_MAX + 1)).from_buffer(nuin.value(2)) ph = pattrs[nfqnl.NFQA_PACKET_HDR].contents.get_payload_as(nfqnl.NfqnlMsgPacketHdr) packet_id = socket.ntohl(ph.packet_id) log.info("res_id: %d, qid: %d", res_id, packet_id) if pattrs[nfqnl.NFQA_PAYLOAD]: nfq_payload = pattrs[nfqnl.NFQA_PAYLOAD].contents ip = IP(bytes(nfq_payload.get_payload_v())) if ip[ICMP].seq % 2 == 0: # wrong data byte ... ip[ICMP].payload = bytes(ip[ICMP].payload).replace(b'!', b'@') # (truncated) # ip[ICMP].payload = bytes(ip[ICMP].payload)[:4] # no error but ``bytes from'' is differ a little? # ip[ICMP].payload = bytes(ip[ICMP].payload) + (b'0' * 8192) ip[ICMP].chksum = 0 # NEED THIS ip[ICMP].chksum = utils.checksum(bytes(ip[ICMP])) nfq_send_repeat(res_id, packet_id, 10, (ctypes.c_ubyte * len(ip)).from_buffer(bytearray(bytes(ip)))) else: nfq_send_accept(res_id, packet_id) return nurs.NURS_RET_OK
def post_build(self, p, pay): # type: (bytes, bytes) -> bytes p += pay if self.chksum_present and self.chksum is None: c = checksum(p) p = p[:4] + chb((c >> 8) & 0xff) + chb(c & 0xff) + p[6:] return p
def post_build(self, p, pay): # See <http://tools.ietf.org/html/rfc5613> p += pay if self.checksum is None: # Checksum is calculated without authentication data # Algorithm is the same as in IP() ck = checksum(p[:16] + p[24:]) p = p[:12] + struct.pack("!H", ck) + p[14:] return p
def guess_payload_class(self, payload): """Implements guess_payload_class to identify MPLS packets with internal Ethernet header""" # If bottom of stack is zero, the next layer is MPLS for sure. if self.s == 0: return MPLS # If checksum is ok, then we have a correct IP header after MPLS labels. elif checksum(payload[:20]) == 0: return IP # If checksum is nok, then we (almost) certainly have an Ethernet header after MPLS. else: return Ether
def run(self): """ Infinite loop that gets packets from the packet queue and checks if the packet is a handover test packet. If it is it inserts the VNF id in the packet an recalculates the UDP/TCP checksum. Then the packet is forwarded to the output socket. :return: """ while True: buf = self.packet_queue.get() eth_type = struct.unpack_from('!H', buf, 12)[0] if eth_type == 0x800: proto = buf[23] if proto == '\x11': # UDP buf = buf[:50] + struct.pack("!H", self.vnf_id) + buf[52:] psdhdr = buf[26:34] + struct.pack("!HH", 0x11, len(buf) - 34) ck = checksum(psdhdr + buf[34:40] + '\x00\x00' + buf[42:]) if ck == 0: ck = 0xffff buf = buf[:40] + chr(ck >> 8) + chr(ck & 0xff) + buf[42:] elif proto == '\x06' and len(buf) >= 84: # TCP buf_len = len(buf) offset = 66 while offset < buf_len: buf = buf[:offset + 8] + struct.pack( "!H", self.vnf_id) + buf[offset + 10:] pkt_len = struct.unpack("!H", buf[offset + 16:offset + 18])[0] offset += pkt_len psdhdr = buf[26:34] + struct.pack("!HH", 0x06, len(buf) - 34) ck = checksum(psdhdr + buf[34:50] + '\x00\x00' + buf[52:]) buf = buf[:50] + chr(ck >> 8) + chr(ck & 0xff) + buf[52:] self.out_socket.send(buf)
def post_build(self, p, pay): # See <http://tools.ietf.org/html/rfc5613> p += pay if self.chksum is None: if self.authtype == 2: ck = 0 # Crypto, see RFC 2328, D.4.3 else: # Checksum is calculated without authentication data # Algorithm is the same as in IP() ck = checksum(p[:16] + p[24:]) p = p[:12] + struct.pack("!H", ck) + p[14:] # TODO: Handle Crypto: Add message digest (RFC 2328, D.4.3) return p
def post_build(self, p, pay): """Called implicitly before a packet is sent to compute and place IGMP checksum. # noqa: E501 Parameters: self The instantiation of an IGMP class p The IGMP message in hex in network byte order pay Additional payload for the IGMP message """ p += pay if self.chksum is None: ck = checksum(p) p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:] return p
def post_build(self, p, pay): ihl = self.ihl p += b"\0" * ((-len(p)) % 4) # pad IP options if needed if ihl is None: ihl = len(p) // 4 p = chb(((self.version & 0xf) << 4) | ihl & 0x0f) + p[1:] if self.len is None: tmp_len = len(p) + len(pay) p = p[:2] + struct.pack("!H", tmp_len) + p[4:] if self.chksum is None: ck = checksum(p) p = p[:10] + chb(ck >> 8) + chb(ck & 0xff) + p[12:] return p + pay
def post_build(self, p, pay): """ Called implicitly before a packet is sent to compute and place PIM checksum. Parameters: self The instantiation of an PIMv2Hdr class p The PIMv2Hdr message in hex in network byte order pay Additional payload for the PIMv2Hdr message """ p += pay if self.chksum is None: ck = checksum(p) p = p[:2] + struct.pack("!H", ck) + p[4:] return p
def post_build(self, p, pay): '''Called implicitly before a packet is sent to compute and place IGMPv3 checksum. Parameters: self The instantiation of an IGMPv3 class p The IGMPv3 message in hex in network byte order pay Additional payload for the IGMPv3 message ''' p += pay if self.type in [0, 0x31, 0x32, 0x22]: # for these, field is reserved (0) p = p[:1]+chr(0)+p[2:] if self.chksum is None: ck = checksum(p) p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:] return p
def post_build(self, pkt, payload): pkt += payload # max_resp_code field is reserved (0) if self.type in [IGMP_TYPE_V3_MEMBERSHIP_REPORT,]: mrc = 0 else: mrc = self.encode_float(self.max_resp_code) pkt = pkt[:1] + chr(mrc) + pkt[2:] if self.checksum is None: chksum = checksum(pkt) pkt = pkt[:2] + chr(chksum >> 8) + chr(chksum & 0xff) + pkt[4:] return pkt
def post_build(self, pkt, payload): pkt += payload # max_resp_code field is reserved (0) if self.type in [ IGMP_TYPE_V3_MEMBERSHIP_REPORT, ]: mrc = 0 else: mrc = self.encode_float(self.max_resp_code) pkt = pkt[:1] + chr(mrc) + pkt[2:] if self.checksum is None: chksum = checksum(pkt) pkt = pkt[:2] + chr(chksum >> 8) + chr(chksum & 0xff) + pkt[4:] return pkt
def mini_ip_checksum(raw_mini_ip): """Returns mini_ip checksum.""" return checksum(raw_mini_ip)
def post_build(self, p, pay): p += pay if self.chksum is None: ck = checksum(p) p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:] return p
def post_build(self, pkt, pay): if self.chksum is None: pkt = pkt[:6] + struct.pack("!H", checksum(pkt)) + pkt[8:] return pkt
def post_build(self, p, pay): p += pay if self.chksum_present and self.chksum is None: c = checksum(p) p = p[:4] + chb((c >> 8) & 0xff) + chb(c & 0xff) + p[6:] return p
def post_build(self, pkt, pay): if self.chksum == None: pkt = pkt[:6] + struct.pack("!H", checksum(pkt)) + pkt[8:] return pkt
def post_build(self, p, pay): p += pay if self.chksum is None: c = checksum(p) p = struct.pack("!H", c) + p[2:] return p
def post_build(self, p, pay): p += pay if self.chksum is None: c = checksum(p) p = p[:2]+chr((c>>8)&0xff)+chr(c&0xff)+p[4:] return p