Reputation: 11
My goal is to get all (UDP) messages from a single interface device. I work on Ubuntu 20.04, programming in C.
A raw socket seemed to be the best solution, the problem is the binding to the interface seems not to work. I still get what seems like ALL messages from all devices.
//Create raw socket
if ((sock_fd = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
printf ("Cannot create raw socket!\n");
return -1;
}
//Bind to interface
if ((setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, if_name, strlen(if_name)+1)) < 0) {
printf ("Failed to bind socket to interface device %s!\n", if_name);
return -1;
}
while(1){
memset (buffer, 0, BUF);
if ((n = recv(sock_fd, buffer, BUF, 0)) < 0){
printf("No data available!\n");
continue;
}
//Print data frame
for(i=0; i<n; i++) {
printf("0x%x ", buffer[i]);
}
printf("\n\n");
}
During execution, I get no errors.
Interestingly, I get no messages at all when I change htons(ETH_P_ALL)
to IPPROTO_UDP
in the socket()
command (finally, I want to end up only with UDP messages).
Did I miss something?
EDIT: To better specify my goal: i want all UDP messages on a single interface device for both IPv4 and IPv6 and with multiple src and dst IPs/Ports (so basically a sniffer for UDP messages on that interface).
Upvotes: 1
Views: 998
Reputation: 223739
If you want to see all UDP packets coming into the system, you'll want to use an AF_INET
socket, not AF_PACKET
, and you'll want to set the protocol to IPPROTO_UDP
:
if ((sock_fd = socket (AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0) {
perror("Cannot create raw socket!\n");
return -1;
}
Note that you want to use perror
instead of printf
when a socket function fails. This will tell you why the call failed.
Also note that this also only receives packets that your system is "supposed to" see, i.e. those where the destination IP is either the interface IP or a broadcast / multicast address.
Upvotes: 1