LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Networking
User Name
Password
Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.

Notices


Reply
  Search this Thread
Old 04-30-2012, 01:34 AM   #1
Sreeram B S
LQ Newbie
 
Registered: Apr 2006
Posts: 26

Rep: Reputation: 0
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
 
Old 05-01-2012, 02:22 PM   #2
nini09
Senior Member
 
Registered: Apr 2009
Posts: 1,850

Rep: Reputation: 161Reputation: 161
DHCP Discover response message is unicast packet. You should open normal UDP socket to receive it.
 
Old 05-02-2012, 06:56 AM   #3
Sreeram B S
LQ Newbie
 
Registered: Apr 2006
Posts: 26

Original Poster
Rep: Reputation: 0
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
 
Old 05-02-2012, 02:20 PM   #4
nini09
Senior Member
 
Registered: Apr 2009
Posts: 1,850

Rep: Reputation: 161Reputation: 161
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.
 
Old 05-03-2012, 02:56 AM   #5
Sreeram B S
LQ Newbie
 
Registered: Apr 2006
Posts: 26

Original Poster
Rep: Reputation: 0
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
 
Old 05-03-2012, 02:44 PM   #6
nini09
Senior Member
 
Registered: Apr 2009
Posts: 1,850

Rep: Reputation: 161Reputation: 161
You need setup server address in recv_dhcp_offer(sock).
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] UDP broadcast from multiple IPs on interface jonshouse Programming 3 02-11-2012 04:45 AM
[SOLVED] Linux udp broadcast socket wierdness jonshouse Programming 4 01-03-2012 01:11 PM
broadcast (udp) socket - multi processes emarri Programming 1 09-25-2006 06:06 AM
Unable to receive data in an udp socket stephenwalter Programming 8 11-24-2005 11:20 PM
How to receive UDP and ICMP packets, by one UDP socket(PMTUD) myself_rajat Linux - Networking 0 05-28-2004 05:43 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Networking

All times are GMT -5. The time now is 11:53 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration