How to use tcp flags in python - python

I have problem with my code.
I write a simple tcp packet sniffer, and i need to show tcp packet flags with this code :
import socket
import struct
server = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
while True:
packet = server.recvfrom(65565)
packet = packet[0]
print "Packing data: "
print "\n", packet
ip_header = packet[0:20]
ip_unpack = struct.unpack('!BBHHHBBH4s4s' , ip_header)
print "\n Unpack ip header"
print ip_unpack
version_ihl = ip_unpack[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
print ihl
ip_ihl = ihl * 4
print ip_ihl
def getflags(packet):
Flag_URG = {1: "URG-Urgent flag)"}
Flag_ACK = {1: "ACK-Acknowledgment flag"}
Flag_PSH = {1: "PSH-Push flag"}
Flag_RST = {1: "RST-Reset flag"}
Flag_SYN = {1: "SYN-Synchronize flag"}
Flag_FIN = {1: "FIN-End of data flag"}
URG = packet & 0x020
URG >>= 5
ACK = packet & 0x010
ACK >>= 4
PSH = packet & 0x008
PSH >>= 3
RST = packet & 0x004
RST >>= 2
SYN = packet & 0x002
SYN >>= 1
FIN = packet & 0x001
FIN >>= 0
new_line = "\n"
Flags = Flag_URG[URG] + new_line + Flag_ACK[ACK] + new_line + Flag_PSH[PSH] + new_line + Flag_RST[RST] + new_line + Flag_SYN[SYN] + new_line + Flag_FIN[FIN]
return Flags
#tcp
tcp_header = packet[ip_ihl:ip_ihl+20]
tcp_unpack = struct.unpack("!HHLLBBHHH", tcp_header)
print "\nUnpack TCP header: "
print "\n", tcp_unpack
tcp_length = tcp_unpack[4] >> 4
print "source port: ", tcp_unpack[0]
print "destination port: ", tcp_unpack[1]
print "sequence number: ", tcp_unpack[2]
print "ack number: ", tcp_unpack[3]
print "dataoffset: ", tcp_unpack[4]
print "tcp length: ", tcp_length
print "flag: ", getflags(tcp_unpack[3])
header_size = ip_ihl + tcp_length * 4
data_size = len(packet) - header_size
data = packet[header_size:]
print "data:"
print "\n", data
but i have this error :
Traceback (most recent call last):
File "tcp.py", line 67, in <module>
print "flag: ", getflags(tcp_unpack[3])
File "tcp.py", line 49, in getflags
Flags = Flag_URG[URG] + new_line + Flag_ACK[ACK] + new_line + Flag_PSH[PSH] + new_line + Flag_RST[RST] + new_line + Flag_SYN[SYN] + new_line + Flag_FIN[FIN]
KeyError: 0L
how can fix this ? and how can use flags and ecn in tcp packet?

You got KeyError because all the dict objects only have 1 as key. (Flag_URG, Flag_ACK...) When any flag is missing in packet, 0 is used as key so the error occurs.
Add 0 to avoid the Error:
Flag_URG = {0:"",1: "URG-Urgent flag"}
Flag_ACK = {0:"",1: "ACK-Acknowledgment flag"}
Flag_PSH = {0:"",1: "PSH-Push flag"}
Flag_RST = {0:"",1: "RST-Reset flag"}
Flag_SYN = {0:"",1: "SYN-Synchronize flag"}
Flag_FIN = {0:"",1: "FIN-End of data flag"}
It seems tcp_unpack[3] is the ack number, so print "flag: ", getflags(tcp_unpack[3]) looks strange.
Try changing it to print "flag: ", getflags(tcp_unpack[5]).

Related

Python error when using assign operator TOS = precedence[data >> 5] + tabs + delay[D] + tabs + throughput[T] + tabs + reliability[R] + tabs = cost[M]

Trying to get a script to work and it displays an error at the spot listed in the Title. It is stating that there is an error that says cannot assign to operator. Have looked around multiple sites and even re-watched the video to see if anything was missing. The video was in Python version two, and the installed version on the computer is version 3.7.2. So far there has been no luck determining the reason for the error, nor has anything been identified that changed between version 2 and 3 in regard to the assign operator. Any assistance in identifying the error would be greatly appreciated. The full script is as follows:
import socket
import sys
import struct
import re
def receiveData(s):
data = ''
try:
data = s.recvfrom(65565)
except timeout:
data = ''
except:
print("An error happened")
sys.exc_info()
return data[0]
# get the type of service - 8 bits
def getTOS(data):
precedence = {0: "Routine", 1: "Priority", 2: "Immediate", 3: "Flash", 4: "Flash override", 5: "Crtiical", 6: "Internetwork control", 7: "Network control"}
delay = {0: "Normal delay", 1: "Low delay"}
throughput = {0: "Normal throughput", 1: "High throughput"}
reliability = {0: "Normal reliability", 1: "High reliability"}
cost = {0: "Normal monetary cost", 1: "Minimize monetary cost"}
D = data & 0X10
D >>= 4
T = data & 0x8
T >>= 3
R = data & 0x4
R >>= 2
M = data & 0x2
M >>= 1
tabs = "\n\t\t\t"
TOS = precedence[data >> 5] + tabs + delay[D] + tabs + throughput[T] + tabs + reliability[R] + tabs = cost[M]
return TOS
def getFlags(data):
flagR = {0: "0 - Reserved bit"}
flagDF = {0: "0 - Fragment if necessary', 1: '1 - Do not fragment"}
flagMF = {0: "0 - Last fragment", 1: "1 - More fragments"}
R = data & 0X8000
R >>= 15
DF = data & 0x4000
DF >>= 14
MF = data & 0x2000
MF >>= 13
tabs = "\n\t\t\t"
flags = flagR[R] + tabs + flagDF[DF] + tabs = flagMF[MF]
return flags
def getProtocol(protocolNr):
protocolFile = open("Protocol.txt", "r")
protocolData = protocolFile.read()
protocol = re.findall(r"\n" + str(protocolNR) + " (?:.)+\n", protocolData)
if protocol:
protocol = protocol[0]
protocol = protocol.replace("\n", "")
protocol = protocol.replace(str(protocolNr), "")
protocol = protocol.lstrip()
return protocol
else:
return "No such protocol."
# the public network interface
HOST = socket.gethostbyname(socket.gethostname())
print ("host: ", HOST)
# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
# bind the socket to the network interface
s.bind((HOST,0))
# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
data = receiveData(s)
unpackedData = struct.unpack('!BBHHHBBH4s4s', data[:20])
version_IHL = unpackedData[0]
version = version_IHL >> 4
IHL = version_IHL & 0xF
TOS = unpackedData[1]
totalLength = unpackedData[2]
ID = unpackedData[3]
flags = unpackedData[4]
fragmentOffset = unpackedData[4] & 0X1FFF
TTL = unpackedData[5]
protocolNr = unpackedData[6]
checksum = unpackedData[7]
sourceAddress = socket.inet_ntoa(unpackedData[8])
destinationAddress = socket.inet_ntoa(unpackedData[9])
print ("An IP packet with the size %i was captured.") % (totalLength)
print ("Raw data: ") + data
print ("\nParsed data")
print ("Version:\t\t") + str(version)
print ("Header Length:\t\t") + str(IHL*4) + "bytes"
print ("Type of Service:\t") + getTOS(TOS)
print ("Length:\t\t\t") + str(totalLength)
print ("ID:\t\t\t") + str(hex(ID)) + " (" + str(ID) + ")"
print ("Flags:\t\t\t") + getFlags(flags)
print ("Fragment offset:\t") + str(fragmentOffset)
print ("TTL:\t\t\t") + str(TTL)
print ("Protocol:\t\t") + getProtocol(protocolNr)
print ("Checksum:\t\t") + str(checksum)
print ("Source:\t\t\t") + sourceAddress
print ("Destination:\t\t") + destinationAddress
print ("Payload:\n") + data[20:]
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

struct.pack raises "struct.error: required argument is not an integer"

I am trying to make a network proxy which will forward packets to another IP. I can sniff a packet, unpack it, and view, print, and manipulate its contents. But when I want to pack the bytes to forward it to some other IP, it gives this error:
struct.error: required argument is not an integer
The error is raised on this line of code:
ip_header = struct.pack('!BBHHHBBH4s4s' ,version_IHL, TOS, totalLength, ID,flags, TTL,protocolNR, checksum,sourceAddress,destinationAddress)
Here is the code. Bold stuff in code are comments in my code.
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 ("\n\t\t\t**************************")
print ("\t\t\t*****SettingUp Server*****")
print ("\t\t\t**************************\n\n")
print("\t*****Implementing DHKE")
print ("\t*****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("\nParsed data")
print("Version:\t\t"+ str(version))
print("Header length:\t\t"+ str(IHL*4)+'bytes')
print("Type of service:\t\t" + str(Functions.getTOS(TOS)))
print("Length:\t\t\t"+str(totalLength))
print("ID:\t\t\t"+str(hex(ID)) + ' {' + str(ID) + '}')
print("Flags:\t\t\t" + Functions.getFlags(flags))
print("Fragment offset:\t" + str(fragmentOffset))
print( "TTL:\t\t\t"+str(TTL))
print("Protocol:\t\t" + Functions.getProtocol(protocolNR))
print("Checksum:\t\t" + str(checksum))
print("Source:\t\t\t" + sourceAddress)
print("Destination:\t\t" + destinationAddress)
print("Payload:\n"+str(data[20:]))
# receive a package
#print(s.recvfrom(65565))
#IP = input("Enter IP address to send: ")
#port = int(input("Port: "))
#..............................................................................................
print("\tOld Destination: "+ destinationAddress)
listunpacked[9] = hold
unpacked_data = tuple(listunpacked)
print("\n\t\tNew 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)
Both the B and H formats require integer arguments (or non-integer objects that implement the __index__ method) (see Format Characters).
The checksum argument is now of type bytes because you set it here before packing:
checksum = bytes(str(checksum),"utf-8")
And bytes objects do not implement the __index__ method.
You can check this using dir(checksum).
That's why you're getting the struct.error exception.
When packing a value x using one of the integer formats ('b', 'B',
'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q'), if x is outside the valid
range for that format then struct.error is raised.
Either:
Use a different variable for the bytes(str(checksum),"utf-8") output
Pass an int type object for the checksum value

Socket Error when using socket.sendto()

So, I have a problem where when I use s.sendto(). Once I arrange all the information to be put into the packet and I try to send it, it ends up telling me there is something wrong with my arguments.
The code below is the code I'm using (admittedly from this website).
# some imports
import socket, sys
from struct import *
# checksum functions needed for calculation checksum
def checksum(msg):
s = 0
# loop taking 2 characters at a time
for i in range(0, len(msg), 2):
w = (ord(msg[i]) << 8) + (ord(msg[i+1]) )
s = s + w
s = (s>>16) + (s & 0xffff);
#s = s + (s >> 16);
#complement and mask to 4 byte short
s = ~s & 0xffff
return s
#create a raw socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
except socket.error , msg:
print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
# tell kernel not to put in headers, since we are providing it
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
# now start constructing the packet
packet = '';
source_ip = '192.168.0.13'
dest_ip = '192.168.0.1' # or socket.gethostbyname('www.google.com')
# ip header fields
ihl = 5
version = 4
tos = 0
tot_len = 20 + 20 # python seems to correctly fill the total length, dont know how ??
id = 54321 #Id of this packet
frag_off = 0
ttl = 255
protocol = socket.IPPROTO_TCP
check = 10 # python seems to correctly fill the checksum
saddr = socket.inet_aton ( source_ip ) #Spoof the source ip address if you want to
daddr = socket.inet_aton ( dest_ip )
ihl_version = (version << 4) + ihl
# the ! in the pack format string means network order
ip_header = pack('!BBHHHBBH4s4s' , ihl_version, tos, tot_len, id, frag_off, ttl, protocol, check, saddr, daddr)
# tcp header fields
source = 1234 # source port
dest = 80 # destination port
seq = 0
ack_seq = 0
doff = 5 #4 bit field, size of tcp header, 5 * 4 = 20 bytes
#tcp flags
fin = 0
syn = 1
rst = 0
psh = 0
ack = 0
urg = 0
window = socket.htons (5840) # maximum allowed window size
check = 0
urg_ptr = 0
offset_res = (doff << 4) + 0
tcp_flags = fin + (syn << 1) + (rst << 2) + (psh <<3) + (ack << 4) + (urg << 5)
# the ! in the pack format string means network order
tcp_header = pack('!HHLLBBHHH' , source, dest, seq, ack_seq, offset_res, tcp_flags, window, check, urg_ptr)
# pseudo header fields
source_address = socket.inet_aton( source_ip )
dest_address = socket.inet_aton(dest_ip)
placeholder = 0
protocol = socket.IPPROTO_TCP
tcp_length = len(tcp_header)
psh = pack('!4s4sBBH' , source_address , dest_address , placeholder , protocol , tcp_length);
psh = psh + tcp_header;
tcp_checksum = checksum(psh)
# make the tcp header again and fill the correct checksum
tcp_header = pack('!HHLLBBHHH' , source, dest, seq, ack_seq, offset_res, tcp_flags, window, tcp_checksum , urg_ptr)
# final full packet - syn packets dont have any data
packet = ip_header + tcp_header
#Send the packet finally - the port specified has no effect
while True:
s.sendto(packet, (dest_ip , 80))
And when I run it, I get this error:
File "tcp-syn.py", line 98, in <module>
s.sendto(packet, (dest_ip , 80))
socket.error: [Errno 22] Invalid argument
Any help would be appreciated!

Python packet sniffer problems running

I created a python code that is meant to be a basic packet sniffer. The code compiles however when it runs it gives no errors but there is no output either. My main question is what went wrong with the code. Open to suggestions. I have used IDLE and coderunner on OS X to attempt to get a running program.
Here is what I have so far thanks.
import socket
import struct
import textwrap
TAB_1 = '\t - '
TAB_2 = '\t\t - '
TAB_3 = '\t\t\t - '
TAB_4 = '\t\t\t\t - '
DATA_TAB_1 = '\t '
DATA_TAB_2 = '\t\t '
DATA_TAB_3 = '\t\t\t '
DATA_TAB_4 = '\t\t\t\t '
def main():
pcap = Pcap('capture.pcap')
conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))
while True:
raw_data, addr = conn.recvfrom(65535)
pcap.write(raw_data)
eth = Ethernet(raw_data)
print('\nEthernet Frame:')
print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(eth.dest_mac, eth.src_mac, eth.proto))
# IPv4
if eth.proto == 8:
ipv4 = IPv4(eth.data)
print(TAB_1 + 'IPv4 Packet:')
print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {},'.format(ipv4.version, ipv4.header_length, ipv4.ttl))
print(TAB_2 + 'Protocol: {}, Source: {}, Target: {}'.format(ipv4.proto, ipv4.src, ipv4.target))
# ICMP
if ipv4.proto == 1:
icmp = ICMP(ipv4.data)
print(TAB_1 + 'ICMP Packet:')
print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmp.type, icmp.code, icmp.checksum))
print(TAB_2 + 'ICMP Data:')
print(format_multi_line(DATA_TAB_3, icmp.data))
# TCP
elif ipv4.proto == 6:
tcp = TCP(ipv4.data)
print(TAB_1 + 'TCP Segment:')
print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(tcp.src_port, tcp.dest_port))
print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(tcp.sequence, tcp.acknowledgment))
print(TAB_2 + 'Flags:')
print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(tcp.flag_urg, tcp.flag_ack, tcp.flag_psh))
print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(tcp.flag_rst, tcp.flag_syn, tcp.flag_fin))
if len(tcp.data) > 0:
# HTTP
if tcp.src_port == 80 or tcp.dest_port == 80:
print(TAB_2 + 'HTTP Data:')
try:
http = HTTP(tcp.data)
http_info = str(http.data).split('\n')
for line in http_info:
print(DATA_TAB_3 + str(line))
except:
print(format_multi_line(DATA_TAB_3, tcp.data))
else:
print(TAB_2 + 'TCP Data:')
print(format_multi_line(DATA_TAB_3, tcp.data))
# UDP
elif ipv4.proto == 17:
udp = UDP(ipv4.data)
print(TAB_1 + 'UDP Segment:')
print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(udp.src_port, udp.dest_port, udp.size))
# Other IPv4
else:
print(TAB_1 + 'Other IPv4 Data:')
print(format_multi_line(DATA_TAB_2, ipv4.data))
else:
print('Ethernet Data:')
print(format_multi_line(DATA_TAB_1, eth.data))
# Returns MAC as string from bytes (ie AA:BB:CC:DD:EE:FF)
def get_mac_addr(mac_raw):
byte_str = map('{:02x}'.format, mac_raw)
mac_addr = ':'.join(byte_str).upper()
return mac_addr
def ipv4_packet(self, raw_data):
version_header_length = raw_data[0]
self.version = version_header_length >> 4
self.header_length = (version_header_length & 15) * 4
self.ttl, self.proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', raw_data[:20])
self.src = self.ipv4(src)
self.target = self.ipv4(target)
self.data = raw_data[self.header_length:]
# Returns properly formatted IPv4 address
def ipv4(self, addr):
return '.'.join(map(str, addr))
def icmp_packet(self, raw_data):
self.type, self.code, self.checksum = struct.unpack('! B B H', raw_data[:4])
self.data = raw_data[4:]
def tcp_segment(self, raw_data):
(self.src_port, self.dest_port, self.sequence, self.acknowledgment, offset_reserved_flags) = struct.unpack(
'! H H L L H', raw_data[:14])
offset = (offset_reserved_flags >> 12) * 4
self.flag_urg = (offset_reserved_flags & 32) >> 5
self.flag_ack = (offset_reserved_flags & 16) >> 4
self.flag_psh = (offset_reserved_flags & 8) >> 3
self.flag_rst = (offset_reserved_flags & 4) >> 2
self.flag_syn = (offset_reserved_flags & 2) >> 1
self.flag_fin = offset_reserved_flags & 1
self.data = raw_data[offset:]
def udp_segment(self, raw_data):
self.src_port, self.dest_port, self.size = struct.unpack('! H H 2x H', raw_data[:8])
self.data = raw_data[8:]
# Formats multi-line data
def format_multi_line(prefix, string, size=80):
size -= len(prefix)
if isinstance(string, bytes):
string = ''.join(r'\x{:02x}'.format(byte) for byte in string)
if size % 2:
size -= 1
return '\n'.join([prefix + line for line in textwrap.wrap(string, size)])
curiosity... thenewboston
I have used IDLE and coderunner on OS X to attempt to get a running program.
...
conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))
That's not going to work on OS X; OS X doesn't have AF_PACKET as an address family. I'm surprised your program didn't fail with an exception.
If you're going to capture packet traffic, you should use pcap; you're already using it to write the capture file, you should use it to capture packets. It will use the OS's mechanism (BPF, on OS X, *BSD, AIX, and Solaris 11; AF_PACKET sockets on Linux; etc.) to capture packets.

Why my TCP packet doesn't seems like a TCP packet for protocol analyzers?

I am trying to use raw sockets to send a GET request to a server. I am using raw sockets so I can edit the Packet window size. Here is my code.
import socket, sys
from struct import *
def checksum(msg):
s = 0
for i in range(0, len(msg), 2):
w = ord(msg[i]) + (ord(msg[i+1]) << 8 )
s = s + w
s = (s>>16) + (s & 0xffff);
s = s + (s >> 16);
s = ~s & 0xffff
return s
#create a raw socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
except socket.error , msg:
print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
# tell kernel not to put in headers, since we are providing it, when using IPPROTO_RAW this is not necessary
# s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
packet = '';
source_ip = '192.168.2.7'
dest_ip = '216.86.145.50' # or socket.gethostbyname('www.google.com')
# ip header fields
ip_ihl = 5
ip_ver = 4
ip_tos = 0
ip_tot_len = 0 # kernel will fill the correct total length
ip_id = 54321 #Id of this packet
ip_frag_off = 0
ip_ttl = 255
ip_proto = socket.IPPROTO_TCP
ip_check = 0 # kernel will fill the correct checksum
ip_saddr = socket.inet_aton ( source_ip ) #Spoof the source ip address if you want to
ip_daddr = socket.inet_aton ( dest_ip )
ip_ihl_ver = (ip_ver << 4) + ip_ihl
ip_header = pack('!BBHHHBBH4s4s' , ip_ihl_ver, ip_tos, ip_tot_len, ip_id, ip_frag_off, ip_ttl, ip_proto, ip_check, ip_saddr, ip_daddr)
# tcp header fields
tcp_source = 1234 # source port
tcp_dest = 80 # destination port
tcp_seq = 454
tcp_ack_seq = 0
tcp_doff = 5
#tcp flags
tcp_fin = 0
tcp_syn = 1
tcp_rst = 0
tcp_psh = 0
tcp_ack = 0
tcp_urg = 0
tcp_window = socket.htons (2048)
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)
tcp_header = pack('!HHLLBBHHH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags, tcp_window, tcp_check, tcp_urg_ptr)
user_data = "GET / HTTP/1.1\r\nHost:www.example.com\n\nUser-Agent:Mozilla 5.0\r\n\r\n"
source_address = socket.inet_aton( source_ip )
dest_address = socket.inet_aton(dest_ip)
placeholder = 0
protocol = socket.IPPROTO_TCP
tcp_length = len(tcp_header) + len(user_data)
psh = pack('!4s4sBBH' , source_address , dest_address , placeholder , protocol , tcp_length);
psh = psh + tcp_header + user_data;
tcp_check = checksum(psh)
tcp_header = pack('!HHLLBBH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags, tcp_window) + pack('H' , tcp_check) + pack('!H' , tcp_urg_ptr)
packet = ip_header + tcp_header + user_data
s.sendto(packet, (dest_ip , 0 ))
I am using Wireshark to view the packet being sent. The problem is the output is not a TCP GET request packet. In wire shark the output is the white in colour, under protocol it says IPv4 and info says: 144 Unknown(255). How do I fix this?
Like #Sivir said you need to establish a three way handshake because you want to use the TCP protocol. In theory the handshake should look like this
YourProgram: sends a SYN packet
Server: sends SYNACK packet
YourProgram: sends a ACK packet
More information regarding this can be found here.
It's because you send one single packet, but in TCP you have to setup connection first (3 ways handshake), then send request and then close connection.
Although it is possible to implement it using raw socket, there is a few parameters that you need to control during connection. If you tell why do you need to control window size, may be there is way to do it without TCP protocol implementation.

Categories

Resources