I am replaying packets from pcap file using scapy from local machine to public. The pcap file contains different packets with multiple protocols like, llmnr, dhcp, http, udp, tcp, nbns e.t.c. The public ip is my VM(Virtual Machine) on azure. When I send packets to public ip, I only get few packets. Most of them are lost and I also get Malformed traffic, not the original packet there. Is there any way in scapy by using that I can receive all packets there.
The python script:
pca = rdpcap("Eg.pcap")
for pkt in pca:
if TCP in pkt:
npkt = (IP(dst="Public IP")/TCP()/Raw(pkt.payload))
del(npkt.len)
del(npkt.chksum)
elif UDP in pkt:
npkt = (IP(dst="Public IP")/UDP()/Raw(pkt.payload))
del(npkt.len)
del(npkt.chksum)
send(npkt)
Related
I have a raspberry pi that is both connected to the internet via Wlan and a local device via Ethernet. So it has two IPs; one for each endpoint.
This is how it looks like simplified when running ifconfig; with different IPs for privacy
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 189.168.200.110 netmask 0.0.0.0 broadcast 255.255.255.255
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 189.168.201.79 netmask 255.255.255.0 broadcast 192.168.1.255
This is the code that python is using to send a message to the device through the Ethernet with that gateway's ip
TCP_PORT = 3001
SERVER_IP_AD = "189.168.200.110"
CLIENT_IP_AD = "189.168.200.155"
BROADCAST_IP = "255.255.255.255"
def sendMessage(self, file_path, client_ip=CLIENT_IP_AD):
print('message en route')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((self.SERVER_IP_AD, 0))
s.connect((client_ip, self.TCP_PORT)) #**ERROR IS HERE**
MESSAGE = self.openFile(file_path)
s.send(MESSAGE.encode())
data = s.recv(self.BUFFER_SIZE)
s.close()
return data
Using wireshark I can see that the package is being sent through the Wlan interface instead of the Ethernet interface with the correct IP source and IP destination.
How do I tell python to use the correct interface when sending out the package?
In my opinion, you can establish Tcp connection with Ethernet, cause there isn't shaking hands by Ethernet
And, you shouldn't use s.bind() and s.connect() at the same time. Because the former is for UDP client, and the later is for TCP client. Have a try with only s.bind().
I need to send a UDP packet over ethernet from 169.254.xx.xx to 192.168.xx.xx. The second address is the address of the FPGA and its MAC address is known. I am using wireshark to monitor the packets, but when i have an unbound socket, and I call sock.sendto() it sends over WLAN. When I bind the socket to the WLAN interface, it sends, but when I bind the socket to the ethernet interface, I get this error when I try to send:
OSError: [WinError 10051] A socket operation was attempted to an unreachable network
When bound to the ethernet interface, and i send to an unused address in the 169.254.xx.xx subnet, it sends an ARP, but nothing is sent when the destination is in the 192.168.xx.xx subnet.
Here is the code:
import socket
import time
address = '192.168.1.239'
port = 1235
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('169.254.190.73', 0))
sock.sendto('100'.encode('utf-8'), (bytes(address, 'UTF-8'), port))
time.sleep(0.005)
sock.close()
'''
'''
Since 169.254.xx.xx and 192.168.xx.xx represent different networks, traffic in between needs to be routed. However, 169.254.0.0/16 (autoconf) isn't usually routed.
If both nodes actually reside in the same layer 2 segment, just (manually) change the autoconf client's IP address.
I am actually new to scapy/networking
Like for ICMP I can send a ICMP packet/request like
srp(Ether(src=u'd2:ff:90:c5:1f:21', dst=u'9c:22:14:4f:6c:ac', type=2048)/IP(src=u'238.166.15.14', dst=u'70.74.2.83')/ICMP(type=8)/Raw(load='UZe5ICdH'),timeout=10,iface="ens192.50")
on the other side I can send a packet/reply like
srp(Ether(dst=u'd2:ff:90:c5:1f:21', src=u'9c:22:14:4f:6c:ac', type=2048)/IP(dst=u'238.166.15.14', src=u'70.74.2.83')/ICMP(type=0)/Raw(load='UZe5ICdH'),timeout=10,iface="ens192.50")
Can some one help me with L2TP ?
LT2P uses UDP packets underlying over 1701 port to communicate.
Packet structure for L2TP is as below:
Ether / IP / UDP/ L2TP / PADDING
So we will be sending a packet like
srp(Ether(src=u'12:24:52:93:c6:54', dst=u'ea:26:7c:6b:02:dc', type=2048)/IP(src=u'22.159.236.164', dst=u'182.187.41.246')/UDP(dport=1701, sport=1701)/L2TP(pkt_type=2)/Padding(load='5Z0WZ'), iface='ens192.50', timeout=5)
Here am sending a message packet over l2tp (i.e pkt_type=2). We can also send control messages too, like Start-Control-Connection-Request, Hello etc.
Reference sites:
http://docstore.mik.ua/orelly/networking_2ndEd/fire/ch14_12.htm
https://technet.microsoft.com/en-us/library/cc958047.aspx
http://www.networksorcery.com/enp/protocol/l2tp.htm
The server has a public IP, the client is behind a nat.
How could the client communicate with server by udp in qt?
The client will send some data to server first, then how could server reply to client?
The current code is this:
server:
self.udpSocketGet = QtNetwork.QUdpSocket()
self.udpSocketGet.bind(QtNetwork.QHostAddress.LocalHost, serverPort)
self.udpSocketGet.readyRead.connect(self.receive)
def receive(self):
while self.udpSocketGet.hasPendingDatagrams():
size = self.udpSocketGet.pendingDatagramSize()
if size > 0:
data, senderAddr, senderPort = self.udpSocketGet.readDatagram(size)
client:
def sentToServer(self,data):
udpSocketSend = QtNetwork.QUdpSocket()
udpSocketSend.writeDatagram(data.encode('utf-8'), serverAddress, serverPort)
The answer to your question goes beyond qt. Check out http://en.m.wikipedia.org/wiki/UDP_hole_punching and http://en.m.wikipedia.org/wiki/NAT_traversal
I am editing this answer after I looked back and found out that the server has a public IP address. In that case, the server will just have to respond to whatever IP address the request comes from. In case the client is communicating via NAT, the server will see the public address of the router and will be totally unaware that the actual client is behind that router.
Read Receiving a response through UDP
The bottom line is that you either have to use port mapping or UPNP.
See also https://superuser.com/questions/456812/nat-and-udp-replies
Again, the server code should not be concerned with NAT traversal. Either the client uses UPNP and the router has UPNP enabled. Or the router is configured to port forward or remember the source and destination IP addresses and ports of the packet originating from the client and properly farwards back the packets sent by the server.
tcmpdump can view all the multicast traffic to specific group and port on eth2, but my Python program cannot. The Python program, running on Ubuntu 12.04:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Multicast port is 52122
sock.bind(('', 52122))
# Interface eth2 IP is 1.2.3.4, multicast group is 6.7.8.9
mreq = socket.inet_aton('6.7.8.9')+socket.inet_aton('1.2.3.4')
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
while True:
print '\nwaiting to receive message'
data, address = sock.recvfrom(1024)
print data
When I use another program to send a multicast packet to eth2, it works and prints the packet. But it fails to see all the current multicast traffic. If I run tcpdump on eth2 on the same port and group as the above program:
sudo tcpdump -i eth2 host 6.7.8.9 and port 52122
it sees both the packets I send from another program AND all the current multicast traffic. It's output looks likes this...
# Packet sent from my other program
09:52:51.952714 IP 1.2.3.4.57940 > 6.7.8.9.52122: UDP, length 19
# Packet send from the outside world
09:52:52.143339 IP 9.9.9.9.39295 > 6.7.8.9.52122: UDP, length 62
Why can't my program see the packets from the outside world? How can I modify it (or something else) to fix this?
Edit:
I should have mentioned, the interface this going over is not eth2 but eth2.200 a VLAN. (The local IP and the tcpdump commands are all run with eth2.200, I just changed that in this question to make it simpler.) Based on this answer that could be the problem?
Edit #2:
netstat -ng when the program is running shows eth2.200 subscribed to 224.0.0.1 and 6.7.8.9`.
tshark -i eth2.200 igmp shows three repeated 1.2.3.4 -> 6.7.8.9 IGMP 46 V2 Membership Report / Join group 6.7.8.9 when the program first starts. When the program process is killed, it shows 1.2.3.4 -> 224.0.0.2 IGMP 46 V2 Leave group 6.7.8.9. There is also an infrequent 1.2.3.1 -> 224.0.0.1 IGMP 60 V2 Membership Query, general, where 1.2.3.1 is 1.2.3.4's gateway.
Not sure if it will help, but the routing table looks like:
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 1.2.5.6 0.0.0.0 UG 0 0 0 eth1
1.2.3.0 0.0.0.0 255.255.255.240 U 0 0 0 eth2.200
Thank you!
Finally! Found this question on ServerFault that addresses the same thing. Basically the kernel was not forwarding on / was filtering out the packets because it thought the sourced address was spoofed.
Changed the settings in /etc/sysctl.conf to match:
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.ip_forward = 1
Rebooted and everything works.