473,406 Members | 2,467 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

How to determine origin of incoming message (uincast/multicast/broadcast)

Plater
7,872 Expert 4TB
(Sorry about the title, i'm not sure how to explain this)

I am wondering if it is possible to tell on socket, HOW the incoming data was sent.
Now, what I mean by that is, I have a UDP socket just reading messages in a loop that come in on a port and pumping out a msg such like "Data from [IP Addy] arrived".
But if I "send" data to it, I want to know if it came from unicast, broadcast, or multicast.
Is that possible? It seems like it should be, but maybe I need to be in RAW mode and examine the bytes in the various headers?
Any thoughts?
Nov 2 '10 #1
17 12113
Oralloy
988 Expert 512MB
Do you mean you want to know if it was sent to a unicast, broadcast, or multicast address, or it was sent from such an address?

I think the answer is that you need to inspect the address to determine its status.

Here is the wikipedia on IP Multicast addressing.

Here are the pertinent bits from the article:

Unicast: The most common concept of an IP address is in unicast addressing, available in both IPv4 and IPv6. It normally refers to a single sender or a single receiver, and can be used for both sending and receiving. Usually, a unicast address is associated with a single device or host, but it is not a one-to-one correspondence. Some individual PCs have several distinct unicast addresses, each for its own distinct purpose. Sending the same data to multiple unicast addresses requires the sender to send all the data many times over, once for each recipient.

Broadcast: In IPv4 it is possible to send data to all possible destinations ("all-hosts broadcast"), which permits the sender to send the data only once, and all receivers receive a copy of it. In the IPv4 protocol, the address 255.255.255.255 is used for local broadcast. In addition, a directed (limited) broadcast can be made by combining the network prefix with a host suffix composed entirely of binary 1s. For example, the destination address used for a directed broadcast to devices on the 192.0.2.0/24 network is 192.0.2.255. IPv6 does not implement broadcast addressing and replaces it with multicast to the specially-defined all-nodes multicast address.

Multicast: A multicast address is associated with a group of interested receivers. In IPv4, addresses 224.0.0.0 through 239.255.255.255 (the former Class D addresses) are designated as multicast addresses.[2] The sender sends a single datagram from its unicast address to the multicast group address and the intermediary routers take care of making copies and sending them to all receivers that have joined the corresponding multicast group. IPv6 uses the address block with the prefix ff00::/8 for multicast applications.

Anycast (here for completeness): Like broadcast and multicast, anycast is a one-to-many routing topology. However, the data stream is not transmitted to all receivers, just the one which the router decides is the "closest" in the network.[Note 1] Anycast is useful for global load balancing and is commonly used in DNS communications.

I don't remember if there are macros available to check addresses or not, though.

Good luck!
Nov 2 '10 #2
Plater
7,872 Expert 4TB
I guess who it was going TO is my question.

For instance with that UDP socket spitting out packets it sees (call it the "server"), I did the following:
*Had a client software on the same system send a UDP message to 255.255.255.255 (broadcast) on the port and my "server" saw the message and said "message from 127.0.0.1"
*Had a client software on the same system send to a multicast ip and my "server" saw the message and said "message from 192.168.1.7" (which is the IP of the machine the code was running on)

I was wondering if on the server I could tell the difference between those two messages (and a unicast to 192.168.1.7).
Would I change my server to have sockets be bound to a specific address (one to 192.168.1.7 and one to the multicast address) would that allow me to tell them apart?

While it is not crucial to the design that i know how the messages were received by my server, it would make things a bit easier on me.

(For what it is worth, I am playing with UPNP and listening for traffic on 1900. Messages from the multicast address are going to be general discover/announce payloads, messages sent to ME(unicast) are directed responses)
Nov 2 '10 #3
Oralloy
988 Expert 512MB
It looks like you're doing local loop-back for your testing, from what I read, correct?

If I recall correctly, sockets can bind to multiple addresses on a system. This is especially important for listening sockets, as they'll listen on 127.0.0.1 (loopback) as well the systems "normal" addresses. If you want to mask out localhost-loopback messages from your testing, you'll need to be careful about that. The problem is exacerbated with each IP address you add to your system, of course.

Alternately, you can drain off all recieved messages, expecting to recieve multiples. I happen to think that this is the better option.

Remember that it's the recipient's IP address that determines how a message is moved around the network. Which means that you can sent to a multi-cast address from a unicast address, right? That is, I can send a message from my local (unicast) IP of 10.1.2.3 to the multicast IP 224.1.2.3, right?

So, the address you recieved the message at determines how the message was sent.

The address the message was sent from determines how the reply will be handled. [as an aside, this is how SMURF and other attacks are crafted using raw sockets].

Since I don't know what your application is, I'm not sure what else to tell you which will help. Hopefully I'm not confusing you here.

Cheers!
Nov 2 '10 #4
Plater
7,872 Expert 4TB
Well the end result would be the packets would be coming from other computers on my network, it is just in testing that i happened to be using the same machine for it.
I am thinking there is no good way to tell (outside of being in raw mode) I may have to look into that method
Nov 2 '10 #5
Oralloy
988 Expert 512MB
I guess I'm confused.

If you're listening on a UDP socket, you'll get the sender's address attached to your message. You already know the recieving address, if you set up your sockets correctly. Nothing prevents you from opening multiple listening sockets in parallel.

As for a TCP socket, you also get the sender's address as part of the connection request. Once listen() returns, you'll be able to get the address.
Nov 2 '10 #6
Plater
7,872 Expert 4TB
I know I can get the senders address, what i want is the address the sender SENT to.

If my server UDP socket is listening (IPANY, PORT 1900)
Has IP 192.168.1.7
Subscribed to multicast IP 239.255.255.250

If the client software:
Has IP 192.168.1.4
Sends one message unicast to 192.168.1.7:1900
Sends one message multicast to 239.255.255.250:1900
Sends one message to broadcast 255.255.255.255:1900

My server UDP will see all 3 messages, all will say they came from 192.168.1.4. Is there a way to tell on the SERVER which message was sent out in what manor (which one was sent to 239.255.255.250 and etc)?
Nov 3 '10 #7
Oralloy
988 Expert 512MB
Ok, I did some quick research, and it's not clear how to extract the recieving address from a conversation.

BTW, are you trying to build a network sniffer of some sort?

Regardless, I'm surprised that you're able to see multicast messages that you haven't registered in the multicast group for. That seems to be how the newer sockets protocol specification wants software to behave.

At this point, I'd start actively consider using raw sockets, just to make sure that I got all the requisite information from the incoming UDP packets. I can't think of any other way of extracting all requisite information, although we might have someone else here who is more knowledgable than I am.

Sorry I can't give you better information than that.

Good luck!
Nov 3 '10 #8
Plater
7,872 Expert 4TB
Just trying to implememnt UPNP "by hand" so to speak.
And sorry, yes I have subscribed to the multicast group with the IP_ADD_MEMBERSHIP.

I was hoping there was some sort of API to read the extra data from the packet, but i can see why there isn't.
Raw socket it is probably going to be.
Nov 4 '10 #9
Oralloy
988 Expert 512MB
Plater - you, Sir, are an ambitious man.

Good luck with your home-brew UPnP. I hope it works out well for you.

When you get done, let us know what your implementation is, would you, please?

Cheers!
Oralloy
Nov 4 '10 #10
Plater
7,872 Expert 4TB
It really was not so bad. I had notes from a few years ago when I tried to do raw sockets and failed.
Now it makes a lot more sense to me (and it works)

Expand|Select|Wrap|Line Numbers
  1. int s_sock =socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
  2. //SOCK_RAW             so you can get extra data in the recv packet
  3. //IPPROTO_UDP        sets the proto field to 0x11(UDP) in packets (expects 8byte UDP header before payload data)
  4. //this will make more sense later
  5.  
  6. //I do not need to call a bind(), all it does is allow sockaddr_in to be filled-in from the recvfrom call
  7. //You could use recv() and ignore the sockaddr_in stuff altogether I think.
  8. //Since I want to get messages on a multicast address, I *DO* still need to join it it would seem
  9. struct ip_mreq imreq;
  10. imreq.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
  11. imreq.imr_interface.s_addr = INADDR_ANY; // use DEFAULT interface
  12. // JOIN multicast group on default interface
  13. int status = setsockopt(s_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,(const void *)&imreq, sizeof(struct ip_mreq));
  14. if ( status < 0 )
  15. {//failure!
  16.      perror("Trying to join multicast group");//this will print a nice message about ERRNO
  17.      return 0;
  18. }
  19.  
  20. struct sockaddr_in from;//This will never fill in correctly if you don't do a BIND
  21. socklen_t fromlen = sizeof(struct sockaddr_in);
  22. char buf[1024];
  23. memset(buf,0x00,1024);
  24. int n = recvfrom(s_sock,buf,1024,0,(struct sockaddr *)&from,&fromlen);
  25. /* //the first 20bytes [0-19] are the basic header
  26. buf[0]=         (Version 4 and header length=20bytes)
  27. buf[1]=         (diferentiated service field)
  28. buf[2-3]=        (total length)
  29. buf[4-5]=        (identification)
  30. buf[6-7]=        (Flags(0x04)+fragment offset=0)
  31. buf[8]=         (TTL)
  32. buf[9]=         (protocol)
  33. buf[10-11]=    (header checksum)
  34. buf[12-15]= (source ip)
  35. buf[16-19]= (dest ip)
  36. */
  37.  
  38. //You are going to get all data on the interface it would seem, so I narrow down to UDP with buf[9] 
  39. if (buf[9] == IPPROTO_UDP)//buf[9] is the idx for the protocol field and I only want UDP messages
  40. {
  41.     /* //UDP messages have another 8 byte header
  42.     buf[20-21]=    2byte source
  43.     buf[22-23]=    2byte dest
  44.     buf[24-25]=    2byte length
  45.     buf[26-27]=    2byte checksum
  46.     */
  47.     int sourceport=htons(buf[20]+(buf[21]<<8));
  48.     int destport=htons(buf[22]+(buf[23]<<8));
  49.     //Narrowing it down again, I only want data sent to MY port 1900 (which would be destport in the udp header) using buf[22-23]
  50.     if(destport==1900)
  51.     {
  52.         printf("FromIP: %u.%u.%u.%u:%u\n", (unsigned char) buf[12],(unsigned char) buf[13], (unsigned char) buf[14],(unsigned char) buf[15],sourceport);
  53.         printf("ToIP: %u.%u.%u.%u:%u\n",(unsigned char)buf[16],(unsigned char)buf[17],(unsigned char)buf[18],(unsigned char)buf[19],destport);
  54.         //payload data starts at buf[28]
  55.         //for me it is string data (HTTP-UDP), anyone else could be anything
  56.     }
  57. }
  58.  
Nov 5 '10 #11
Oralloy
988 Expert 512MB
Plater,

Thanks for posting your solution. I learned something!

Cheers!
Oralloy
Nov 8 '10 #12
Oralloy
988 Expert 512MB
@Plater,

It looks like you might have a bug in lines 47 and 48:
Expand|Select|Wrap|Line Numbers
  1. //--original
  2.     int sourceport=htons(buf[20]+(buf[21]<<8)); 
  3.     int destport=htons(buf[22]+(buf[23]<<8)); 
  4. //--modified
  5.     int sourceport=ntohs(*(short *)(buf + 20)); 
  6.     int destport=ntohs(*(short *)(buf + 22)); 
You probably aren't seeing anything, as the network byte order is little-endian, and your computer matches it - thus rendering the functions htons() and ntohs() as identity transforms.

Cheers!
Nov 8 '10 #13
Plater
7,872 Expert 4TB
Good catch, I stole that from somewhere else. Normally I wouldn't even use those functions at all and would hand assemble those bytes in the correct order. (Which isn't very robust)
Could you not also do:
ntohs(*(short *)(&buf[20]));
Nov 9 '10 #14
Oralloy
988 Expert 512MB
Actually, that's the code form I considered before I settled on the offset-addition form.

Either form should work just fine, at least until we run into a system where a short is something other than 16 bits, in which case we'll have to provide new networking primitives to handle byte ordering.

Good Luck!
Nov 9 '10 #15
Plater
7,872 Expert 4TB
I found the function recvmsg() that claims it would expose the interface/ip/port data, but so far i've found it to be convuluted way to get the same data as i did above. (It filled in a buffer with the same bytes as buf had, at the same indexes too)
Also, it only seemed to get any messages when i'm in RAW mode anyway.
So unless there is a better way to use it in a non-RAW socket, it is not useful.
Nov 10 '10 #16
Oralloy
988 Expert 512MB
Well recvmsg() seems to do about what you need, but if you're already cracking the raw bytes of the message - just run with what you have.
Nov 10 '10 #17
Plater
7,872 Expert 4TB
Well the points really were:
*recvmsg only worked on a raw socket.
*recvmsg through convulted means, populated a char[] with the bytes that came in
*Using either method, i still had to interpret what bytes belonged to what field.

I would say it is actually MORE difficult to use recvmsg then to just use recv
Nov 11 '10 #18

Sign in to post your reply or Sign up for a free account.

Similar topics

3
by: Fred Palmer | last post by:
I am trying to get reponses from multiple devices on my network by sending the following message via UDP: // Create the message Byte bytesSent = new Byte {0x00, 0x00, 0x00, 0xF6}; Socket s =...
3
by: Tom Opgenorth | last post by:
I'm experiencing a problem with sockets, and I'm really hoping someone can help me, please and thank you. I've written a TCP Server, which listens on a port for an incoming connection. When the...
2
by: Ronodev.Sen | last post by:
the way my program needs to go is -- 1) open a socket and listen on it 2) moment a client connects to the socket - process some data (by sending it to another machine), get the result and send...
4
by: John A Grandy | last post by:
How to determine if a request originated from a link click , or otherwise ( such as pasting the url the browser ). This would seem to work ... if (Request.Url.Host == Request.UrlReferrer.Host)...
8
by: swell | last post by:
I would like to write a server with the low level API of python ( socket+select and/or socket+thread ) that allow me to register client and update them every X seconds ( could be the time, the...
1
by: jlamanna | last post by:
Hi. I'm adding IPV6 support to my app, and I have a UDP Broadcast socket that I need to redo using IPV6. I know that IPV6 doesn't have a notion of broadcast anymore, its all multicast (broadcast...
0
by: Stodge | last post by:
I'm trying to get a simple multicast application working using Twisted; so far I have: from twisted.internet.protocol import DatagramProtocol from twisted.internet import reactor from...
1
by: Jean-Paul Calderone | last post by:
On Thu, 9 Oct 2008 06:03:44 -0700 (PDT), Stodge <stodge@gmail.comwrote: Your server and client are both listening on the multicast address 224.0.0.1. Traffic sent to that address will be...
0
by: rahulsengar | last post by:
Hey how can i lauch my application on incoming call notification in windows mobile . hey can u please help me how to launch my application automatically when an incoming call occurs. Is there any...
0
by: LTCCTL | last post by:
hi all, I have an application to send and recieve an SMS but my application is not catching the incoming message. can anyone tell what's wrong with the following code: import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.