I am trying to mimic a DHCP client from my end using C++ Code. My objective is to get some free/unused IP's from the DHCP server to assign it to different equipments - similar to a DHCP Relay, but not technically the same. My CLIENT is running on an Embedded linux platform and talks to a DHCP server via our internal network.
As per the DHCP protocol there is a formal procedure (DISCOVER, OFFER, REQUEST, ACK/NAK, RELEASE) to communicate with the DHCP server.According to the RFC's(2131), when I do a DISCOVER, I receive and OFFER with an unused IP address in the YIAddr field. I further use this IP address in my REQUEST message using option 50 as mentioned in RFC 2132.
My main router, make- Edgewater(which is also the DHCP server) on sending a DISCOVER message, sends back an OFFER message with an unused IP address in the YIAddr field (I used this unused IP in my consequent REQUEST message), which is my requirement. I did the same experiment with few other router's (NetGear, Dlink, Broadcom) and found that the OFFER message is sending me back the same IP address of the CLIENT that is requesting the unused IP's. I am curious to know why this is happening. As I understand, I'm following the steps mentioned in RFC2131/RFC2131/RFC4361 for creating my DHCP packet format.
Is there a specific format or specific option that the other DHCP server/Routers are expecting to give out unused IP's? I am using a unique client identifier in my option field as mentioned in RFC4361.
This is a snap shot of the section where I'm creating the dhcp packet.
request_packet.m_OperationCode = 0x01;
request_packet.m_HwareType = 0x01;
request_packet.m_HwareLen = 0x06;
request_packet.m_Hops = 0x01;
request_packet.m_XID = htonl(XID[m_numberOfIPs]);
request_packet.m_Secs = htons(0x10);
request_packet.m_flags = htons(0x8000);
request_packet.m_CIAddr = 0x000000; //Client IP
request_packet.m_YIAddr = 0x000000; //Your IP
request_packet.m_SIAddr = 0x000000; //Server IP
request_packet.m_GIAddr = 0x000000;
request_packet.m_CHAddr[0] = MACADDRESS[m_numberOfIPs][0];
request_packet.m_CHAddr[1] = MACADDRESS[m_numberOfIPs][1];//[1];
request_packet.m_CHAddr[2] = MACADDRESS[m_numberOfIPs][2];//[2];
request_packet.m_CHAddr[3] = MACADDRESS[m_numberOfIPs][3];//[3];
request_packet.m_CHAddr[4] = MACADDRESS[m_numberOfIPs][4];//[4];
request_packet.m_CHAddr[5] = MACADDRESS[m_numberOfIPs][5];//[5];
memset(request_packet.m_CHAddr+6, 0, 10);
memset(request_packet.m_SName, 0, 64);
memset(request_packet.m_File, 0, 128);
request_packet.m_pOptions[0] = 99; //Start of magic cookie
request_packet.m_pOptions[1] = 130;
request_packet.m_pOptions[2] = 83;
request_packet.m_pOptions[3] = 99; //end of magic cookie
Options Field
DISCOVER message
CID and DUID are random unique numbers to create a unique client identifier
request_packet.m_pOptions[4] = 53; //DHCP MESSAGE TYPE OPTION CODE
request_packet.m_pOptions[5] = 1; //OPTION DATA LEN
request_packet.m_pOptions[6] = 1; //DHCP DISCOVER
request_packet.m_pOptions[7] = 55; //Parameter Request List
request_packet.m_pOptions[8] = 7; //Length
request_packet.m_pOptions[9] = 1; //Subnet Mask
request_packet.m_pOptions[10] = 3; //Router
request_packet.m_pOptions[11] = 6; //Domain Name Server
request_packet.m_pOptions[12] = 12; // Host Name
request_packet.m_pOptions[13] = 15; //Domain Name
request_packet.m_pOptions[14] = 28; //Broadcast Address
request_packet.m_pOptions[15] = 42; //NTP servers
request_packet.m_pOptions[16] = 51; //IP Address Lease Time
request_packet.m_pOptions[17] = 4;
request_packet.m_pOptions[18] = 0x00;
request_packet.m_pOptions[19] = 0x00;
request_packet.m_pOptions[20] = 0xFF;
request_packet.m_pOptions[21] = 0xFF;
request_packet.m_pOptions[22] = 61;//Client Identifier code
request_packet.m_pOptions[23] = 15;//Length
request_packet.m_pOptions[24] = 255;//IAID Type
printf("The CID generated inside REQUEST is %x\n", CID[m_numberOfIPs]);
request_packet.m_pOptions[25] = CID[m_numberOfIPs][0];
request_packet.m_pOptions[26] = CID[m_numberOfIPs][1];
request_packet.m_pOptions[27] = CID[m_numberOfIPs][2];
request_packet.m_pOptions[28] = CID[m_numberOfIPs][3];
request_packet.m_pOptions[29] = 0x00;//DUID Type
request_packet.m_pOptions[30] = 0x03;//DUID Type
request_packet.m_pOptions[31] = 0x00;//HW Type code - Ethernet
request_packet.m_pOptions[32] = 0x01;//HW Type code - Ethernet
request_packet.m_pOptions[33] = DUID[m_numberOfIPs][0];
request_packet.m_pOptions[34] = DUID[m_numberOfIPs][1];
request_packet.m_pOptions[35] = DUID[m_numberOfIPs][2];
request_packet.m_pOptions[36] = DUID[m_numberOfIPs][3];
request_packet.m_pOptions[37] = DUID[m_numberOfIPs][4];
request_packet.m_pOptions[38] = DUID[m_numberOfIPs][5];
request_packet.m_pOptions[39] = (0xff); // End option
REQUEST message
request_packet.m_pOptions[4] = 53; //DHCP MESSAGE TYPE OPTION CODE
request_packet.m_pOptions[5] = 1; //OPTION DATA LEN
request_packet.m_pOptions[6] = 3; //DHCP REQUEST
request_packet.m_pOptions[7] = 50; //DHCP REQUESTION OPTION
request_packet.m_pOptions[8] = 4; //OPTION DATA LEN
request_packet.m_pOptions[9] = (m_YourIP & 0xff000000)>>24; //first byte
request_packet.m_pOptions[10] = (m_YourIP & 0xff0000)>>16; //second byte
request_packet.m_pOptions[11] = (m_YourIP & 0xff00)>>8; //third byte
request_packet.m_pOptions[12] = (m_YourIP & 0xff); //fourth byte
/*- Added by JA. Refer 3.1.3 Section of RFC2131.txt - Server identifier option*/
request_packet.m_pOptions[13] = 54;
request_packet.m_pOptions[14] = 4;
request_packet.m_pOptions[15] = (m_ServerIP & 0xff000000) >> 24; //first byte
request_packet.m_pOptions[16] = (m_ServerIP & 0xff0000)>>16; //second byte
request_packet.m_pOptions[17] = (m_ServerIP & 0xff00)>>8; //third byte
request_packet.m_pOptions[18] = (m_ServerIP & 0xff); //fourth byte
request_packet.m_pOptions[19] = 55; //Parameter Request List
request_packet.m_pOptions[20] = 7; //Length
request_packet.m_pOptions[21] = 1; //Subnet Mask
request_packet.m_pOptions[22] = 3; //Router
request_packet.m_pOptions[23] = 6; //Domain Name Server
request_packet.m_pOptions[24] = 12; // Host Name
request_packet.m_pOptions[25] = 15; //Domain Name
request_packet.m_pOptions[26] = 28; //Broadcast Address
request_packet.m_pOptions[27] = 42; //NTP servers
request_packet.m_pOptions[28] = 51; //IP Address Lease Time
request_packet.m_pOptions[29] = 4;
request_packet.m_pOptions[30] = 0x00;
request_packet.m_pOptions[31] = 0x00;
request_packet.m_pOptions[32] = 0xFF;
request_packet.m_pOptions[33] = 0xFF;
/*- Added by JA. Refer 6.1 Section of RFC4361.txt - Client identifier option*/
request_packet.m_pOptions[34] = 61;//Client Identifier code
request_packet.m_pOptions[35] = 15;//Length
request_packet.m_pOptions[36] = 255;//IAID Type
printf("The CID generated inside REQUEST is %x\n", CID[m_numberOfIPs]);
request_packet.m_pOptions[37] = CID[m_numberOfIPs][0];
request_packet.m_pOptions[38] = CID[m_numberOfIPs][1];
request_packet.m_pOptions[39] = CID[m_numberOfIPs][2];
request_packet.m_pOptions[40] = CID[m_numberOfIPs][3];
request_packet.m_pOptions[41] = 0x00;//DUID Type
request_packet.m_pOptions[42] = 0x03;//DUID Type
request_packet.m_pOptions[43] = 0x00;//HW Type code - Ethernet
request_packet.m_pOptions[44] = 0x01;//HW Type code - Ethernet
request_packet.m_pOptions[45] = DUID[m_numberOfIPs][0];
request_packet.m_pOptions[46] = DUID[m_numberOfIPs][1];
request_packet.m_pOptions[47] = DUID[m_numberOfIPs][2];
request_packet.m_pOptions[48] = DUID[m_numberOfIPs][3];
request_packet.m_pOptions[49] = DUID[m_numberOfIPs][4];
request_packet.m_pOptions[50] = DUID[m_numberOfIPs][5];
request_packet.m_pOptions[51] = (0xff); // End option
Using router as DHCP relay and server it will assign you Unique IP based DHCP subnetwork configured on it say 10.1.2.0/24 is the pool defined on router for DHCP requests it will assign you very first non-allocated IP against your MAC only and this assignment is random you can not reserve mac on router.After DORA it triggers lease timer for that MAC-IP .
If you use DHCP server Microsoft/Unix they they have extended functionality as reserving IP for particular mac permanently.
Related
I have a device using USB Serialport and, during the form load, I get the port number using below code. Actually, I googled and modified it.
ManagementClass processClass = new ManagementClass("Win32_PnPEntity");
ManagementObjectCollection Ports = processClass.GetInstances();
List<string> FTDIPorts = new List<string>();
int i = 0;
foreach (ManagementObject property in Ports)
{
string name = (string)property.GetPropertyValue("Name");
var manu = property.GetPropertyValue("Manufacturer");
if (name != null && name.ToString().Contains("USB") && name.ToString().Contains("COM") && Manu.ToString() == "FTDI")
{
FTDIPorts.Add(name.Substring(name.LastIndexOf("COM") + 3, 1));
}
}
It works, but it takes over 6 to 10seconds to get the port number! Are there any faster way of getting Serial Port number provided by specific manufacturer(for example, FTDI usb serial port)?
I am able to get the serial port number by searching registry "\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM". However, it does not give manufacturer information but only port number.
This is my program to display the ip address of a system.
IPHostEntry ip = Dns.GetHostEntry(Dns.GetHostName());
IPAddress[] IPaddr = ip.AddressList;
for (int i = 0; i < IPaddr.Length; i++)
{
Console.WriteLine("IP Address {0}: {1} ", i, IPaddr[i].ToString());
}
This displays the below output:
IP Address 0: fe80::90da:c637:d34a:c8a3%2
IP Address 1: 10.0.2.6
Why does this display two values? Isn't the second one the real ip address?
I am currently developing a program where Raspberry Pi 3 will read contents sent by 4 Arduino (USB) devices through serial communication every 100ms. The UI gets stuck on the fourth call (serialDeviceIndex = 3) of Concurrency::create_task but if there are only 3 Arduino devices, the problem is not happening and the thread execution continues to the .then lambda body. Can you help me pin point what is the problem? Here's the function called when the connect button from the xaml devices is pressed.
void MainPage::comPortInput_Click(Object^ sender, RoutedEventArgs^ e)
{
m_timer->Start();
auto selectionIndex = ConnectDevices->SelectedIndex;
if (selectionIndex < 0)
{
status->Text = "Select a device and connect";
return;
}
auto selectedItems = ConnectDevices->SelectedItems;
for (unsigned serialDeviceIndex = 0; serialDeviceIndex < selectedItems->Size; serialDeviceIndex++)
{
Device ^device = static_cast<Device ^>(selectedItems->GetAt(serialDeviceIndex));
textBox->Text = textBox->Text + "\n<START>:" + device->Id->ToString() + "<END>";
Windows::Devices::SerialCommunication::SerialDevice ^serial_device;
Windows::Devices::Enumeration::DeviceInformation ^entry = device->DeviceInfo;
auto childTokenSource = Concurrency::cancellation_token_source::create_linked_source(cancellationTokenSource->get_token());
auto childToken = childTokenSource.get_token();
Concurrency::create_task(
Windows::Devices::SerialCommunication::SerialDevice::FromIdAsync(entry->Id), childToken)
.then([this, serialDeviceIndex](Windows::Devices::SerialCommunication::SerialDevice ^serial_device)
{
_serialPort = serial_device;
Platform::String ^deviceString1 = _serialPort->ToString();
// Disable the 'Connect' button
//comPortInput->IsEnabled = false;
Windows::Foundation::TimeSpan _timeOut;
_timeOut.Duration = 100000L; //100000 works with delay(200)
// Configure serial settings
_serialPort->WriteTimeout = _timeOut;
_serialPort->ReadTimeout = _timeOut;
_serialPort->BaudRate = 9600;
_serialPort->Parity = Windows::Devices::SerialCommunication::SerialParity::None;
_serialPort->StopBits = Windows::Devices::SerialCommunication::SerialStopBitCount::One;
_serialPort->DataBits = 8;
_serialPort->Handshake = Windows::Devices::SerialCommunication::SerialHandshake::None;
_dataReaderObject = ref new Windows::Storage::Streams::DataReader(_serialPort->InputStream);
_dataReaderObject->InputStreamOptions = Windows::Storage::Streams::InputStreamOptions::Partial;
_dataReaderObjects.Append(_dataReaderObject);
_serialPorts.Append(_serialPort);
int serialPortsSize = _serialPorts.Size;
Listen(_serialPorts.GetAt(serialDeviceIndex), _dataReaderObject, serialDeviceIndex);
});
Sleep(5);
}
}
EDIT:
Okay, I simplified now the code to JUST this one
for (unsigned serialDeviceIndex = 0; serialDeviceIndex < selectedItems->Size; serialDeviceIndex++){
Device ^device = static_cast<Device ^>(selectedItems->GetAt(serialDeviceIndex));
textBox->Text = textBox->Text + "\n<START>:" + device->Id->ToString() + "<END>";
Windows::Devices::Enumeration::DeviceInformation ^entry = device->DeviceInfo;
auto it = Concurrency::create_task(Windows::Devices::SerialCommunication::SerialDevice::FromIdAsync(entry->Id));
while (!it.is_done())
textBoxStatus->Text = "processing" + deviceIndex.ToString();
it.get();
}
FYI, this code runs normally fine in my pc. no errors. When I try to run this in my RaspberryPi3 under Windows IoT the program hungs up at the fourth time I try to get the device using it.get()
I am trying to integrate the ADAU1761 codec with the Beaglebone Black. I need to configure a sound card in order to play audio through the codec.
I tried writing device tree overlay but did not succeed. Then I tried changing directly in the device tree.
Now the modes of the PINS are changed but the sound card is not getting configured.
am I going in the right direction? Please help.
Below are the changes I made in the device tree:
Pins mode change i2c:
pinmux_i2c2_pins {
pinctrl-single,pins = <0x178 0x0b 0x17c 0x0b>;
linux,phandle = <0x30>;
phandle = <0x30>;
Pins mode change i2s:
mcasp0_pins {
pinctrl-single,pins = <0x1ac 0x08 0x19c 0x2 0x194 0x08 0x190 0x08
0x6c 0x7 0x198 0x08>;
linux,phandle = <0x47>;
phandle = <0x47>;
};
Driver loading:
i2c#4819c000 {
compatible = "ti,omap4-i2c";
#address-cells = <0x1>;
#size-cells = <0x0>;
ti,hwmods = "i2c3";
reg = <0x4819c000 0x1000>;
interrupts = <0x1e>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <0x30>;
clock-frequency = <0x186a0>;
linux,phandle = <0x9d>;
phandle = <0x9d>;
adau1761: adau1361#38 {
compatible = "adi,adau1761";
reg = <0x38>;
};
Sound Card:
sound {
compatible = "adi,adau1761-evm-audio";
ti,model = "ADI ADAU1761";
ti,audio-codec = <&adau1761>;
ti,mcasp-controller = <0x52>;
ti,audio-routing =
"Headphone Jack", "LOUT",
"Headphone Jack", "ROUT",
"LINE1L", "LAUX",
"LINE1R", "RAUX";
clocks = <0x53>;
clock-names = "mclk";
};
I red about netmap which allows user programmers to access packets in the user space, that means user applications can read / send network packets very quickly using this netamp.
netmap :
http://info.iet.unipi.it/~luigi/netmap/
Can any one who are very familiar with netamp, tell me should we create entire packet that we want to send out, or we using the stack features to send it out.
Edit : here is example on how to use this api
https://www.freebsd.org/cgi/man.cgi?query=netmap&sektion=4
#include <net/netmap_user.h>
void sender(void)
{
struct netmap_if *nifp;
struct netmap_ring *ring;
struct nmreq nmr;
struct pollfd fds;
fd = open("/dev/netmap", O_RDWR);
bzero(&nmr, sizeof(nmr));
strcpy(nmr.nr_name, "ix0");
nmr.nm_version = NETMAP_API;
ioctl(fd, NIOCREGIF, &nmr);
p = mmap(0, nmr.nr_memsize, fd);
nifp = NETMAP_IF(p, nmr.nr_offset);
ring = NETMAP_TXRING(nifp, 0);
fds.fd = fd;
fds.events = POLLOUT;
for (;;) {
poll(&fds, 1, -1);
while (!nm_ring_empty(ring)) {
i = ring->cur;
buf = NETMAP_BUF(ring, ring->slot[i].buf_index);
// here they are saying to construct the packet
... prepare packet in buf ...
ring->slot[i].len = ... packet length ...
ring->head = ring->cur = nm_ring_next(ring, i);
}
}
}
You need to create entire packed, including ethernet, ip and tcp headers. Netmap completely bypasses kernel network stack, so you need to do all work yourself.