// broadcast-proxy.c // accepts a single UDP packet and broadcasts it accross every broadcast // interface it connects to. // // lol #include #include #include #include #include #include #include #define BACKLOG 10 #define RECVBUF 1024 #define LISTEN_ON 31337 #define MAX_PVID 25 void usage(); int main(int argc, char**argv) { // Pull in some options.. if(argc != 2) { usage(); return(1); } /* the following code is setting up a socket connection on * the admin interface to listen for packets to rebroadcast. * It will then spam a UDP packet with the original payload * to every single broadcast address of every VLAN. */ int sockfd, sendsock, sin_size, addr_len; struct sockaddr_in my_addr; struct sockaddr_in their_addr; // Open a socket, nothing more than a file descriptor at this point. sockfd = socket(PF_INET, SOCK_DGRAM, 0); if(!sockfd) { printf("Unable to open socket, bailing out.\n"); return(1); } // Zero out the newly created struct to avoid any potential weirdness. memset((void *)&my_addr, '\0', sizeof(struct sockaddr_in)); // initialize the struct as an INET socket type and setup the // address and port to listen on. my_addr.sin_family = AF_INET; my_addr.sin_port = htons(LISTEN_ON); my_addr.sin_addr.s_addr = inet_addr(argv[1]); printf("Debug: my_addr.sin_addr.s_addr '%d'\n", my_addr.sin_addr.s_addr); // Now bind the socket if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr)) { printf("Unable to bind to '%s:%d', bailing out.\n", argv[1], LISTEN_ON); perror("bind"); return(1); } // Listens for incoming connections listen(sockfd, BACKLOG); // now it's time to accept said connections. sin_size = sizeof their_addr; void *inbuf[RECVBUF]; // Note the careful instantiation of broadcast = 1, we // need this in setsockopt() later to enable broadcast mode. int retval, broadcast = 1; // Server listen loop, receives a message from the port via UDP while( retval = recvfrom(sockfd, inbuf, RECVBUF, 0, (struct sockaddr *) &their_addr, (socklen_t *) &addr_len) ) { if (retval <1) { printf("No data received on socket, or something got closed wtf?\n"); perror("recvfrom"); return(1); } printf("Received UDP message containing payload: '%s'\n", inbuf); // Set up sending socket to be reused for each broadcast. sendsock = socket(PF_INET, SOCK_DGRAM, 0); if(!sendsock) { printf("Unable to open socket for sending, bailing out.\n"); return(1); } // Again, initialize memory, set port number and INET type. // but save the IP setting for later. struct sockaddr_in send_addr; memset((void *)&send_addr, '\0', sizeof(struct sockaddr_in)); send_addr.sin_family = AF_INET; send_addr.sin_port = htons(LISTEN_ON); // Necessary for broadcasting. if (setsockopt(sendsock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) == -1) { perror("setsockopt (SO_BROADCAST)"); exit(1); } int i; char bcastaddr[16];// max possible length of an IPv4 address for( i=2; i < MAX_PVID; ++i) { // compose the broadcast address sprintf(bcastaddr, "10.0.%d.255", i); // Define the IP to send on send_addr.sin_addr.s_addr = inet_addr(bcastaddr); int numbytes; // Actually send the packet here. if ((numbytes=sendto(sendsock, inbuf, strlen(inbuf), 0, (struct sockaddr *)&send_addr, sizeof send_addr)) == -1) { perror("sendto"); continue; } } } // Cleanup close(sockfd); close(sendsock); return(0); } void usage() { printf("usage: broadcaster \nIn other words, f yo couch!\n"); }