Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
04-30-2012, 01:34 AM
|
#1
|
LQ Newbie
Registered: Apr 2006
Posts: 26
Rep:
|
Unable to receive UDP broadcast from a UDP socket bound to an interface
Hi,
I have an program written with an intent to receive the broadcasted UDP packets. Unfortunately, I am not able to receive them.
I have made several attempts by making modifications here and there in the program, but in vain. I have now become idealess and I have turned to you for help/suggestion.
Kindly suggest.
Here are the set of things I do:
1. I have my interface eth0 up, but deliberately I have no IP address assigned. [This is order to simulate a situation when DHCP discover is sent during booting.]
2. Create UDP socket.
3. Bind to the eth0 using SO_BINDTODEVICE
4. Enable broadcasting for this socket SO_BROADCAST.
5. Build a DHCPDiscover message.
6. Broadcast the message. This will elicit a response from the DHCP server in the local LAN. I am able to see the response in wireshark.
7. Call recvfrom() to receive the message. << recvfrom() waits forever. It is not able to grab the response >>
The program is as follows:
----------------------------------------
[root@sreeramb-linux DHCP]# cat dhcp.c
/* This is a test program to bind a socket to an interface
* instead of to an IP address(which is done normally).
* Also, broadcasting is enabled for this socket so that
* any broadcast packet is sent over this socket.
*/
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#define SA struct sockaddr
#define IFC "eth0"
#define PORT 67
#define IFCSZ sizeof(IFC)
struct dhcp_header {
unsigned char op;
unsigned char htype;
unsigned char hlen;
unsigned char hops;
int xid;
short secs;
short flags;
struct in_addr ciaddr;
struct in_addr yiaddr;
struct in_addr siaddr;
struct in_addr giaddr;
unsigned char chaddr[16];
unsigned char sname[64];
unsigned char file[128];
unsigned char opts[128];
};
int main(int argc, char **argv) {
int sock, retn;
struct sockaddr_in peer, addr;
char mesg[] = "Hello World!";
int val=1, size = sizeof(val);
/* Create an UDP socket first. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Socket");
exit(-1);
}
printf("Created socket successfully.\n");
/* Enable the SO_DEBUG option for this socket. */
retn = setsockopt(sock, SOL_SOCKET, SO_DEBUG, &val, size);
if (retn < 0) {
perror("SO_DEBUG");
close(sock);
exit(-1);
}
printf("Successfully enabled the SO_DEBUG flag for the socket.\n");
/* Now, set the SO_REUSEADDR flag for this socket. */
retn = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, size);
if (retn < 0) {
perror("SO_REUSEADDR");
close(sock);
exit(-1);
}
printf("Successfully set the SO_REUSEADDR flag to this socket.\n");
#if 0
/* Set the structure to send to the broadcast address. */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(6800);
retn = bind(sock, (SA *)&addr, sizeof(SA));
if (retn < 0) {
perror("BIND_TO_PORT");
close(sock);
exit(-3);
}
printf("Successfully bound to port 68 also.\n");
#endif
/* Now, bind to device, eth0 */
retn = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, IFC, IFCSZ);
if (retn < 0) {
perror("SO_BINDTODEVICE:eth0");
close(sock);
exit(-1);
}
printf("Successfully bound to device '%s'\n", IFC);
/* Now, set the broadcast flag for this socket. */
val = 1, size = sizeof(val);
retn = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, size);
if (retn < 0) {
perror("SO_BROADCAST");
close(sock);
exit(-1);
}
printf("Successfully set the broadcast flag to this socket.\n");
/* Set the structure to send to the broadcast address. */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
inet_aton("255.255.255.255", &addr.sin_addr);
send_dhcp_discover(sock, addr);
recv_dhcp_offer(sock);
}
int send_dhcp_discover(int sock, struct sockaddr_in addr) {
int retn, i = 0;
struct dhcp_header hdr;
memset(&hdr, 0, sizeof(hdr));
hdr.op = 1;
hdr.htype = 1;
hdr.hlen = 6;
hdr.xid = 1;
hdr.flags = 128;
hdr.chaddr[0] = 0x08;
hdr.chaddr[1] = 0x00;
hdr.chaddr[2] = 0x27;
hdr.chaddr[3] = 0x9D;
hdr.chaddr[4] = 0x13;
hdr.chaddr[5] = 0xEE;
/* The first four octets are supposed to be magic number. */
hdr.opts[i++] = 99;
hdr.opts[i++] = 130;
hdr.opts[i++] = 83;
hdr.opts[i++] = 99;
/* The next option depicts the message type. */
hdr.opts[i++] = 53; // DHCP message type.
hdr.opts[i++] = 1; // Length = 1
hdr.opts[i++] = 1; // DHCP Discover message.
/* Let the client make a wish that it be assigned 192.168.1.25 */
hdr.opts[i++] = 50; // Preferred IP address
hdr.opts[i++] = 4; // Length = 4
inet_aton("192.168.1.25", (struct in_addr *)&hdr.opts[i]);
i += 4;
hdr.opts[i++] = 255; // End of options.
/* Now, broadcast the message. */
retn = sendto(sock, &hdr, sizeof(hdr), 0, (SA *)&addr, sizeof(SA));
if (retn < 0) {
perror("sendto");
close(sock);
exit(-2);
}
printf("Successfully broadcasted the message.\n");
printf("IFC size is %d\n", IFCSZ);
return 0;
}
/* This program will receive the DHCP offer message */
int recv_dhcp_offer(int sock) {
int retn, size = sizeof(SA);
struct sockaddr_in server;
unsigned char mesg[sizeof(struct dhcp_header)];
/* Receive the message */
retn = recvfrom(sock, mesg, sizeof(mesg), 0, (SA *)&server, &size);
if (retn < 0) {
perror("recvfrom");
exit(-1);
}
printf("Received message: DHCP OFFER\n");
return 0;
}
[root@sreeramb-linux DHCP]#
------------------------------------------
Am I missing something very obvious. Kindly guide me as I want to proceed with this program.
With regards,
Sreeram
|
|
|
05-01-2012, 02:22 PM
|
#2
|
Senior Member
Registered: Apr 2009
Posts: 1,881
Rep:
|
DHCP Discover response message is unicast packet. You should open normal UDP socket to receive it.
|
|
|
05-02-2012, 06:56 AM
|
#3
|
LQ Newbie
Registered: Apr 2006
Posts: 26
Original Poster
Rep:
|
Hi,
Thanks for the response. Could you please elaborate your suggestion please?
Do you suggest that I open another UDP socket, NOT set the broadcast flags etc and bind to port 67 and
start listening?
Please elaborate.
Regards,
Sreeram
|
|
|
05-02-2012, 02:20 PM
|
#4
|
Senior Member
Registered: Apr 2009
Posts: 1,881
Rep:
|
My suggestion is following.
1)Open a normal UDP socket.
2)Send to boardcast address, DHCP Discover.
3)Receive from server DHCP address, DHCP Discover response.
|
|
|
05-03-2012, 02:56 AM
|
#5
|
LQ Newbie
Registered: Apr 2006
Posts: 26
Original Poster
Rep:
|
Hi,
I cleared the broadcast flag before calling recvfrom(). But even that did not solve the problem.
Just pasting only the changed part (and one line before and after the portion of change):
send_dhcp_discover(sock, addr);
/* Now, clear the broadcast flag for this socket. */
val = 0, size = sizeof(val);
retn = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, size);
if (retn < 0) {
perror("SO_BROADCAST");
close(sock);
exit(-1);
}
printf("Successfully cleared the broadcast flag to this socket.\n");
recv_dhcp_offer(sock);
Please suggest what could be wrong.
Or is there any flaw in the approach of reading DHCP offer from a UDP socket bound to port. [In the RFC, it says that DHCP/BOOTP is built on UDP. So, I dont think I can use raw sockets here.]
Regards,
Sreeram
|
|
|
05-03-2012, 02:44 PM
|
#6
|
Senior Member
Registered: Apr 2009
Posts: 1,881
Rep:
|
You need setup server address in recv_dhcp_offer(sock).
|
|
|
All times are GMT -5. The time now is 09:03 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|