I'm programing in python 2.7 and i have tried to write a function which asking for ip address from the DHCP server, the problem is that after I'm sending the packet and do sniffing for DHCP offer the sniffing doesn't catch it(i can see the offer on wireshark), I have no idea why, a friend of mine told me that maybe, since the net isn't so loaded the DHCP offer response is too fast(between the DHCP-descover and offer there's 0.000335059 sec, according wireshark) and the sniffing start working after the offer has
arrived.
so first, is it true?
If this is true how can i fix it?
here's the script
def get_ip_address(mac):
ethernet = Ether(dst='ff:ff:ff:ff:ff:ff', src=myMac, type=0x800)
ip = IP(src='0.0.0.0', dst='255.255.255.255')
udp = UDP(sport=68, dport=67)
bootp = BOOTP(chaddr=mac, ciaddr='0.0.0.0', xid=0x01020304, flags=1)
dhcp = DHCP(options=[("message-type", "discover"), "end"])
packet = ethernet / ip / udp / bootp / dhcp
**sendp(packet, iface=myInterface)**
**a= sniff(count=1, iface=myInterface,filter="(udp) and(port 67 or port 68)")**
dhcp1 = DHCP(options=[("message-type", "request"), ("server_id", a[BOOTP][0][3].siaddr),
("requested_addr", a[BOOTP][0][3].yiaddr), "end"])
req_packet = ethernet / ip / udp / bootp / dhcp1
sendp(req_packet, iface=myInterface)
returned_ip = a[BOOTP][0][3].yiaddr
return returned_ip
Related
I am new to networking. And have found using scapy a great way to learn different protocols.
I am trying to send a DHCPDISCOVER packet, however in wireshark it comes out as a malformed packet.
Here is the code I use to construct the packet (my MAC address has been excluded and replaced with "[my MAC address]":
ethernet = Ether(dst='ff:ff:ff:ff:ff:ff',src="[my MAC address]",type=0x800)
ip = IP(src ='0.0.0.0',dst='255.255.255.255')
udp = UDP (sport=68,dport=67)
fam,hw = get_if_raw_hwaddr("Wi-Fi")
bootp = BOOTP(chaddr = hw, ciaddr = '0.0.0.0',xid = 0x01020304,flags= 1)
dhcp = DHCP(options=[("message-type","discover"),"end"])
packet = ethernet / ip / udp / bootp / dhcp
scap.send(packet, iface="Wi-Fi")
This is the wireshark result of the packet:
14 2.065968 ASUSTekC_a5:fa:7a Broadcast IPX 300 [Malformed Packet]
Thanks!
If you're going to specify layer 2, you need to use the *p variants of the send/receive functions instead:
scap.sendp(packet, iface="Wi-Fi")
I have to admit, I haven't gotten around to looking into exactly why this otherwise results in a malformed packet, but I've assumed it attempts to add a layer 2 protocol to the packet for you, resulting in two such layers in the final packet.
I'm trying to make an arpspoofing attack with scapy.
I'm working with virtualbox in Linux Min OS, My attack machine is KaliLinux and my target is Metasploitable.
This is my scapy script:
targetIP="192.168.56.103"
gatewayIP="192.168.56.1"
myIP="192.168.56.101"
targetMAC="08:00:27:57:58:54"
myMAC="08:00:27:7d:94:1e"
a = ARP()
a.psrc = gatewayIP
a.pdst = targetIP
a.hwdst = targetMAC
a.hwsrc = myMAC
a.op = 2
send(a)
After i sent a i would expect that arp table of target will be
gatewayIP => myMAC
but instead I get
myIp => myMAC
What am i doing wrong?
If you want to see arp table in Kalilinux; you can write arp --a on prompt. And also if you want to attack you can use;
arpspoof -i eth0 --targetIP NetworkDeviceIP
arpspoof -i eth0 --NetworkDeviceIP targetIP
But do not forget to make IP forward.
I hope, it will work.
I have a problem to connect 2 computers by using UDP protocol. As reference I've used broadcast server and broadcast receiver provided by qt (version 5.9). So what's the problem. When I want to check this 2 programs on one computer, they works correct, but when i use them on the different machines, all crashes. Datagrams wasn't received by receiver computer. What am i do wrong? Could anyone answer me.
sender code:
void Sender::broadcastDatagram()
{
statusLabel->setText(tr("Now broadcasting datagram %1").arg(messageNo));
//! [1]
QByteArray datagram = "Broadcast message " + QByteArray::number(messageNo);
udpSocket->writeDatagram(datagram.data(), datagram.size(),
QHostAddress::Broadcast, 45454);
//! [1]
++messageNo;
}
`
and receiver
udpSocket->bind(QHostAddress::Any,45454, QUdpSocket::ShareAddress);
sender ip is 127.0.0.1 ;
receiver ip is 10.0.0.10
My goal is to send UDP packets from the microcontroller (nucleo board) to the PC - as simple as that. Update: I reached the goal successfully. I'll explain here how I did it, and the problems I stumbled upon initially. Many thanks to the StackOverflow community and people on LinkedIn ARM group to help me out!
1. SYSTEM OVERVIEW
My system is as follows:
1.1 Microcontroller side
Nucleo_F767ZI board with STM32F767ZI microcontroller. This board has an ethernet connector.
Mbed-OS 5 operating system.
lwip library (wich is part from the Mbed-OS 5 operating system).
1.2 PC side 🖳
Windows 10, 64-bit.
Free ethernet port (internet is through WiFi, that's why this ethernet port is unused).
Wireshark to see if the microcontroller actually sends out UDP packets. Interpretation of them will be done later on in Python. First I want to see packets in Wireshark.
1.3 Connections
Initially I connected the nucleo board directly to my computer, without a router or switch involved. Such a setup requires "static IP configuration". I would configure the PC to have IP address "192.168.1.10" and the microcontroller to have "192.168.1.20". I know this can work, because I've done it before with a PIC microcontroller.
But this situation is a little different. I got a little operating system running on the microcontroller: mbed-os v5. This operating system makes use of Lwip (Light-weight ip stack). Although it should be possible to configure a "static IP address", the software currently doesn't support it. More information can be found here: https://developer.mbed.org/questions/74145/EthernetInterfaceinit-mbed-os-5x-not-wor/. Because there is no way to configure a static IP address on the microcontroller, you need a DHCP server. The microcontroller connects to the network without an IP address, and broadcasts a packet with the question: "What IP address should I use on this network?". If the microcontroller doesn't get an answer, it will broadcast the question a few times, and eventually give up.
If there is a DHCP server connected to the network, it will receive the question and hand over a free IP address. So that is what you need. There are several ways to provide such a DHCP server:
Install a DHCP server on your Windows PC. This is the only way to keep switches and routers out of the picture. The nucleo board is connected directly to the PC. When the microcontroller broadcasts the question, the Windows PC hands over an IP address. After that, communication can start.
Throw a Raspberry PI into the game. The Raspberry PI should run a DHCP server. Connect the three devices (Windows PC, Raspberry PI and Nucleo board) to a switch.
Buy a simple router. Home routers have a DHCP server built-in. Connect the Windows PC and the Nucleo board to the LAN ports of this router.
I decided to go for the third option. The following figure shows the connections to my Netgear R7000 router:
2. ROUTER SETUP
The DHCP server inside the router will hand out IP addresses to all devices that connect to it. My router will hand out the IP address "192.168.1.2" to the first device, "192.168.1.3" to the second, and so forth all the way up to "192.168.1.254". But that's a bit problematic. How can the PC and the microcontroller know each others IP addresses? Perhaps there are more clever solutions, but I've figured out the following approach.
Each DHCP server has a table with "reserved IP addresses". In this table, you can add devices and assign a static IP address to them. So whenever that device asks for an IP address, the DHCP server takes a look in the table and hands over the one you've configured. But how does the DHCP server recognizes a device? It can recognize a device by its MAC-address. Every device has a globally unique MAC-address of 6 bytes.
This is how I've added my Windows PC and my microcontroller to the table:
STEP 1: Connect the computer to one of the LAN ports of the router. Switch the router on.
STEP 2: Make sure that all WiFi on your computer is disconnected. I've experienced lots of issues with this. (*)
STEP 3: Open a browser, and surf to "192.168.1.1". This is my routers home page. It could be different for your router.
STEP 4: Login (my routers default login is "admin" for the username and "password" for the password)
STEP 5: Add the Windows PC and the microcontroller board to the table. You have to look up their MAC-addresses first (**):
2.1 Disconnect all WiFi (*)
This should be a simple step, but Windows makes it hard. Windows can be quite stubborn and reconnect automatically to WiFi networks around, even if you've unchecked the connect automatically box! To force Windows to listen to you, you can use the cmd terminal. Open a cmd terminal with admin privileges. Next, type the following command to see all your WiFi profiles:
> netsh wlan show profiles
Apply the following command to those WiFi profiles that your PC is stubbornly connecting to:
> netsh wlan set profileparameter name="someWifiName" connectionmode=manual
Now you can disconnect from that WiFi network, and Windows won't reconnect automatically anymore.
2.2 Find the MAC address of your PC (**)
This is how I found the MAC-address of my computer. Keep in mind that a computer can have several MAC-addresses. The one for your ethernet port will be different to the one for your wireless connection! Type ipconfig /all in the Windows cmd terminal. I got the following output:
# Note: this is the correct item!
# --------------------------------
Ethernet adapter Local Area Connection:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Intel(R) Ethernet Connection (2) I219-LM
Physical Address. . . . . . . . . : C8-xx-xx-xx-xx-01 # Replaced some numbers by x for security :-)
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Make sure you're looking at the correct item in the list of connections. Ethernet adapter Local Area Connection is the correct one for my computer, because the network card description fits what is expected: Intel(R) Ethernet Connection (2) I219-LM. Before, I was looking at another item in the list, labelled Ethernet adapter Ethernet:
# Note: this is the wrong item!
# ------------------------------
Ethernet adapter Ethernet:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : TAP-Windows Adapter V9
Physical Address. . . . . . . . . : 00-xx-xx-xx-xx-F7
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Mr. Joel C (see his answer below) notified me that the network card from that item is TAP-Windows Adapter V9. Apparently that is a virtual network card. That made me lose a lot of time. Thank you Mr. Joel C for helping me out!
Please make also sure that DHCP Enabled and Autoconfiguration Enabled are turned on!
2.3 Find the MAC address of your Nucleo board (**)
I found the MAC-address of my Nucleo board with the following code:
#include "lwip-interface/EthernetInterface.h"
//1. Make an ethernet object
EthernetInterface eth;
//2. Try to connect
eth.connect(); // <- This line will not work now,
// but at least it will help you to find out your
// own MAC-address.
//3. Print the MAC-address
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
The print output I got over my serial port is (some numbers I replaced by x for security):
Controller MAC Address is: 00:xx:xx:xx:xx:40
3. MICROCONTROLLER CODE
This is the code that runs on the microcontroller. My main.cpp file is inspired on the code found on the Mbed-os forum at https://forums.mbed.com/t/udp-receive-with-nucleo-f767zi/1806.
#include <string>
using std::string;
#include "mbed.h"
#include "lwip-interface/EthernetInterface.h"
static Serial logger(USBTX, USBRX);
static DigitalOut led1(LED1);
// IP addresses
#define IP_COMPUTER "192.168.1.10" // Make sure these IP addresses correspond to the
#define IP_NUCLEO "192.168.1.20" // table of 'reserved IP addresses' you have setup in
// your routers DHCP server!
// Ethernet settings
const int PORT_T = 50000;
const int PORT_R = 50001;
EthernetInterface eth;
static void udp_tx_thread_func();
static void udp_rx_thread_func();
static Thread udp_tx_thread;
static Thread udp_rx_thread;
int main()
{
// 1. Initialize the serial logger
logger.baud(115200);
logger.printf("\r\n\r\nApplication started\r\n");
// 2. Initialize and start the UDP connection
eth.connect();
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
logger.printf("Controller IP Address is: %s\r\n", eth.get_ip_address());
Thread::wait(200);
udp_tx_thread.start(udp_tx_thread_func);
udp_rx_thread.start(udp_rx_thread_func);
while (true)
{
led1 = !led1;
Thread::wait(500);
}
}
//------------------ Ethernet --------------------------------------------------
static void udp_tx_thread_func()
{
UDPSocket socket(ð);
SocketAddress sock_addr(IP_COMPUTER, PORT_T);
static uint32_t out_buffer[3];
while(true)
{
Thread::wait(100);
// Send 3 values of 32-bit each
out_buffer[0] = 150500;
out_buffer[1] = 255300;
out_buffer[2] = 54;
int ret = socket.sendto(sock_addr, &out_buffer[0], 12); // 3 values of 32-bit equals 12 bytes
//logger.printf("sendto return: %d\r\n", ret);
}
}
static void udp_rx_thread_func()
{
UDPSocket socket(ð);
SocketAddress sock_addr;
int bind = socket.bind(PORT_R);
logger.printf("bind return: %d\n", bind);
char buffer[256];
while(true)
{
//logger.printf("\nWait for packet...\n");
int n = socket.recvfrom(&sock_addr, buffer, sizeof(buffer));
buffer[n] = '\0';
//logger.printf("Packet from \"%s\": %s\n", sock_addr.get_ip_address(), buffer);
Thread::wait(500);
}
}
4. RESULTS
4.1 Wireshark results
In Wireshark I can see the UDP packets flowing in on the Local Area Connection! Huray!
4.2 Python code
The python code to catch the UDP packets looks like this:
import sys
import os
import socket
import dataprocessing.datastruct as datastruct
def main():
# 1. Configure the IP address
# -----------------------------
myAddr = ('192.168.1.10', 50000)
# 2. Create a UDP socket
# -----------------------
sock = None
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(1.5)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(myAddr)
print('UDPsock #: ' + str(sock.getsockname()))
sys.stdout.flush()
except Exception as e:
print('Could not bind to the UDP socket.')
print(e)
sys.stdout.flush()
while (true):
try:
data, address = sock.recvfrom(256) # buffer size is 256 bytes
bytedata = bytearray(data)
# Each 32-bit number is cut in 8-bit pieces. Bring them back together.
value_01 = bytedata[0] + 256*bytedata[1] + 65536*bytedata[2] + 16777216*bytedata[3]
value_02 = bytedata[4] + 256*bytedata[5] + 65536*bytedata[6] + 16777216*bytedata[7]
value_03 = bytedata[8] + 256*bytedata[9] + 65536*bytedata[10] + 16777216*bytedata[11]
print("Value 01: %d", value_01)
print("Value 02: %d", value_02)
print("Value 03: %d", value_03)
except socket.error as err:
print(err)
if __name__== '__main__':
print("")
print("Start UDP catcher")
print("-----------------")
main()
5. LET WIFI AND ETHERNET COEXIST
The UDP packets from the microcontroller flow in on your ethernet port (passing along the router). Meanwhile you might want to connect to some WiFi network for internet access. The problem is that any browser will try to get access through your ethernet port - ignoring the WiFi.
The solution is to make your browsers FIRST attempt to use the WiFi to reach an IP address, next attempt through the Ethernet port. This is done with the "Interface metric" in the Control Panel. Increase this number slightly:
The connection you have labelled Ethernet is actually a TAP connection (eg. a virtual ethernet card). Your actual ethernet connection is labelled Local Area Connection; that is the connection you will need to be configuring and watching with Wireshark, etc.
As to everything else Mbed-OS related, I personally have not dealt with it.
I am having an issue trying to communicate between a python TCP server and a c++ TCP client.
After the first call, which works fine, the subsequent calls cause issues.
As far as WinSock is concerned, the send() function worked properly, it returns the proper length and WSAGetLastError() does not return anything of significance.
However, when watching the packets using wireshark, i notice that the first call sends two packets, a PSH,ACK with all of the data in it, and an ACK right after, but the subsequent calls, which don't work, only send the PSH,ACK packet, and not a subsequent ACK packet
the receiving computers wireshark corroborates this, and the python server does nothing, it doesnt have any data coming out of the socket, and i cannot debug deeper, since socket is a native class
when i run a c++ client and a c++ server (a hacked replica of what the python one would do), the client faithfully sends both the PSH,ACk and ACK packets the whole time, even after the first call.
Is the winsock send function supposed to always send a PSH,ACK and an ACK?
If so, why would it do so when connected to my C++ server and not the python server?
Has anyone had any issues similar to this?
client sends a PSH,ACK and then the
server sends a PSH,ACK and a
FIN,PSH,ACK
There is a FIN, so could it be that the Python version of your server is closing the connection immediately after the initial read?
If you are not explicitly closing the server's socket, it's probable that the server's remote socket variable is going out of scope, thus closing it (and that this bug is not present in your C++ version)?
Assuming that this is the case, I can cause a very similar TCP sequence with this code for the server:
# server.py
import socket
from time import sleep
def f(s):
r,a = s.accept()
print r.recv(100)
s = socket.socket()
s.bind(('localhost',1234))
s.listen(1)
f(s)
# wait around a bit for the client to send it's second packet
sleep(10)
and this for the client:
# client.py
import socket
from time import sleep
s = socket.socket()
s.connect(('localhost',1234))
s.send('hello 1')
# wait around for a while so that the socket in server.py goes out of scope
sleep(5)
s.send('hello 2')
Start your packet sniffer, then run server.py and then, client.py. Here is the outout of tcpdump -A -i lo, which matches your observations:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 96 bytes
12:42:37.683710 IP localhost:33491 > localhost.1234: S 1129726741:1129726741(0) win 32792 <mss 16396,sackOK,timestamp 640881101 0,nop,wscale 7>
E..<R.#.#...............CVC.........I|....#....
&3..........
12:42:37.684049 IP localhost.1234 > localhost:33491: S 1128039653:1128039653(0) ack 1129726742 win 32768 <mss 16396,sackOK,timestamp 640881101 640881101,nop,wscale 7>
E..<..#.#.<.............C<..CVC.....Ia....#....
&3..&3......
12:42:37.684087 IP localhost:33491 > localhost.1234: . ack 1 win 257 <nop,nop,timestamp 640881102 640881101>
E..4R.#.#...............CVC.C<......1......
&3..&3..
12:42:37.684220 IP localhost:33491 > localhost.1234: P 1:8(7) ack 1 win 257 <nop,nop,timestamp 640881102 640881101>
E..;R.#.#...............CVC.C<......./.....
&3..&3..hello 1
12:42:37.684271 IP localhost.1234 > localhost:33491: . ack 8 win 256 <nop,nop,timestamp 640881102 640881102>
E..4.(#.#...............C<..CVC.....1}.....
&3..&3..
12:42:37.684755 IP localhost.1234 > localhost:33491: F 1:1(0) ack 8 win 256 <nop,nop,timestamp 640881103 640881102>
E..4.)#.#...............C<..CVC.....1{.....
&3..&3..
12:42:37.685639 IP localhost:33491 > localhost.1234: . ack 2 win 257 <nop,nop,timestamp 640881104 640881103>
E..4R.#.#...............CVC.C<......1x.....
&3..&3..
12:42:42.683367 IP localhost:33491 > localhost.1234: P 8:15(7) ack 2 win 257 <nop,nop,timestamp 640886103 640881103>
E..;R.#.#...............CVC.C<......./.....
&3%W&3..hello 2
12:42:42.683401 IP localhost.1234 > localhost:33491: R 1128039655:1128039655(0) win 0
E..(..#.#.<.............C<......P...b...
9 packets captured
27 packets received by filter
0 packets dropped by kernel
What size of packets do you send?
If they are small - may be Nagle's Algorith & Delayed ACK Algorithm is your headache? From what you described think Delayed ACK is involved...