I am learning about the ping implementation in C.
The problem is, I was using a raw sockets to receive the packet. For all packets we have a identification value in ICMP header.
I was running the ping in multiple terminal.
For example, I was running three ping google.com in three terminals.
For the first ping the identification value is 23456, the second ping identification value is 34564, and the third ping identification value is 98763.
My problem is the second ping have to receives the identification with 34564 packet, but it receives the identification value as 23456.
For each ping the new raw socket is creating. But it receives another ping packet.
Can anyone please explain me, why it receives another ping packet ?
UPDATE:-
I have another one doubt. The doubt is,
raw sockets reads the packet from where and how it identify the packet is for this raw socket ?
UPDATE 1:-
Here is the link for the codes.
ping_common.c
ping.c
ping.h
What's you are seeing is by design of the raw socket, because raw sockets are meant to receive all the raw packets. So to only receive the reply to certain ICMP packets, you need to apply filters on the socket. First you can use ICMP_FILTER socket options to restrict receiving of certain ICMP types:
struct icmp_filter filter;
filter.data = <bit mask of ICMP types, like ICMP_REPLY>;
setsockopt(sock, SOL_RAW, ICMP_FILTER, &filter, sizeof filter)
Second, you can attach socket filter to enforce only receive the package with the given ICMP ID:
struct sock_fprog filter;
// set filter to check ID with your own ID
setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof filter);
To answer your other doubt:
raw sockets reads the packet from where and how it identify the packet is for this raw socket ?
Raw socket sit along side other protocol handlers after IP layer. From book "Understanding Linux Network Internals" Chapter 25.5:
Here are some examples of interactions between protocols:
IP protocol
The ip_local_deliver_finish routine, described in Chapter 24, delivers
ingress ICMP messages to the receive routine icmp_rcv registered by
the ICMP protocol, but it also delivers them to the raw IP sockets
that registered against the ICMP protocol (raw_v4_input).
Related
We want to receive packets from udp sockets, the udp packets have variable length and we don't know how long they really are until we receive them (parts of them exactly, length were written in the sixth byte).
We tried the function lrs_set_receive_option with MarkerEnd only to find it has no help on this issue. The reason why we want to receive by packets is that we need to respond some packet by sending back user-defined udp packets.
Is there anybody knows how achieve that?
UPDATE
The LR version seems to be v10 or v11.
We need respond an incoming udp packet by sending back a udp packet immediately.
The udp packet may be like this
| orc code | packet length | Real DATA |
Issue is we can't let loadrunner return data for each packets, sometimes it returns many packets in a buffer, sometimes it waits until timeout though when there has been an incoming packet in the socket buffer. While in the c programming language world, when calling recvfrom(udp socket) we are returned only one udp packet per time (per call) which is want we really want.
If you need raw socket support to intercept at the packet level then you are likely going to have to jump to a DLL virtual user in Visual Studio with the raw socket support.
As to your question on UDP support: Yes, a Winsock user supports both core transport types, UDP and TCP. TCP being the more common variant as connection oriented. However, packet examination is at layer 3 of the OSI model for the carrier protocol IP. The ACK should come before you receive the dataflow for your use in the script. You are looking at assembled data flows in the data.ws when you jump to the TCP and UDP level.
Now, you are likely receiving a warning on receive buffer size mismatch which is taking you down this path with a mismatch to the recording size. There is an easy way to address this. If you take your send buffer and construct it using the lrs_set_send_buffer() function, then anything that returns will be taken as correct, ignoring the previously recorded buffer size and not having to wait for a match or timeout before continuing.
I'm trying to send commands using UDP. The receiver is supposed to receive the UDP datagram and reply. However, I would like the reply to always be sent to the sender's source port. I know how to parse the the port (struct header and move the pointer to the right position...), however, I'm looking for a function that returns the whole received frame including the headers and not only the datagram/data.
What about the recvfrom() function? It allows you to grab the data and it fills a sockaddr struct from which you can find the source port of the sender.
I was writing a multithreaded ping program. I created rawsockets on each thread (for each IP) and sent ICMP Echo Request to each using sendto() and then I did recvfrom() in each thread. I am getting messages from IPs in various sockets(like if I had used socket S1 for sendto for IP1, I get echo-replies from IP1 to S1, S2 etc). Do I need to do a bind?
Also another problem is that even though I send only 1 ICMP request I get back many echo replies from target. Is there any way I can limit this? This is causing me to miss some of the other ICMP packets. Is there a way for my program to ask the target to stop sending ICMP echo's?
Thanks,
Raw sockets pick up all incoming packets; you will need to do your own filtering, or - better yet - only open one raw socket, and detect all of the incoming echo replies on a single thread.
Your duplicate packets may be because of the multiple raw sockets - you'll get one copy of each incoming packet per socket. Also note that in some cases internet packets can be duplicated (this is rare, however).
I'm trying to build an RTP packet metric analyzer in C, but i ended up in a strange issue, I'm cutting down implementation details for ease of exposure:
Since the RTP packets are contained in UDP my socket is initalized with the following parameters:
sock_domain = AF_INET;
sock_type = SOCK_DGRAM;
sock_proto = IPPROTO_UDP;
and binded with those parameters:
socket_addr.sin_family = AF_INET;
socket_addr.sin_port = 10000; // My server is streaming on 10000
socket_addr.sin_addr.s_addr = INADDR_ANY;
and joined the multicast group:
mgroup_req.imr_multiaddr.s_addr = inet_addr("224.1.0.1"); // Multicast group of the stream
mgroup_req.imr_interface.s_addr = INADDR_ANY;
set the multicast group from which i receive to:
mgroup_addr.sin_family = socket_addr.sin_family;
mgroup_addr.sin_port = socket_addr.sin_port;
mgroup_addr.sin_addr.s_addr = mgroup_req.imr_multiaddr.s_addr;
receiving packets with recvfrom function:
errcode = recvfrom(sockfd, &recvbuff, IPMAXSIZE, 0, (struct sockaddr *)&mgroup_addr, &mgroup_addr_len)
Something goes wrong, while i can receive standard UDP packets addressed to the multicast group 224.1.0.1, the RTP packets are not received the first time, but sending them again makes the trick.
Scenario 1:
I send n UDP packets: They are correctly received
Scenario 2:
I send n RTP packets: Nothing happens
I send again the same n RTP packets: They are correctly received
whatever the n number of packets is... so weird but true.
edit:
At the analyzer side I'm running a sniffer and it shows both the packet bursts, so messages arrives at the analyzer side, it's not a sender related problem.
Question:
the code is exactly the same (read: Same executable) for the RTP scenario AND the UDP scenario.
What am I doing wrong?
Side notes:
RTP manage libraries or high-level RTP libraries suggestions are a no-no, I MUST work at this level of abstraction because of the metrics i need to analyze.
Also Network metrics analyzer are a no-no, I MUST do this with my own code.
Thanks in advance.
I'm not convinced that you need to name the mcast group address again as the recvfrom address, as you've already joined the group. Is receiving packets from elsewhere a genuine concern? I would just use recv().
The issue was due to the board i was working on, it was set (not my code) for redirecting RTP packets directly to the MPEG decoder.
Turns out that packets in the decoder are not to be forwarded to the Kernel. Still has to understand why the double send was working.
When receiving on an ICMP socket, (SOCK_RAW with IPPROTO_ICMP), since
there is no concept of "port" in the ICMP protocol, how can an
application determine that a received packet is not part of some other
TCP/UDP/whatever socket transmission that is also happening at the
same time?
For example, suppose you have an application with 2 threads. Thread 1
sets up a TCP server socket, and continuously receives data from a
connected client. Thread 2 continuously sends echo request packets
(ping) to the same client using an ICMP socket, and then receives echo
replys. What is to prevent Thread 2 from receiving one of the TCP
packets instead?
ICMP is a different protocol from TCP and UDP, as determined by the protocol field in the IP header. When you open a socket with IPPROTO_ICMP, you're telling the socket to transmit and receive only packets with IP headers whose protocol field is set to ICMP.
Similarly, sockets opened with IPPROTO_TCP or IPPROTO_UDP respond only to packets whose IP headers contain a protocol field that is set to TCP or UDP, respectively.
You can check the ICMP header for the type and see if its ICMP Echo Response (Type 0). Also in ICMP, the response will contain the request you had sent in the first place.
Received UDP & TCP packets never passed to raw sockets . IF a process wants to read IP datagram containing UDP or TCP packets the packets must be read at data link layer . check this link
http://aschauf.landshut.org/fh/linux/udp_vs_raw/ch01s03.html
if the packet is not cached at layer 2 then it is processed by kernel .
And if the packet is of icmp protocol and it is of type echo request or timestamp request or address mask request then it is entirely processed by kernel otherwise it will passed to RAW SOCKETS.
Another one all datagrams with a protocol field that the kernel does not understand are passed to raw sockets only basic processing of ip is done on them
At last if datagram arrives in fragments then nothing is passed to raw sockets until all fragments are arived and reassembled .
If you want to learn more, then read this book.