/* * routine for adding elements in the existing hostlist * linked list. */ host* host_add(host *hst, char *name, char *user) { if (!hst) return(host_new(name, user)); hst->next = host_add(hst->next, name, user); return(hst->next); }
/* * routine for adding elements in the existing hostlist * linked list. */ static struct host* host_add(struct host *hst, char *user, char *host, uint16_t port) { if (hst == NULL) return(host_new(user, host, port)); hst->next = host_add(hst->next, user, host, port); return(hst->next); }
static int subnet_add(in_addr_t addr, int prefix_length, uint8_t flags) { uint32_t mask = ~((1<<(32-prefix_length))-1); uint32_t net = (ntohl((uint32_t)addr)) & mask; uint32_t brd = (ntohl((uint32_t)addr)) | ~mask; uint32_t a; for (a = net+1; a<brd; a++) { in_addr_t ia = (in_addr_t) htonl(a); host_add(ia, HOST_SUBNET|flags); } }
void host_load(void) { FILE *f; int ip; char name[80]; char *p = name; if (!(f = fopen("nethost.cache", "r"))) return; if (hostcache_list) host_free(); while (fscanf(f, "%x %s\n", &ip, p) == 2) host_add(ip, name); fclose(f); }
static GSList *host_cache_read_list (FILE *f) { GSList *hosts = NULL; char buf[1024]; char *token[4]; int n; struct host *h; time_t refreshed; char *endptr; while (fgets (buf, 1024, f)) { n = tokenize (buf, token, 4, " \t\n\r"); if (n == 3) { refreshed = strtoul (token[0], &endptr, 10); if (endptr == token[0]) /* It's not a number */ continue; h = host_add (token[1]); if (h) { if (h->name) g_free (h->name); h->name = g_strdup (token[2]); h->refreshed = refreshed; // hosts = host_list_add (hosts, h); hosts = g_slist_prepend (hosts, h); host_ref(h); } } } hosts = slist_sort_remove_dups(hosts,(GCompareFunc)host_sorting_helper,(void(*)(void*))host_unref); return hosts; }
int main(int argc, char *argv[]) { extern char *optarg; extern int optind; char pcap_ebuf[PCAP_ERRBUF_SIZE]; char libnet_ebuf[LIBNET_ERRBUF_SIZE]; int c; int n_scan_hosts = 0; char *scan_prefix = NULL; int scan_prefix_length = 32; char *cleanup_src = NULL; in_addr_t target_addr; intf = NULL; poison_reverse = 0; poison_mesh = 0; n_hosts = 0; /* allocate enough memory for target list */ hosts = calloc( argc+1, sizeof(struct host) ); while ((c = getopt(argc, argv, "vrmi:s:t:c:h?V")) != -1) { switch (c) { case 'v': verbose = 1; break; case 'i': intf = optarg; break; case 't': target_addr = libnet_name2addr4(l, optarg, LIBNET_RESOLVE); if (target_addr == -1) { usage(); } else { host_add(target_addr, HOST_TARGET); } break; case 'r': poison_reverse = 1; break; case 'm': poison_mesh = 1; break; case 's': scan_prefix = strchr(optarg, '/'); if (scan_prefix) { *scan_prefix = '\0'; scan_prefix_length = atoi(scan_prefix+1); if (scan_prefix_length < 0 || scan_prefix_length > 32) { usage(); } } n_scan_hosts += (1<<(32-scan_prefix_length)); /* we need some more memory to store the target data */ int mem = (argc+1 + n_scan_hosts) * sizeof(struct host); hosts = realloc( hosts, mem ); hosts[n_hosts].ip = (uint32_t)0; subnet_add(inet_addr(optarg), scan_prefix_length, HOST_TARGET); break; case 'c': cleanup_src = optarg; break; default: usage(); } } argc -= optind; argv += optind; if (!cleanup_src || strcmp(cleanup_src, "own")==0) { /* default! */ /* only use our own hw address when cleaning up, * not jeopardizing any bridges on the way to our * target */ cleanup_src_own = 1; cleanup_src_host = 0; } else if (strcmp(cleanup_src, "host")==0) { /* only use the target hw address when cleaning up; * this can screw up some bridges and scramble access * for our own host, however it resets the arp table * more reliably */ cleanup_src_own = 0; cleanup_src_host = 1; } else if (strcmp(cleanup_src, "both")==0) { cleanup_src_own = 1; cleanup_src_host = 1; } else { errx(1, "Invalid parameter to -c: use 'own' (default), 'host' or 'both'."); usage(); } while (argc--) { if ((target_addr = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) { errx(1, "Invalid address: %s", argv[0]); usage(); } host_add(target_addr, HOST_MODEL); argv++; } if (poison_mesh) { struct host *host = hosts; for(;host->ip; host++) { host->flags |= (HOST_TARGET|HOST_MODEL); } } if (poison_reverse && active_targets() <= 0) { errx(1, "Spoofing the reverse path (-r) is only available when specifying at least one target (-t/-s)."); usage(); } if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL) errx(1, "%s", pcap_ebuf); if ((l = libnet_init(LIBNET_LINK, intf, libnet_ebuf)) == NULL) errx(1, "%s", libnet_ebuf); fprintf(stderr, "Scanning %d hw addresses...\n", n_hosts); struct host *target = hosts; for (; target->ip; target++) { if (verbose) { fprintf(stderr, "Looking up host %s...\n", libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE)); } int arp_status = arp_find(target->ip, &target->mac); if (arp_status && /* just make sure we are not getting an empty or broadcast address */ (memcmp(&target->mac, zero_ha, sizeof(struct ether_addr)) != 0) && (memcmp(&target->mac, brd_ha, sizeof(struct ether_addr)) != 0)) { target->flags |= HOST_ACTIVE; if (target->flags & HOST_SUBNET) { fprintf(stderr, "Found host in subnet %s: %s\n", libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE), ether_ntoa((struct ether_addr *)&target->mac)); } } else { target->flags &= (~HOST_ACTIVE); if (! (target->flags & HOST_SUBNET)) { fprintf(stderr, "Unable to find specified host %s\n", libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE)); } if (poison_reverse && target->flags & HOST_MODEL) { errx(1, "couldn't arp for spoof host %s", libnet_addr2name4(target->ip, LIBNET_DONT_RESOLVE)); usage(); } } } if ((my_ha = (u_int8_t *)libnet_get_hwaddr(l)) == NULL) { errx(1, "Unable to determine own mac address"); } if (active_targets() == 0) { errx(1, "No target hosts found."); } signal(SIGHUP, cleanup); signal(SIGINT, cleanup); signal(SIGTERM, cleanup); fprintf(stderr, "Starting spoofing process...\n"); for (;;) { struct host *target = hosts; for(;target->ip; target++) { if (!(target->flags & HOST_TARGET)) continue; if (!(target->flags & HOST_ACTIVE)) continue; struct host *model = hosts; for (;model->ip; model++) { if (!(model->flags & HOST_ACTIVE)) continue; if (!(model->flags & HOST_MODEL)) continue; if (target->ip != model->ip) { arp_send(l, ARPOP_REPLY, my_ha, model->ip, (target->ip ? (u_int8_t *)&target->mac : brd_ha), target->ip, my_ha); usleep(ARP_PAUSE); if (poison_reverse) { arp_send(l, ARPOP_REPLY, my_ha, target->ip, (uint8_t *)&model->mac, model->ip, my_ha); usleep(ARP_PAUSE); } } } } sleep(2); } /* NOTREACHED */ exit(0); }
/* * routine that reads the host from a file and puts them * in the hostlist linked list using the above two routines */ host* host_readlist(char *fname) { FILE *hstlist; host *head; host *hst; char line[MAXNAME]; char host_line[MAXNAME]; char user[MAXUSER]; int linelen; if (!fname) return(NULL); hstlist = fopen(fname, "r"); if (!hstlist) return(NULL); head = host_new("", NULL); hst = head; char tok[] = "@"; char *res = NULL; while (fgets(line, sizeof(line), hstlist)) { if (sscanf(line, "%[A-Za-z0-9-.@]", line) != 1) continue; if (strpbrk(line, "@") != NULL) { res = strtok(line, tok); int i = 0; while (res != NULL) { if (i == 0) { strncpy(user, res, sizeof(user)); } else { res = strtok(NULL, tok); if (res == NULL) continue; strncpy(host_line, res, sizeof(host_line)); } i++; } hst = host_add(hst, host_line, user); linelen = strlen(host_line); } else { hst = host_add(hst, line, NULL); linelen = strlen(line); } /* keep track of the longest line */ if (linelen > host_len_max) host_len_max = linelen; hostcount++; } fclose(hstlist); hst = head->next; free(head); if (maxchld > hostcount) maxchld = hostcount; return(hst); }
/* * routine that reads the host from a file and puts them * in the hostlist linked list using the above two routines */ struct host* host_readlist(char *fname) { FILE *hstlist; struct host *hst; struct host *hst_head; char line[MAXNAME*3]; int i; int linelen; u_long port; char *login = NULL; char *hostname = NULL; char *llabel = NULL; hstlist = host_openfile(fname); if (hstlist == NULL) exit(1); hst_head = hst = host_add(NULL, NULL, NULL, 0); if (hst_head == NULL) { perr("Unable to add host structure head in %s\n", __func__); exit(1); } while (fgets(line, sizeof(line), hstlist)) { if (sscanf(line, "%[A-Za-z0-9-.@:%]", line) != 1) continue; linelen = strlen(line); /* label support */ if (line[0] == '%') { if (llabel) free(llabel); llabel = calloc(1, linelen + 1); if (llabel == NULL) { perr("Can't alloc mem in %s\n", __func__); exit(1); } strncpy(llabel, &line[1], linelen); continue; } hostname = line; login = NULL; port = NON_DEFINED_PORT; /* XXX: This is ugly */ for (i=0; i < linelen; i++) { switch (line[i]) { case '@': if (login) break; line[i] = '\0'; if (strlen(line)) login = line; else break; hostname = &line[i+1]; break; case ':': line[i] = '\0'; port = strtol(&line[i+1], (char **)NULL, 10); break; default: break; } } if ((hostname == NULL) || (strlen(hostname) == 0)) continue; errno = 0; if (!login) login = user; /* check if labels match */ if (label && llabel) { if (strcmp(llabel, label)) continue; } /* add the host record */ hst = host_add(hst, login, hostname, (uint16_t)port); if (hst == NULL) { perr("Unable to add member to " "the host struct in %s\n", __func__); exit(1); } /* keep track of the longest username */ if (login && strlen(login) > user_len_max) user_len_max = strlen(login); /* keep track of the longest hostname */ if (strlen(hostname) > host_len_max) host_len_max = strlen(hostname); hostcount++; } if (llabel) free(llabel); fclose(hstlist); if (maxchld > hostcount) maxchld = hostcount; hst = hst_head->next; free(hst_head); return(hst); }
void props_load (void) { FILE *f; char *fn; struct host *h; struct server_props *p = NULL; char *addr; unsigned short port; char buf[1024]; char *ptr; props_free_all (); fn = file_in_dir (user_rcdir, SERVERS_FILE); f = fopen (fn, "r"); g_free (fn); if (!f) return; while (!feof (f)) { fgets (buf, 1024, f); if (buf[0] == '\n') { if (p) p = NULL; } else if (buf[0] == '[') { if (p) continue; ptr = strchr (&buf[1], ']'); if (!ptr) continue; *ptr = '\0'; if (!parse_address (&buf[1], &addr, &port)) continue; if (port == 0) { g_free (addr); continue; } h = host_add (addr); g_free (addr); if (!h) continue; p = __properties (h, port); if (!p) p = properties_new (h, port); } else { if (!p) continue; ptr = strchr (buf, ' '); if (!ptr) continue; *ptr++ = '\0'; if (strcmp (buf, "custom_cfg") == 0) { g_free (p->custom_cfg); p->custom_cfg = strdup_strip (ptr); } else if (strcmp (buf, "password") == 0) { g_free (p->server_password); p->server_password = strdup_strip (ptr); } else if (strcmp (buf, "spectator_password") == 0) { g_free (p->spectator_password); p->spectator_password = strdup_strip (ptr); } else if (strcmp (buf, "rcon_password") == 0) { g_free (p->rcon_password); p->rcon_password = strdup_strip (ptr); } else if (strcmp (buf, "reserved_slots") == 0) { p->reserved_slots= atoi(ptr); } else if (strcmp (buf, "sucks") == 0) { p->sucks = atoi(ptr); } else if (strcmp (buf, "comment") == 0) { unsigned di, si; size_t slen = strlen(ptr); int quote = 0; g_free (p->comment); p->comment = g_malloc0 (slen + 1); for (si = 0, di = 0; si < slen; ++si) { if (quote) { quote = 0; if (ptr[si] == 'n') p->comment[di++] = '\n'; else if (ptr[si] == '\\') p->comment[di++] = '\\'; else xqf_warning("unknown control sequence \\%c", ptr[si]); } else if (ptr[si] == '\\') { quote = 1; } else { p->comment[di++] = ptr[si]; } } } } } fclose (f); }