struct.pack引发“struct.error:required参数不是整数”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了struct.pack引发“struct.error:required参数不是整数”相关的知识,希望对你有一定的参考价值。

我正在尝试建立一个网络代理,将数据包转发到另一个IP。我可以嗅探数据包,解压缩,查看,打印和操作其内容。但是,当我想打包字节以将其转发到其他IP时,它会给出以下错误:

struct.error:required参数不是整数

这行代码引发了错误:

ip_header = struct.pack('!BBHHHBBH4s4s' ,version_IHL, TOS, totalLength, ID,flags, TTL,protocolNR, checksum,sourceAddress,destinationAddress)

这是代码。代码中的大胆内容是我的代码中的注释。

import socket
import sys
import struct
import re
import logging
import struct
from scapy.all import *
import Functions
logging.basicConfig(filename='example.log',level=logging.DEBUG)

hold = "192.168.0.125"

print ("
			**************************")
print ("			*****SettingUp Server*****")
print ("			**************************

")
print("	*****Implementing DHKE")
print ("	*****Generating server public & private keypairs now . . .")
(e,n), private = Functions.generate_keypair(7, 11)
print ("*****Public Key: {} , {} ", e,n)
print ("*****Private key: {} ", private)
public = (e,n)
ip = '192.168.0.125'
port = 5001

# the public network interface
#HOST = socket.gethostbyname(socket.gethostname())
#..............................................................................................
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind(('192.168.0.117',5001))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

logging.basicConfig(format='%(asctime)s %(message)s')
logging.warning('format=%(asctime)s %(message)s')

# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

#..............................................................................................
data = Functions.recievedata(s)
logging.info('**Packet Recieved')
print("Packet Recieved")

#function_data = tuple(struct.unpack(data))
unpacked_data = struct.unpack('!BBHHHBBH4s4s',data[:20])
listunpacked = list(unpacked_data)
logging.info('--> Unpacking packet')
version_IHL = unpacked_data[0]
version = version_IHL >>4
IHL = version_IHL & 0xF
TOS = unpacked_data[1]
totalLength = unpacked_data[2]
ID = unpacked_data[3]
flags = unpacked_data[4]
fragmentOffset =  unpacked_data[4] &  0x1FFF
TTL = unpacked_data[5]
protocolNR = unpacked_data[6]
checksum = unpacked_data[7]
sourceAddress = socket.inet_ntoa(unpacked_data[8])
destinationAddress = socket.inet_ntoa(unpacked_data[9])



#..............................................................................................
print("An IP packet with the size %i is captured.", (totalLength))
print("Raw data: "+ str(data))
print("
Parsed data")
print("Version:		"+ str(version))
print("Header length:		"+ str(IHL*4)+'bytes')
print("Type of service:		" + str(Functions.getTOS(TOS)))
print("Length:			"+str(totalLength))
print("ID:			"+str(hex(ID)) + ' {' + str(ID) + '}')
print("Flags:			" + Functions.getFlags(flags))
print("Fragment offset:	" + str(fragmentOffset))
print( "TTL:			"+str(TTL))
print("Protocol:		" + Functions.getProtocol(protocolNR))
print("Checksum:		" + str(checksum))
print("Source:			" + sourceAddress)
print("Destination:		" + destinationAddress)
print("Payload:
"+str(data[20:]))
# receive a package
#print(s.recvfrom(65565))
#IP = input("Enter IP address to send: ")
#port = int(input("Port: "))

#..............................................................................................
print("	Old Destination: "+ destinationAddress)

listunpacked[9] = hold
unpacked_data = tuple(listunpacked)
print("
		New Address is: "+ unpacked_data[9])
print()
#s.inet_aton(unpacked_data[9]) = hold

#unpacked_data = tuple(listunpacked)
#unpacked_data = bytes(unpacked_data)
#destinationAddress = socket.inet_ntoa(unpacked_data[9])
#..............................................................................................
# tcp header fields
tcp_source = 80  # source port
tcp_dest = 5001  # destination port
tcp_seq = 454
tcp_ack_seq = 0
tcp_doff = 5  # 4 bit field, size of tcp header, 5 * 4 = 20 bytes
# tcp flags
tcp_fin = 0
tcp_syn = 1
tcp_rst = 0
tcp_psh = 0
tcp_ack = 0
tcp_urg = 0
tcp_window = socket.htons(5840)  # maximum allowed window size
tcp_check = 0
tcp_urg_ptr = 0
tcp_offset_res = (tcp_doff << 4) + 0
tcp_flags = tcp_fin + (tcp_syn << 1) + (tcp_rst << 2) + (tcp_psh << 3) + (tcp_ack << 4) + (tcp_urg << 5)

# the ! in the pack format string means network order
tcp_header = tuple(struct.pack('!HHLLBBHHH', tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags, tcp_window,tcp_check, tcp_urg_ptr))
#p =(data+tcp_header)

#hold = bytes(hold,"utf-8")
#hold  = socket.inet_aton ( hold )
#checksum = bytes(checksum,"utf-8")
#destinationAddress = c_int(listunpacked[9])
checksum = bytes(str(checksum),"utf-8")
#ip_header = struct.pack('!BBHHHBBH4s4s' , version_IHL, TOS, totalLength, ID,flags, TTL,protocolNR, checksum,sourceAddress,destinationAddress)
#tcp_header = struct.pack('!HHLLBBH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags,  tcp_window) + struct.pack('H' , tcp_check) + struct.pack('!H' , tcp_urg_ptr)

#packet = ip_header + tcp_header + str(data[20:])
message = "How are  you"
#data = bytes(unpacked_data,"utf-8") + tcp_header + message
ip_header = struct.pack('!BBHHHBBH4s4s' ,version_IHL, TOS, totalLength, ID,flags, TTL,protocolNR, checksum,sourceAddress,destinationAddress)
data = bytes(unpacked_data) + data[20:]
s.sendto(data, ("192.168.0.125" , 5001))
print("Packet sent")
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
答案
ip_header = struct.pack('!BBHHHBBH4s4s' ,version_IHL, TOS, totalLength, ID,flags, TTL,protocolNR, checksum,sourceAddress,destinationAddress)

BH格式都需要整数参数(或实现__index__方法的非整数对象)(请参阅Format Characters)。

checksum参数现在是bytes类型,因为你在打包之前将它设置在这里:

checksum = bytes(str(checksum),"utf-8")

并且bytes对象不实现__index__方法。 你可以使用dir(checksum)来检查。

这就是你获得struct.error exception的原因。

当使用整数格式之一('b','B','h','H','i','I','l','L','q','Q'打包值x时'),如果x超出该格式的有效范围,则引发struct.error。

或者:

  • bytes(str(checksum),"utf-8")输出使用不同的变量
  • 传递一个int类型对象作为校验和值

以上是关于struct.pack引发“struct.error:required参数不是整数”的主要内容,如果未能解决你的问题,请参考以下文章

Python struct.pack() 行为

如何通过 Modbus TCP 使用“struct.pack”类型发送?

Python学习——struct模块的pack unpack示例

使用“struct.pack”将数据写入文件时出错

msgpack 能否提供更好的性能和与 python 的 struct.pack() 相同的功能?

C# 中的 Struct.Pack 等价物?