Reputation: 33
I'm writing simple program that sends icmp echo requests. I'm using ping sockets (to be able to send without suid).
This is how i open the socket:
int fd=socket(PF_INET,SOCK_DGRAM,IPPROTO_ICMP);
And this is how i construct icmp datagram:
struct icmphdr req;
req.type=8;
req.code=0;
req.checksum=0;
req.un.echo.id=htons(12);
req.un.echo.sequence=htons(1);
I'm sending the packet with sendto() and it works well, I mean the target host receives the request, sends response and i am able to receive this response in my program.
However, I'm not sure the meaning of un.echo.id field. In many samples that are on the net this field is filled with something like rand() etc. But it is overwritten later, I can clearly see it in tcpdump.
I found such description: LWN.net net: ipv4: add IPPROTO_ICMP
Message identifiers (octets 4-5 of ICMP header) are interpreted as local ports. Addresses are stored in struct sockaddr_in. No port numbers are reserved for privileged processes, port 0 is reserved for API ("let the kernel pick a free number"). There is no notion of remote ports, remote port numbers provided by the user (e.g. in connect()) are ignored.
It's not clear to me. So please, could you tell me, if I should fill this filed or not?
UPDATE: Thanks to John's Zwinck anwer I realised that I posted wrong code example, it's correct now.
Here is whole code and tcpdump output: code and dump
It illustrates my question, in the code id is set to 12 (just a random number, tried many others) but icmp headers in dump have id set to 4.
Upvotes: 3
Views: 1689
Reputation: 2020
You should bind to the port you want to use as icmp id. Add
struct sockaddr_in sa;
sa.sin_family = PF_INET;
sa.sin_port = htons(12);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
And after socket()
if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
return -1;
This will cause the id to be what you want. You can set the req.un.echo.id
field to 0. Sample run where id is 12:
ICMP Reply, id=0xc00, sequence = 0x100
Upvotes: 2
Reputation: 249223
The id
field can be used to distinguish which program sent the messages. Therefore you could use something like your PID or another unique-in-time numeric identifier (or even a random number, so long as it's the same random number for all messages sent as one operation).
The sequence
field should be an sequential, increasing number, rather than a random number as you have now.
But in the end it seems like it's up to you, the sender, to decide how you want to use these fields. You could probably put some other meaningful data in them and get it echoed back to you if you wanted.
Upvotes: 2