![]() ![]() |
discover |
Subversion Repositories: |
Compare with Previous - Blame - Download
#include <arpa/inet.h>#include <netinet/in.h>#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <netdb.h>#include <sys/select.h>#include <sys/time.h>#include <ifaddrs.h>#include <net/if.h>#define BUFLEN 1024#define UBNT_PORT 10001#define SNDLEN 4struct udisc_msg_hdr {uint8_t vh;uint8_t vl;uint16_t length;} __attribute__((packed));struct udisc_rec_hdr {uint8_t type;uint16_t length;} __attribute__((packed));int main(int argc, char *argv[]){struct sockaddr_in si_srv;struct sockaddr_in si_clnt;int sock;socklen_t soutlen = sizeof(si_srv);socklen_t sinlen = sizeof(si_srv);char rcvbuf[BUFLEN];char sendbuf[BUFLEN];ssize_t rlen;struct udisc_msg_hdr *umh;struct udisc_rec_hdr *urh;char *p;char *dest;struct addrinfo hints;struct addrinfo *ai_res;int result;int i, t;fd_set socks;struct timeval tv;int multicast;int responses = 0;struct ifaddrs *ifa;hints.ai_protocol = IPPROTO_UDP;hints.ai_socktype = SOCK_DGRAM;hints.ai_flags = AI_CANONNAME;hints.ai_family = PF_UNSPEC;hints.ai_addrlen = 0;hints.ai_addr = 0;hints.ai_canonname = 0;if (argc < 2) {dest = "233.89.188.1";multicast = 1;} else {dest = argv[1];multicast = 0;}if ((result = getaddrinfo(dest, NULL, &hints, &ai_res))) {printf("getaddrinfo-failed: %s\n", gai_strerror(result));exit(1);}if ((sock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {perror("socket");exit(1);}memset((char *) &si_clnt, 0, sizeof(si_clnt));si_clnt.sin_family = AF_INET;si_clnt.sin_port = htons(UBNT_PORT);si_clnt.sin_addr = ((struct sockaddr_in *)ai_res->ai_addr)->sin_addr;sendbuf[0] = 1;sendbuf[1] = 0;sendbuf[2] = 0;sendbuf[3] = 0;if (multicast) {char loop = 0;setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(char));if (getifaddrs(&ifa)) {perror("getifaddrs");exit(1);}for (; ifa; ifa = ifa->ifa_next) {if (!(ifa->ifa_flags & IFF_UP))continue;if (!ifa->ifa_addr)continue;if (ifa->ifa_addr->sa_family != AF_INET)continue;if (!strcmp(ifa->ifa_name, "lo"))continue;if (!strncmp(ifa->ifa_name, "dummy", 5))continue;printf("Probing %s:%d", inet_ntoa(si_clnt.sin_addr), UBNT_PORT);printf(" via %s (%s).\n", ifa->ifa_name, inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr));if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr), sizeof(struct in_addr))) {perror("setsockopt");exit(1);}if (sendto(sock, sendbuf, SNDLEN, 0, (struct sockaddr *)&si_clnt, soutlen) == -1) {perror("socket");exit(1);}}} else {printf("Probing %s:%d.\n", inet_ntoa(si_clnt.sin_addr), UBNT_PORT);if (sendto(sock, sendbuf, SNDLEN, 0, (struct sockaddr *)&si_clnt, soutlen) == -1) {perror("socket");exit(1);}}FD_ZERO(&socks);FD_SET(sock, &socks);tv.tv_sec = 0;tv.tv_usec = 200000;while (select(sock + 1, &socks, NULL, NULL, &tv)) {if ((rlen = recvfrom(sock, rcvbuf, BUFLEN, 0, (struct sockaddr *)&si_srv, &sinlen)) == -1) {perror("recvfrom");exit(1);}if (ntohs(si_srv.sin_port) != UBNT_PORT)continue;responses++;printf("\n");printf("Response : %s:%d\n", inet_ntoa(si_srv.sin_addr), ntohs(si_srv.sin_port));p = rcvbuf;umh = (void*)p;p += sizeof(struct udisc_msg_hdr);rlen -= sizeof(struct udisc_msg_hdr);printf("Discovery: v%d.%02d\n", umh->vh, umh->vl);if (umh->vh != 1 && umh->vl != 0 && ntohs(umh->length) != rlen) {fprintf(stderr, "protocol invalid\n");exit(1);}while (rlen > 0) {urh = (void*)p;p += sizeof(struct udisc_rec_hdr);rlen -= sizeof(struct udisc_rec_hdr);switch (urh->type) {case 2:printf("IP Address: ");for (i = 0; i < 4; i++) {printf("%d", (unsigned char) p[i + 6]);if (i < 3)printf(".");}printf(" (");for (i = 0; i < 6; i++) {printf("%02x", (unsigned char) p[i]);if (i < 5)printf(":");}printf(")\n");break;case 1:printf("MAC Address: ");for (i = 0; i < 6; i++) {printf("%02x", (unsigned char) p[i]);if (i < 5)printf(":");}printf("\n");break;case 3:case 11:case 12:case 13:switch(urh->type) {case 3:printf("FW Version: ");break;case 11:printf("Hostname: ");break;case 12:printf("Model: ");break;case 13:printf("ESSID: ");break;}for (i = 0; i < ntohs(urh->length); i++)printf("%c", isprint(p[i]) ? p[i] : '.');printf("\n");break;case 14:printf("Mode: %s (%d)\n", *p == 2 ? "Station" : (*p == 3 ? "AP" : "?"), *p);break;case 10:t = ntohl(*(uint32_t *)p);printf("Uptime: %dd, %d:%02d:%02d\n", t / 60 / 60 / 24, t / 60 / 60 % 24, t / 60 % 60, t % 60);break;default:printf("Entry %3d: ", urh->type);for (i = 0; i < ntohs(urh->length); i++)printf("%02x ", (unsigned char) p[i]);printf(" >");for (i = 0; i < ntohs(urh->length); i++)printf("%c", isprint(p[i]) ? p[i] : '.');printf("<\n");}p += ntohs(urh->length);rlen -= ntohs(urh->length);}}close(sock);if (!responses) {printf("No UBNT routers found.\n");return 1;}printf("\n");return 0;}