#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BUFLEN 1024 #define UBNT_PORT 10001 #define SNDLEN 4 struct 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)); struct cache_entry { unsigned long s_addr; unsigned short s_port; }; #define MAXENTRIES 1024 struct cache_entry cache[MAXENTRIES]; size_t cachep; int add_cache(unsigned long s_addr, unsigned short s_port) { if (cachep == 1024) return 0; cache[cachep].s_addr = s_addr; cache[cachep].s_port = s_port; cachep++; return 1; } int lookup_cache(unsigned long s_addr, unsigned short s_port) { int i; for (i = 0; i <= cachep; i++) if (cache[i].s_addr == s_addr && cache[i].s_port == s_port) return 1; return 0; } 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; memset(&hints, 0, sizeof(hints)); hints.ai_protocol = IPPROTO_UDP; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_CANONNAME; hints.ai_family = PF_UNSPEC; 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++; if (!lookup_cache(si_srv.sin_addr.s_addr, si_srv.sin_port)) { if (!add_cache(si_srv.sin_addr.s_addr, si_srv.sin_port)) { fprintf(stderr, "too many unique responses\n"); exit(1); } } else { continue; } 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; case 16: printf("System ID: 0x%02hhX%02hhX\n", p[0], p[1]); 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; } WebSVN - discover - Blame - Rev 5 - /trunk/discover.c
  jablonka.czprosek.czf

discover

Subversion Repositories:
[/] [trunk/] [discover.c] - Blame information for rev 5

 

Line No. Rev Author Line

Powered by WebSVN 2.2.1