/* * Receive udp packets from desired interface * * This tool is used to check that option SO_BINDTODEVICE works correctly * setsockop(SO_BINDTODEVICE) * Use together with b2d_send.c * * 1. Start b2d_recv on receiver PC * 2. Start b2d_send on sender PC * 3. Check that packets are received only from the selected interface * * usage: ./b2d_recv interface port * example: ./b2d_recv eth0 23777 */ #include #include #include #include #include #include #include #include #include #define RX_BUFF_SIZE 1024 /* create recv socket, if error occured exit(EXIT_FAILURE) */ int create_recv_sock(const char * str_interface, const char * str_port, struct sockaddr_in * sock_addr); int main(int argc, char *argv[]) { struct sockaddr_in sa_recv; if (argc != 3) { printf("usage: %s interface port\n", argv[0]); exit(EXIT_FAILURE); } int sfd_recv = create_recv_sock(argv[1], argv[2], &sa_recv); char rx_buff[RX_BUFF_SIZE] = {0}; struct sockaddr_in src_addr; socklen_t addr_len; memset(&src_addr, 0, sizeof(struct sockaddr_in)); while (1) { ssize_t res = recvfrom(sfd_recv, rx_buff, RX_BUFF_SIZE - 1, 0, (struct sockaddr *)&src_addr, &addr_len); if (res < 0) { perror("recvfrom"); exit(EXIT_FAILURE); } char buf[256]; const char * x = inet_ntop(src_addr.sin_family, &src_addr.sin_addr, buf, addr_len); if (x == NULL) { perror("inet_ntop"); exit(EXIT_FAILURE); } printf("recv %ld bytes from %s:%u: \"%s\"\n", res, buf, ntohs(src_addr.sin_port), rx_buff); } exit(EXIT_SUCCESS); } int create_recv_sock(const char * str_interface, const char * str_port, struct sockaddr_in * sock_addr) { int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket"); exit(EXIT_FAILURE); } memset(sock_addr, 0, sizeof(struct sockaddr_in)); sock_addr->sin_family = AF_INET; sock_addr->sin_addr.s_addr = htonl(INADDR_ANY); sock_addr->sin_port = htons((uint16_t)atoi(str_port)); int res = bind(sockfd, (struct sockaddr*)sock_addr, sizeof(struct sockaddr_in)); if (res < 0) { perror("bind"); exit(EXIT_FAILURE); } if (strlen(str_interface) == 0) { puts("Data will be received from all interfaces"); } else { res = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, str_interface, strlen(str_interface) + 1); if (res < 0) { perror("setsockopt"); exit(EXIT_FAILURE); } else { printf("success bind to device \"%s\"\n", str_interface); } } printf("recv port %s\n", str_port); return sockfd; }/* create_recv_socket() */