My server will receive UDP multicast packets at a certain period during workday. I wrote a c socket application to receive these UDP multicast packets. As my server can only receive packets at a certain period, for testing, I captured the packets with tcpdump.
tcpdump -i enp0s25 -s 1600 -w /home/user/log/capture.pcap
and then, I replay the captured packets with tcpreplay.
tcpreplay -i p1p2 --pktlen /home/user/log/capture.pcap
this is the 'ifconfig' output.
enp0s25: flags=4163<UP,BROADCAST,RUNNING,MULTICAST mtu 1500
inet 192.168.3.6 netmask 255.255.255.0 broadcast 192.168.3.255
inet6 2400:2410:2a41:2e00:1d6f:2fde:2436:608f prefixlen 64 scopeid 0x0<global
inet6 fe80::555d:f7f2:a114:51df prefixlen 64 scopeid 0x20<link
ether 98:90:96:a7:6f:f3 txqueuelen 1000 (Ethernet)
RX packets 45031 bytes 50053845 (47.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 14129 bytes 1784865 (1.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 20 memory 0xf9100000-f9120000
lo: flags=73<UP,LOOPBACK,RUNNING mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host
loop txqueuelen 1 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
p1p1: flags=4099<UP,BROADCAST,MULTICAST mtu 1500
ether 00:02:c9:5a:77:62 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 218 dropped 207 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
p1p2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST mtu 1500
inet6 fe80::2acf:23a9:3c1a:89a0 prefixlen 64 scopeid 0x20<link
ether 00:02:c9:5a:77:63 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 329583 bytes 50655424 (48.3 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
p4p1: flags=4099<UP,BROADCAST,MULTICAST mtu 1500
ether 00:0f:53:29:e9:30 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 26
p4p2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST mtu 1500
ether 00:0f:53:29:e9:31 txqueuelen 1000 (Ethernet)
RX packets 329583 bytes 51973756 (49.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 35
three NICs was installed in my server. two of them are Fibre Channel NIC. and each of them has two ports. p1p1 and p1p2 are the same physical NIC, p4p1 and p4p2 are the same physical NIC. I connect fiber cable from p1p2 to p4p2, so tcpreplay should send packets from p1p2 to p4p2.
then, I checked whether there's packets comming into p4p2.
tcpdump -i p4p2 -nnn
part of the output:
18:05:21.062023 IP 10.10.31.31.3131 > 239.239.31.31.3131: UDP, length 97
18:05:21.062035 IP 10.10.31.31.3131 > 239.239.31.31.3131: UDP, length 97
it seems that tcpreplay do resend the captured packets to p4p2. but the problem is my sock application cannot receive these packets. following are part of my C socket application.
#pragma pack(1)
#include <stdio.h>
#include <string.h>
#include <float.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MAXBUFSIZE 65536 // Max UDP Packet size is 64 Kbyte
int main() {
int sock, status, socklen;
uint8_t buffer[MAXBUFSIZE];
struct sockaddr_in saddr;
struct ip_mreq imreq;
memset(&saddr, 0x00, sizeof(saddr));
memset(&imreq, 0x00, sizeof(imreq));
memset(buffer, 0x00, MAXBUFSIZE);
// open a UDP socket
sock = socket(PF_INET, SOCK_DGRAM, 0);
if ( sock < 0 ) {
perror("Error creating socket");
return(0);
}
imreq.imr_multiaddr.s_addr = inet_addr("239.239.31.31");
imreq.imr_interface.s_addr = htonl(INADDR_ANY); // use DEFAULT interface
// JOIN multicast group on default interface
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&imreq, sizeof(struct ip_mreq));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(3131);
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
status = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
if ( status < 0 ) {
perror("Error binding socket to interface");
return(0);
}
socklen = sizeof(struct sockaddr_in);
// receive 500 packets from socket
int m = 0;
for (; m < 500; m++) {
status = recvfrom(sock, buffer, MAXBUFSIZE, 0, (struct sockaddr *)&saddr, &socklen);
if(status < 0) {
perror("receive error!\n");
} else if (status > 0) {
// DO sth usefully here.
}
}
// shutdown socket
shutdown(sock, 2);
// close socket
close(sock);
return 0;
}
when I run the application above, it will stop at recvfrom function. Can anyone tell me why my application cannot receive these packets?
saddr.sin_family
is an address family, and should beAF_INET
. ThePF
inPF_INET
stands for protocol family. FortunatelyAF_INET
andPF_INET
both expands to the same value. – Some programmer dudeif (status 0)
? – Some programmer duderecvfrom
call succeeds then it will return a value larger than zero. It will be the size of the packet you received. – Some programmer dude