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)
B
和H
格式都需要整数参数(或实现__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参数不是整数”的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Modbus TCP 使用“struct.pack”类型发送?
Python学习——struct模块的pack unpack示例