#include //socket, inet_aton #include //socket, inet_aton #include //socket #include //htons, ntohs, htonl, ntohl, inet_aton #include //signal #include //fprintf #include //perror #include //strtol #include //close /*PROTOTYPES*/ void bail(int code); void sig_handler(int signum); void usage(char* name); /*DEFINES*/ //Magic Number used to distinguish our UDP Packets (First 8 Bytes of Payload) #define MAGIC 0xDEADBEEFCAFEFEED //Receive Buffer Size #define BUFFER_SIZE 1000 /*GLOBAL VARIABLES*/ long port = 0; int sock_fd = -1; struct sockaddr_in src_addr; int main(int argc, char **argv){ /*Parse Arguments*/ if (argc < 3) { fprintf(stderr, "Insufficient arguments\n"); usage(argv[0]); } //Source Address in_addr_t src_ip_addr = inet_addr(argv[1]); if (src_ip_addr == INADDR_NONE) { fprintf(stderr, "Invalid SRC IP Address\n"); usage(argv[0]); } //Port Number errno = 0; port = strtol(argv[2], NULL, 10); if (errno != 0) { fprintf(stderr, "Invalid Port Number\n"); usage(argv[0]); } /*MISC MAIN THREAD*/ //Register Signal Handling signal(SIGHUP, sig_handler); signal(SIGINT, sig_handler); signal(SIGQUIT, sig_handler); signal(SIGABRT, sig_handler); /*SOCKET OPERATIONS*/ src_addr = {AF_INET, htons(port), {src_ip_addr}}; //Open Socket sock_fd = socket(AF_INET, SOCK_DGRAM, 0); //Bind Socket if (bind(sock_fd, (const struct sockaddr*) &src_addr, sizeof(src_addr)) < 0) { perror("Bind failed"); bail(EXIT_FAILURE); } //Set Receive Timeout const struct timeval tv = {.tv_usec = 1000}; //1 ms setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); char buffer[BUFFER_SIZE]; uint64_t* p = (uint64_t*) buffer; socklen_t addrlen; struct sockaddr_in src; int n; printf("Entering Main loop\n"); while(true){ //Receive Packet n = recvfrom(sock_fd, buffer, BUFFER_SIZE, MSG_TRUNC, (struct sockaddr*) &src, &addrlen); if (n < 0){ // Error if (errno != EAGAIN && errno != EWOULDBLOCK) { perror("rcvfrom() error"); } continue; } //Packet not relevant if (src.sin_family != src_addr.sin_family && src.sin_port != src_addr.sin_port && n >= 8 && p[0] != MAGIC){ continue; } //Sent Packet Back if (sendto(sock_fd, buffer, n, 0, (const struct sockaddr*) &src, addrlen) < 0) { perror("sendto failed"); } } } void bail(int code){ //Close Sockets if (sock_fd != -1) { close(sock_fd); } //DONE exit(code); } void sig_handler(int signum){ fprintf(stderr, "Received Signal %d.\n Exiting...\n", signum); bail(EXIT_SUCCESS); } void usage(char* name){ printf("USAGE: %s SRC_ADDRESS PORT\n", name); printf("SRC_ADDRESS The local source IPv4 Address from which to send and listen to (In x.x.x.x format)\n"); printf("PORT The port number of the Addresses\n"); bail(EXIT_SUCCESS); }