История изменений
Исправление Tumyq, (текущая версия) :
Пробовал сделать bind на INADDR_ANY, в таком случае принимаются только те пакеты, которые я собственно сам отправил. Те, что из другой - не приходят, но их все так же видит WireShark. Судя по man, INADDR_ANY это бродкаст подсети, то бишь той, в которой я. Так же, пробовал делать это с INADDR_BROADCAST, результат тот же. Вариант с INADDR_ANY ниже:
int sockfd;
char buf[30];
struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;
int numbytes;
socklen_t addr_len;
int broadcast=1;
if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("socket");
exit(1);
}
if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
&broadcast, sizeof broadcast)) == -1) {
perror("setsockopt - SO_SOCKET ");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
"enp4s0", strlen("enp4s0")) == -1) {
perror("setsockopt (SO_BINDTODEVICE)");
exit(1);
}
printf("Socket created\n");
memset(&sendaddr, 0, sizeof sendaddr);
sendaddr.sin_family = AF_INET;
sendaddr.sin_port = htons(PORT);
sendaddr.sin_addr.s_addr = INADDR_BROADCAST;
memset(&recvaddr, 0, sizeof recvaddr);
recvaddr.sin_family = AF_INET;
recvaddr.sin_port = htons(PORT);
recvaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*)&recvaddr, sizeof recvaddr) == -1) {
perror("bind");
exit(1);
}
numbytes = sendto(sockfd, "Hello", 5 , 0,
(struct sockaddr *)&sendaddr, sizeof sendaddr);
if (numbytes < 0)
{
perror("sendto");
//exit(1);
}
else
{
printf("sent %d bytes to %s\n", numbytes,
inet_ntoa(sendaddr.sin_addr));
}
for (;;) {
int n;
fd_set set;
struct timeval time_500ms = { 0, 500*1000 };
FD_ZERO(&set);
FD_SET(sockfd, &set);
n = select(sockfd+1, &set, NULL, NULL, &time_500ms);
if (n < 0) {
perror("select");
break;
}
else if (n == 0) {
printf("sleep(5)\n");
sleep(5);
}
else if (!FD_ISSET(sockfd, &set)) {
perror("FD_ISSET");
break;
}
else {
addr_len = sizeof recvaddr;
if ((numbytes = recvfrom(sockfd, buf, sizeof buf, 0,
(struct sockaddr *)&recvaddr, &addr_len)) > 0)
{
time_t now = time(NULL);
printf("recvfrom: '%.*s' at %s\n", numbytes, buf, ctime(&now));
}
else
perror("recvfrom");
}
}
close(sockfd);
}
«дропать по RFC» Имеется в виду DHCP(RFC 2131)?
Исправление Tumyq, :
Пробовал сделать bind на INADDR_ANY, в таком случае принимаются только те пакеты, которые я собственно сам отправил. Те, что из другой - не приходят, но их все так же видит WireShark. Судя по man, INADDR_ANY это бродкаст подсети, то бишь той, в которой я. Так же, пробовал делать это с INADDR_BROADCAST, результат тот же. Вариант с INADDR_ANY ниже:
int sockfd;
char buf[30];
struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;
int numbytes;
socklen_t addr_len;
int broadcast=1;
if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("socket");
exit(1);
}
if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
&broadcast, sizeof broadcast)) == -1) {
perror("setsockopt - SO_SOCKET ");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
"enp4s0", strlen("enp4s0")) == -1) {
perror("setsockopt (SO_BINDTODEVICE)");
exit(1);
}
printf("Socket created\n");
memset(&sendaddr, 0, sizeof sendaddr);
sendaddr.sin_family = AF_INET;
sendaddr.sin_port = htons(PORT);
sendaddr.sin_addr.s_addr = INADDR_BROADCAST;
memset(&recvaddr, 0, sizeof recvaddr);
recvaddr.sin_family = AF_INET;
recvaddr.sin_port = htons(PORT);
recvaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*)&recvaddr, sizeof recvaddr) == -1) {
perror("bind");
exit(1);
}
numbytes = sendto(sockfd, "Hello", 5 , 0,
(struct sockaddr *)&sendaddr, sizeof sendaddr);
if (numbytes < 0)
{
perror("sendto");
//exit(1);
}
else
{
printf("sent %d bytes to %s\n", numbytes,
inet_ntoa(sendaddr.sin_addr));
}
for (;;) {
int n;
fd_set set;
struct timeval time_500ms = { 0, 500*1000 };
FD_ZERO(&set);
FD_SET(sockfd, &set);
n = select(sockfd+1, &set, NULL, NULL, &time_500ms);
if (n < 0) {
perror("select");
break;
}
else if (n == 0) {
printf("sleep(5)\n");
sleep(5);
}
else if (!FD_ISSET(sockfd, &set)) {
perror("FD_ISSET");
break;
}
else {
addr_len = sizeof recvaddr;
if ((numbytes = recvfrom(sockfd, buf, sizeof buf, 0,
(struct sockaddr *)&recvaddr, &addr_len)) > 0)
{
time_t now = time(NULL);
printf("recvfrom: '%.*s' at %s\n", numbytes, buf, ctime(&now));
}
else
perror("recvfrom");
}
}
close(sockfd);
}
Исходная версия Tumyq, :
Я пробовал сделать bind на INADDR_ANY, в таком случае принимаются только те пакеты, которые я собственно сам отправил. Те, что из другой - не приходят - их все так же видит WireShark. Я так понял, что INADDR_ANY это бродкаст подсети, то бишь той, в которой я. Так же, пробовал делать это с INADDR_BROADCAST, результат тот же. Вариант с INADDR_ANY ниже:
int sockfd;
char buf[30];
struct sockaddr_in sendaddr;
struct sockaddr_in recvaddr;
int numbytes;
socklen_t addr_len;
int broadcast=1;
if ((sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("socket");
exit(1);
}
if ((setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
&broadcast, sizeof broadcast)) == -1) {
perror("setsockopt - SO_SOCKET ");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
"enp4s0", strlen("enp4s0")) == -1) {
perror("setsockopt (SO_BINDTODEVICE)");
exit(1);
}
printf("Socket created\n");
memset(&sendaddr, 0, sizeof sendaddr);
sendaddr.sin_family = AF_INET;
sendaddr.sin_port = htons(PORT);
sendaddr.sin_addr.s_addr = INADDR_BROADCAST;
memset(&recvaddr, 0, sizeof recvaddr);
recvaddr.sin_family = AF_INET;
recvaddr.sin_port = htons(PORT);
recvaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*)&recvaddr, sizeof recvaddr) == -1) {
perror("bind");
exit(1);
}
numbytes = sendto(sockfd, "Hello", 5 , 0,
(struct sockaddr *)&sendaddr, sizeof sendaddr);
if (numbytes < 0)
{
perror("sendto");
//exit(1);
}
else
{
printf("sent %d bytes to %s\n", numbytes,
inet_ntoa(sendaddr.sin_addr));
}
for (;;) {
int n;
fd_set set;
struct timeval time_500ms = { 0, 500*1000 };
FD_ZERO(&set);
FD_SET(sockfd, &set);
n = select(sockfd+1, &set, NULL, NULL, &time_500ms);
if (n < 0) {
perror("select");
break;
}
else if (n == 0) {
printf("sleep(5)\n");
sleep(5);
}
else if (!FD_ISSET(sockfd, &set)) {
perror("FD_ISSET");
break;
}
else {
addr_len = sizeof recvaddr;
if ((numbytes = recvfrom(sockfd, buf, sizeof buf, 0,
(struct sockaddr *)&recvaddr, &addr_len)) > 0)
{
time_t now = time(NULL);
printf("recvfrom: '%.*s' at %s\n", numbytes, buf, ctime(&now));
}
else
perror("recvfrom");
}
}
close(sockfd);
}