void recv_packet(void) { char errbuf[PCAP_ERRBUF_SIZE], pfilter[512], base_filter[256], addr_filter[64], defhost[64]; struct bpf_program filter; struct sockaddr_in lsin; bpf_u_int32 net, mask; int ac_s=0, ret=0; uint32_t foct=0, defport=0; uint8_t msg_type=0, status=0, *ptr=NULL; size_t msg_len=0; xpoll_t spdf[2]; union { void *ptr; uint8_t *cr; uint16_t *r_magic; } r_u; union { recv_udp_workunit_t *u; recv_tcp_workunit_t *t; recv_arp_workunit_t *a; uint8_t *cr; uint32_t *magic; } wku; union { listener_info_t *l; uint8_t *ptr; } l_u; r_queue=fifo_init(); close_output_modules(); close_report_modules(); close_payload_modules(); if (s->verbose > 3) MSG(M_DBG1, "Creating server socket"); CLEAR(defhost); CLEAR(defport); /* heh */ if (sscanf(DEF_LISTENER, "%63[0-9.]:%u", defhost, &defport) != 2) { MSG(M_ERR, "Cant parse default listener data `%s'", DEF_LISTENER); terminate(TERM_ERROR); } if (inet_aton(defhost, &lsin.sin_addr) < 0) { MSG(M_ERR, "Can't parse default host `%s'", defhost); terminate(TERM_ERROR); } if (defport > 0xFFFF) { MSG(M_ERR, "Default listening port is out of range"); terminate(TERM_ERROR); } lsin.sin_port=htons(defport); lsin.sin_addr.s_addr=htonl(INADDR_ANY); if ((ac_s=create_server_socket((const struct sockaddr_in *)&lsin)) < 0) { MSG(M_ERR, "cant create listener socket"); terminate(TERM_ERROR); } if (s->verbose > 3) MSG(M_DBG1, "Waiting for main to connect"); lc_s=wait_for_client(ac_s); if (lc_s < 0) { MSG(M_ERR, "main didnt connect, exiting"); terminate(TERM_ERROR); } if (s->verbose > 3) MSG(M_DBG1, "Got connection"); if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) { MSG(M_ERR, "Unexpected sequence of messages from parent waiting for ident request, exiting"); terminate(TERM_ERROR); } if (msg_type != MSG_IDENT || status != MSG_STATUS_OK) { MSG(M_VERB, "Got an unknown message type `%s' or bad status %d from parent, exiting", strmsgtype(msg_type), status); } if (send_message(lc_s, MSG_IDENTLISTENER, MSG_STATUS_OK, NULL, 0) < 0) { MSG(M_ERR, "Can't send back msgident to parent"); terminate(TERM_ERROR); } if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) { MSG(M_ERR, "Can't read ident ack message from parent, exiting"); terminate(TERM_ERROR); } if (msg_type != MSG_ACK || status != MSG_STATUS_OK) { MSG(M_VERB, "Got an unknown message type `%s' or bad status %d from parent, exiting", strmsgtype(msg_type), status); } if (s->verbose > 3) MSG(M_DBG1, "Sending ready message to parent"); l_u.l=(listener_info_t *)xmalloc(sizeof(listener_info_t)); l_u.l->myaddr=s->vi->myaddr.sin_addr.s_addr; memcpy(l_u.l->hwaddr, s->vi->hwaddr, THE_ONLY_SUPPORTED_HWADDR_LEN); l_u.l->mtu=s->vi->mtu; if (send_message(lc_s, MSG_READY, MSG_STATUS_OK, l_u.ptr, sizeof(listener_info_t)) < 0) { MSG(M_ERR, "Cant send message ready"); terminate(TERM_ERROR); } xfree(l_u.l); /* XXX */ s->_low_ip=0; s->_high_ip=0; s->repeats=0; s->pps=0; s->port_str=NULL; s->ss->syn_key=0; memset(s->ss, 0, sizeof(scan_settings_t)); if (get_singlemessage(lc_s, &msg_type, &status, &(wku.cr), &msg_len) != 1) { MSG(M_ERR, "Unexpected sequence of messages from parent looking for a workunit"); terminate(TERM_ERROR); } if (msg_type == MSG_QUIT || status != MSG_STATUS_OK) terminate(0); if (msg_type != MSG_WORKUNIT) { MSG(M_ERR, "I was expecting a work unit or quit message, i got a `%s' message", strmsgtype(msg_type)); terminate(TERM_ERROR); } assert(wku.magic != NULL); if (*wku.magic == UDP_RECV_MAGIC) { if (s->verbose > 5) MSG(M_DBG2, "Got udp workunit"); s->ss->mode=MODE_UDPSCAN; s->ss->recv_timeout=wku.u->recv_timeout; s->vi->mtu=wku.u->mtu; s->recv_opts=wku.u->recv_opts; } else if (*wku.magic == TCP_RECV_MAGIC) { if (s->verbose > 5) MSG(M_DBG2, "Got tcp workunit"); s->ss->mode=MODE_TCPSCAN; s->ss->recv_timeout=wku.t->recv_timeout; s->vi->mtu=wku.t->mtu; s->recv_opts=wku.t->recv_opts; s->ss->syn_key=wku.t->syn_key; } else if (*wku.magic == ARP_RECV_MAGIC) { if (s->verbose > 5) MSG(M_DBG2, "Got arp workunit"); s->ss->mode=MODE_ARPSCAN; s->ss->recv_timeout=wku.a->recv_timeout; s->vi->mtu=wku.a->mtu; s->recv_opts=wku.a->recv_opts; } else { MSG(M_ERR, "Unknown workunit type `%c'", *wku.cr); terminate(0); } s->mode=s->ss->mode; /* XXX */ if (s->verbose > 3) { if (s->ss->mode == MODE_TCPSCAN) { MSG(M_DBG1, "FROM IPC: TCP scan recv_timeout %d mtu %d recv_opts %x syn_key %.08x", s->ss->recv_timeout, s->vi->mtu, s->recv_opts, s->ss->syn_key); } else if (s->ss->mode == MODE_UDPSCAN) { MSG(M_DBG1, "FROM IPC: UDP scan recv_timeout %d mtu %d recv_opts %x", s->ss->recv_timeout, s->vi->mtu, s->recv_opts); } else if (s->ss->mode == MODE_ARPSCAN) { MSG(M_DBG1, "FROM IPC: ARP scan recv_timeout %d mtu %d recv_opts %x", s->ss->recv_timeout, s->vi->mtu, s->recv_opts); } } if (GET_RETPACKET()) { if (s->verbose > 3) MSG(M_DBG2, "Setting up packet queue"); p_queue=fifo_init(); } if (s->ss->mode == MODE_TCPSCAN || s->ss->mode == MODE_UDPSCAN) { foct=(htonl(s->vi->myaddr.sin_addr.s_addr) >> 24); if (foct == 0x7f) { snprintf(addr_filter, sizeof(addr_filter) -1, "dst %s", s->vi->myaddr_s); } else { snprintf(addr_filter, sizeof(addr_filter) -1, "dst %s and ! src %s", s->vi->myaddr_s, s->vi->myaddr_s); } }
void process_packet(uint8_t *user, const struct pcap_pkthdr *phdr, const uint8_t *packet) { const struct myiphdr *ip_ptr=NULL; const struct mytcphdr *tcp_ptr=NULL; const uint8_t *data=NULL; size_t hdrlen=0; int j=0, j1=0; if (packet == NULL) return; hdrlen=(header_len + sizeof(struct myiphdr) + sizeof(struct mytcphdr)); if (phdr->caplen < hdrlen) { ERR("Short packet at %d bytes", phdr->caplen); return; } ip_ptr=(const struct myiphdr *)(packet + header_len); tcp_ptr=(const struct mytcphdr *)(packet + header_len + sizeof(struct myiphdr)); if (phdr->caplen > (header_len + sizeof(struct myiphdr) + (4 * tcp_ptr->doff))) { data=(const uint8_t *)(packet + header_len + sizeof(struct myiphdr) + (4 * tcp_ptr->doff)); } else { data=NULL; } VRB(0, "caplen %d datalen %d " "sport %d dport %d doff %d" "seq %08x ackseq %08x " "window %u checksum %04x urg_ptr %d\n", phdr->caplen, (phdr->caplen - (header_len + sizeof(struct myiphdr) + (4 * tcp_ptr->doff))), ntohs(tcp_ptr->source), ntohs(tcp_ptr->dest), tcp_ptr->doff, tcp_ptr->seq, tcp_ptr->ack_seq, tcp_ptr->window, tcp_ptr->check, tcp_ptr->urg_ptr); for (j=0; j < MAX_CONNS ; j++) { if (conns[j].sport == ntohs(tcp_ptr->source) && conns[j].dport == ntohs(tcp_ptr->dest)) { break; } if (conns[j].sport == 0) { conns[j].sport=ntohs(tcp_ptr->source); conns[j].dport=ntohs(tcp_ptr->dest); if (conns[j].sport > 7999 && conns[j].sport < 8006) { conns[j].name=xstrdup("Master To Drone"); } else if (conns[j].sport > 12320 && conns[j].sport < 12324) { conns[j].name=xstrdup("Drone To Master"); } else { conns[j].name=xstrdup("Unknown"); } break; } } if (data) { union { const ipc_msghdr_t *msg; const uint8_t *ptr; } mm_u; union { const uint8_t *ptr; const void *vp; listener_info_t *l; } md_u; mm_u.ptr=data; if (mm_u.msg->header != 0xf0f1f2f3) { ERR("BAD IPC PACKET, magic header wrong"); return; } if (mm_u.msg->type == MSG_IDENTLISTENER) { if (conns[j].name) xfree(conns[j].name); conns[j].name=xstrdup("LISTENER To Master"); for (j1=0 ; j1 < MAX_CONNS ; j1++) { if (conns[j1].dport == conns[j].sport && conns[j1].sport == conns[j].dport) { if (conns[j1].name) xfree(conns[j1].name); conns[j1].name=xstrdup("Master to LISTENER"); } } } else if (mm_u.msg->type == MSG_IDENTSENDER) { if (conns[j].name) xfree(conns[j].name); conns[j].name=xstrdup("SENDER To Master"); for (j1=0 ; j1 < MAX_CONNS ; j1++) { if (conns[j1].dport == conns[j].sport && conns[j1].sport == conns[j].dport) { if (conns[j1].name) xfree(conns[j1].name); conns[j1].name=xstrdup("Master to SENDER"); } } } MSG(M_INFO, "{%s}\tMessagetype %s status %d len %d", (conns[j].name == NULL ? "Unknown" : conns[j].name), strmsgtype(mm_u.msg->type), mm_u.msg->status, mm_u.msg->len); if (mm_u.msg->len > 0) { struct in_addr ia1; if (mm_u.msg->len != (phdr->caplen - (header_len + sizeof(struct myiphdr) + (4 * tcp_ptr->doff) + sizeof(ipc_msghdr_t)))) { MSG(M_ERR, "BAD IPC PACKET!"); return; } md_u.ptr=data + sizeof(ipc_msghdr_t); switch (mm_u.msg->type) { case MSG_WORKUNIT: MSG(M_OUT, "WORKUNIT: `%s'", strworkunit(md_u.vp, (size_t )mm_u.msg->len)); break; case MSG_READY: if (mm_u.msg->len == sizeof(listener_info_t)) { ia1.s_addr=md_u.l->myaddr; MSG(M_OUT, "Ready with IP %s HWADDR %s MTU %u", inet_ntoa(ia1), decode_6mac(md_u.l->hwaddr), md_u.l->mtu); } else { MSG(M_OUT, "Unknown ready infomation"); } default: break; } } } return; }
void connect_wait(void *pri_work) { drone_t *d=NULL; xpoll_t spdf[8]; unsigned int spdf_off=0; int pret=0, getret=0; uint8_t msg_type=0, status=0; size_t msg_len=0; uint8_t *ptr=NULL; time_t s_time=0, e_time=0; VRB(1, "waiting for connections to finish"); if (s->dlh == NULL || s->dlh->head == NULL) { PANIC("waiting for connections with no drones?"); } for (s_time=time(NULL);;) { int livesocks=0; for (d=s->dlh->head, spdf_off=0; d != NULL; d=d->next, spdf_off++) { if (d->s) livesocks++; spdf[spdf_off].fd=d->s; } DBG(M_CON, "polling %d sockets......", livesocks); if ((pret=xpoll(&spdf[0], s->dlh->size, 5000)) < 0) { ERR("poll drone fd's fail: %s", strerror(errno)); } time(&e_time); if ((e_time - s_time) > s->ss->recv_timeout) { break; } for (d=s->dlh->head, spdf_off=0; d != NULL; d=d->next, spdf_off++) { d->s_rw=0; if (d->status != DRONE_STATUS_DEAD && d->status != DRONE_STATUS_DONE) { d->s_rw=spdf[spdf_off].rw; } if (spdf[spdf_off].rw & XPOLL_READABLE) { DBG(M_CON, "socket type %s is readable", strdronetype(d->type)); } } for (d=s->dlh->head; d != NULL; d=d->next) { DBG(M_CON, "drone type %s drone status %s", strdronetype(d->type), strdronestatus(d->status)); if (d->type == DRONE_TYPE_LISTENER && (d->status == DRONE_STATUS_READY || d->status == DRONE_STATUS_WORKING)) { /* i just moved this here cause the line above was ugly */ if ((d->s_rw & XPOLL_READABLE) == XPOLL_READABLE) { if (recv_messages(d->s) < 1) { ERR("cant recv_messages from ready listener"); drone_updatestate(d, DRONE_STATUS_DEAD); continue; } while (1) { getret=get_message(d->s, &msg_type, &status, &ptr, &msg_len); if (getret < 1) { break; } if (msg_type == MSG_ERROR || status != MSG_STATUS_OK) { ERR("drone on fd %d is dead, closing socket and marking dead", d->s); drone_updatestate(d, DRONE_STATUS_DEAD); break; } else if (msg_type == MSG_OUTPUT) { deal_with_output(ptr, msg_len); } else { ERR("unhandled message from Listener drone message type `%s' with status %d", strmsgtype(msg_type), status); } } } } else if (d->type == DRONE_TYPE_SENDER && d->status == DRONE_STATUS_READY) { union { uint8_t *pw_ptr; void *ptr; send_pri_workunit_t *p; } pw_u; while ((pw_u.ptr=fifo_pop(pri_work)) != NULL) { DBG(M_CON, "sending pri work to sender in wait connections"); if (send_message( d->s, MSG_WORKUNIT, MSG_STATUS_OK, pw_u.pw_ptr, sizeof(send_pri_workunit_t) + pw_u.p->doff ) < 0) { ERR("cant send priority workunit to sender on fd %d, marking dead", d->s); drone_updatestate(d, DRONE_STATUS_DEAD); fifo_push(pri_work, pw_u.ptr); continue; } xfree(pw_u.ptr); } } if (s->senders == 0 || s->listeners == 0) { PANIC(s->senders == 0 ? "no senders" : "no listeners"); } } } VRB(1, "connections timeout"); }
void recv_packet(void) { char errbuf[PCAP_ERRBUF_SIZE], *pfilter=NULL; struct bpf_program filter; bpf_u_int32 net, mask; int ac_s=0, ret=0, worktodo=1; uint8_t msg_type=0, status=0, *ptr=NULL; size_t msg_len=0; xpoll_t spdf[2]; union { recv_workunit_t *r; uint8_t *cr; uint32_t *magic; } wk_u; union { listener_info_t *l; uint8_t *ptr; } l_u; union { drone_version_t *v; uint8_t *ptr; } d_u; drone_version_t dv; struct pcap_stat pcs; r_queue=fifo_init(); close_output_modules(); close_report_modules(); close_payload_modules(); DBG(M_IPC, "creating server socket"); memset(s->ss, 0, sizeof(scan_settings_t)); memset(&dv, 0, sizeof(dv)); d_u.v=&dv; dv.magic=DRONE_MAGIC; dv.maj=DRONE_MAJ; dv.min=DRONE_MIN; recv_stats_t recv_stats; /* heh */ if ((ac_s=socktrans_bind(s->ipcuri)) < 0) { terminate("cant create listener socket"); } DBG(M_IPC, "waiting for main to connect"); parent_sync(); lc_s=socktrans_accept(ac_s, DEF_SOCK_TIMEOUT); if (lc_s < 0) { terminate("main didnt connect, exiting"); } DBG(M_IPC, "got connection"); if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) { terminate("unexpected sequence of messages from parent waiting for ident request, exiting"); } if (msg_type != MSG_IDENT || status != MSG_STATUS_OK) { ERR("got an unknown message type `%s' or bad status %d from parent, exiting", strmsgtype(msg_type), status); } if (send_message(lc_s, MSG_IDENTLISTENER, MSG_STATUS_OK, d_u.ptr, sizeof(drone_version_t)) < 0) { terminate("cant send back msgident to parent"); } if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) { terminate("cant read ident ack message from parent, exiting"); } if (msg_type != MSG_ACK || status != MSG_STATUS_OK) { ERR("got an unknown message type `%s' or bad status %d from parent, exiting", strmsgtype(msg_type), status); } DBG(M_IPC, "sending ready message to parent"); l_u.l=(listener_info_t *)xmalloc(sizeof(listener_info_t)); memcpy(&l_u.l->myaddr, &s->vi[0]->myaddr, sizeof(struct sockaddr_storage)); memcpy(&l_u.l->mymask, &s->vi[0]->mymask, sizeof(struct sockaddr_storage)); memcpy(l_u.l->hwaddr, s->vi[0]->hwaddr, THE_ONLY_SUPPORTED_HWADDR_LEN); l_u.l->mtu=s->vi[0]->mtu; assert(s->interface_str != NULL); if (pcap_lookupnet(s->interface_str, &net, &mask, errbuf) < 0) { ERR("pcap_lookupnet fails, ignoring: %s", errbuf); } if (s->pcap_readfile == NULL) { pdev=pcap_open_live(s->interface_str, /* XXX haha */ s->vi[0]->mtu + 64, (GET_PROMISC() ? 1 : 0), 0, errbuf); if (pdev == NULL) { ERR("pcap open live: %s", errbuf); DBG(M_IPC, "sending ready error message to parent"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("cant send message ready error"); } terminate("informed parent, exiting"); } } else { pdev=pcap_open_offline(s->pcap_readfile, errbuf); if (pdev == NULL) { ERR("pcap open offline: %s", errbuf); DBG(M_IPC, "sending ready error message to parent"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("cant send message ready error"); } terminate("informed parent, exiting"); } } ret=util_getheadersize(pdev, errbuf); if (ret < 0 || ret > 0xffff) { ERR("error getting link header size: %s", errbuf); DBG(M_IPC, "sending ready error message to parent"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("cant send message ready error"); } terminate("informed parent, exiting"); } s->ss->header_len=(uint16_t)ret; if (s->pcap_dumpfile != NULL) { VRB(0, "opening `%s' for pcap log", s->pcap_dumpfile); pdump=pcap_dump_open(pdev, s->pcap_dumpfile); if (pdump == NULL) { ERR("cant log to pcap file `%s'", pcap_geterr(pdev)); DBG(M_IPC, "sending ready error message to parent"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("cant send message ready error"); } terminate("informed parent, exiting"); } } else { DBG(M_CLD, "not logging to pcap file"); } if (util_preparepcap(pdev, errbuf) < 0) { ERR("cant setup pcap filedesc to immediate mode: %s", errbuf); DBG(M_IPC, "sending ready error message to parent"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("cant send message ready error"); } terminate("informed parent, exiting"); } /* pcap_fd will be -1 for a pcap file */ pcap_fd=pcap_get_selectable_fd(pdev); if (pcap_fd < 0 && s->pcap_readfile == NULL) { ERR("cant get selectable fd from pcap device, exiting"); DBG(M_IPC, "sending ready error message to parent"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("sant send message ready error"); } terminate("informed parent, exiting"); } #ifdef PCAP_D_IN if (pcap_setdirection(pdev, PCAP_D_IN) < 0) { ERR("cant set pcap direction to in, exiting"); DBG(M_IPC, "sending ready error message to parent"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("sant send message ready error"); } terminate("informed parent, exiting"); } #endif DBG(M_CLD, "listener dropping privs"); if (drop_privs() < 0) { terminate("cant drop privs"); } if (send_message(lc_s, MSG_READY, MSG_STATUS_OK, l_u.ptr, sizeof(listener_info_t)) < 0) { terminate("cant send message ready"); } xfree(l_u.l); /* XXX */ s->ss->syn_key=0; do { if (get_singlemessage(lc_s, &msg_type, &status, &wk_u.cr, &msg_len) != 1) { terminate("unexpected sequence of messages from parent looking for a workunit"); } if (status != MSG_STATUS_OK) { terminate("bad message status %u", status); } if (msg_type == MSG_QUIT) { worktodo=0; break; } else if (msg_type == MSG_WORKUNIT) { ; } else { terminate("unexpected message, expecting workunit or quit message"); } if (msg_len < sizeof(uint32_t)) { terminate("bad message, too short [" STFMT "]", msg_len); } if (msg_len < sizeof(recv_workunit_t)) { terminate("short workunit"); } worktodo=1; DBG(M_WRK, "workunit `%s'", strworkunit(wk_u.cr, msg_len)); s->ss->recv_timeout=wk_u.r->recv_timeout; s->ss->ret_layers=wk_u.r->ret_layers; s->recv_opts=wk_u.r->recv_opts; s->ss->window_size=wk_u.r->window_size; s->ss->syn_key=wk_u.r->syn_key; if (wk_u.r->pcap_len) { if ((msg_len - sizeof(recv_workunit_t)) == wk_u.r->pcap_len) { extract_pcapfilter(wk_u.cr + sizeof(recv_workunit_t), wk_u.r->pcap_len); } else { terminate("pcap option length illegal"); } } switch (*wk_u.magic) { case UDP_RECV_MAGIC: s->ss->mode=MODE_UDPSCAN; break; case TCP_RECV_MAGIC: s->ss->mode=MODE_TCPSCAN; break; case ARP_RECV_MAGIC: s->ss->mode=MODE_ARPSCAN; break; default: terminate("unknown recv workunit type"); break; } DBG(M_IPC, "from ipc, got workunit: %s", strworkunit((const void *)wk_u.cr, msg_len)); if (s->ss->mode == MODE_ARPSCAN) { if (s->ss->header_len != 14) { DBG(M_IPC, "sending msg error"); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { terminate("cant send message ready"); } terminate("wrong linktype for arp scan"); } } if (s->ss->ret_layers > 0) { DBG(M_CLD, "setting up packet queue"); p_queue=fifo_init(); } pfilter=get_pcapfilterstr(); VRB(1, "using pcap filter: `%s'", pfilter); memset(&filter, 0, sizeof(filter)); if (pcap_compile(pdev, &filter, pfilter, 0, net) < 0) { ERR("error compiling filter: %s", pcap_geterr(pdev)); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { ERR("cant send message ready error"); } terminate("cant compile pcap filter"); } if (pcap_setfilter(pdev, &filter) < 0) { ERR("error setting compiled filter: %s", pcap_geterr(pdev)); if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) { ERR("cant send message ready error"); } terminate("cant set compiled pcap filter"); } pcap_freecode(&filter); if (s->ss->ret_layers > 0) { DBG(M_IPC, "returning whole packet via ipc"); } DBG(M_IPC, "sending ready message to parent"); if (pcap_setnonblock(pdev, 1, errbuf) < 0) { terminate("cant set pcap non-blocking mode"); } if (send_message(lc_s, MSG_READY, MSG_STATUS_OK, NULL, 0) < 0) { terminate("cant send message ready"); } while (1) { spdf[0].fd=lc_s; spdf[1].fd=pcap_fd; /* if pdev is a socket ( ! -1 ) */ if (xpoll(&spdf[0], 2, -1) < 0) { ERR("xpoll fails: %s", strerror(errno)); } if (spdf[1].rw & XPOLL_READABLE) { pcap_dispatch(pdev, 1, parse_packet, NULL); } /* no packets, better drain the queue */ drain_pqueue(); if (spdf[0].rw & XPOLL_READABLE) { if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) { ERR("unexpected sequence of messages from parent in main read loop, exiting"); worktodo=0; break; } if (msg_type == MSG_TERMINATE) { DBG(M_IPC, "parent wants me to stop listening, breaking"); break; } else if (msg_type == MSG_QUIT) { DBG(M_IPC, "Parent wants me to quit, breaking"); worktodo=0; break; } else { ERR("got strange message `%s' from parent, exiting", strmsgtype(msg_type)); worktodo=0; break; } } } memset(&recv_stats, 0, sizeof(recv_stats)); if (pcap_stats(pdev, &pcs) != -1) { recv_stats.packets_recv=pcs.ps_recv; recv_stats.packets_dropped=pcs.ps_drop; recv_stats.packets_dropped=pcs.ps_ifdrop; } if (send_message(lc_s, MSG_WORKDONE, MSG_STATUS_OK, (void *)&recv_stats, sizeof(recv_stats)) < 0) { terminate("cant send workdone message to parent, exiting"); } } while (worktodo); pcap_close(pdev); if (s->pcap_dumpfile) { pcap_dump_close(pdump); } DBG(M_CLD, "listener exiting"); shutdown(lc_s, SHUT_RDWR); close(lc_s); uexit(0); }
int main(int argc, char **argv) { char buf[4096]; pid_t chld_listener=-1, chld_sender=-1; uint8_t status=0, msg_type=0, ecount=0; size_t msg_len=0; struct sigaction chsa; uint8_t *ptr=NULL; int lports=IPC_BINDPORT_START; uint8_t all_done=0; char verbose_level[4]; drone_t *c=NULL; ident=IDENT_MASTER; ident_name_ptr=IDENT_MASTER_NAME; CLEAR(buf); s=(settings_t *)xmalloc(sizeof(settings_t)); memset(s, 0, sizeof(settings_t)); s->vi=(interface_info_t *)xmalloc(sizeof(interface_info_t)); memset(s->vi, 0, sizeof(interface_info_t)); s->forked=0; /* not required, for clarity */ /* s->display=&display_builtin; */ getconfig_argv(argc, argv); if (s->interface_str == NULL) { if (get_default_route_interface(&s->interface_str) != 1) { MSG(M_WARN, "Can't find default route, and matching device, using default interface `%s'", DEFAULT_NETDEV); s->interface_str=xstrdup(DEFAULT_NETDEV); } if (s->verbose > 1) { MSG(M_VERB, "Using interface %s", s->interface_str); } } if (!(GET_OVERRIDE())) { /* let the listener tell us then, the user didnt request a specific address */ CLEAR(s->vi->myaddr_s); CLEAR(s->vi->hwaddr_s); sprintf(s->vi->myaddr_s, "0.0.0.0"); sprintf(s->vi->hwaddr_s, "00:00:00:00:00:00"); memset(&s->vi->myaddr, 0, sizeof(s->vi->myaddr)); memset(&s->vi->hwaddr, 0, sizeof(s->vi->hwaddr)); } else { /* complete the information we need like hwaddr, cause its impossible to specify that currently */ if (s->verbose > 1) MSG(M_DBG2, "Spoofing from `%s [%s]'", s->vi->myaddr_s, s->vi->hwaddr_s); /* the ip info is already filled in, so just complete the rest */ CLEAR(s->vi->hwaddr_s); sprintf(s->vi->hwaddr_s, "00:00:00:00:00:00"); memset(&s->vi->hwaddr, 0, sizeof(s->vi->hwaddr)); } s->vi->mtu=0; /* the listener HAS to tell us this, seeing as how the real limitation is there */ time(&(s->s_time)); if (s->forklocal) { if (s->verbose > 5) MSG(M_DBG2, "children will be forked, setting up signal handler for them"); memset(&chsa, 0, sizeof(chsa)); chsa.sa_handler=&child_dead; if (sigaction(SIGCHLD, &chsa, NULL) < 0) { MSG(M_ERR, "Cant register SIGCHLD handler"); terminate(TERM_ERROR); } } arc4random_stir(); if (init_modules() < 0) { MSG(M_ERR, "Can't initialize module structures, quiting"); terminate(TERM_ERROR); } if (ipc_init() < 0) { MSG(M_ERR, "Cant initialize IPC, quiting"); terminate(TERM_ERROR); } if (s->verbose > 0) { char low[32], high[32]; uint32_t ips=0; CLEAR(low); CLEAR(high); ips=ntohl(s->_low_ip); snprintf(low, sizeof(low) -1, "%s", inet_ntoa((*(struct in_addr *)&ips))); ips=ntohl(s->_high_ip); snprintf(high, sizeof(high) -1, "%s", inet_ntoa((*(struct in_addr *)&ips))); MSG(M_VERB, "Scanning: %s -> %s : %s from %s [%s] at %u pps", low, high, (s->mode == MODE_ARPSCAN ? "Arp" : s->port_str), s->vi->myaddr_s, s->vi->hwaddr_s, s->pps); } if (s->verbose > 3) MSG(M_DBG1, "Main process id is %d", getpid()); snprintf(verbose_level, sizeof(verbose_level) -1, "%d", s->verbose); /* initialize senders */ if ((s->forklocal & FORK_LOCAL_SENDER) == FORK_LOCAL_SENDER) { if (s->drone_str == NULL) { s->drone_str=xstrdup(DEF_SENDER); if (s->verbose > 5) MSG(M_DBG2, "Added default sender to drone list `%s'", s->drone_str); } else { char newstr[128]; CLEAR(newstr); snprintf(newstr, sizeof(newstr) -1, "%s,%s", s->drone_str, DEF_SENDER); xfree(s->drone_str); s->drone_str=xstrdup(newstr); } chld_sender=fork(); if (chld_sender < 0) { MSG(M_ERR, "Can't fork sender: %s", strerror(errno)); terminate(TERM_ERROR); } if (chld_sender == 0) { char *argz[5]; char *envz[2]; argz[0]=SENDERNAME; argz[1]=s->mod_dir; argz[2]=verbose_level; argz[3]=s->interface_str; argz[4]=NULL; envz[0]='\0'; execve(SENDER_PATH, argz, envz); MSG(M_ERR, "execve %s fails", SENDER_PATH); terminate(TERM_ERROR); } child_running++; s->forklocal &= ~(FORK_LOCAL_SENDER); } else if (s->verbose > 5) { MSG(M_DBG2, "No local sender will be forked"); } /* initialize listeners */ if ((s->forklocal & FORK_LOCAL_LISTENER) == FORK_LOCAL_LISTENER) { if (s->drone_str == NULL) { s->drone_str=xstrdup(DEF_LISTENER); if (s->verbose > 5) MSG(M_DBG2, "Adding default listener to drone list"); } else { char newstr[128]; CLEAR(newstr); snprintf(newstr, sizeof(newstr) -1, "%s,%s", s->drone_str, DEF_LISTENER); xfree(s->drone_str); s->drone_str=xstrdup(newstr); } chld_listener=fork(); if (chld_listener < 0) { MSG(M_ERR, "Can't fork listener: %s", strerror(errno)); terminate(TERM_ERROR); } if (chld_listener == 0) { char *argz[7]; char *envz[2]; char mtu[8]; CLEAR(mtu); snprintf(mtu, sizeof(mtu) -1, "%u", s->vi->mtu); argz[0]=LISTENERNAME; argz[1]=s->mod_dir; argz[2]=verbose_level; argz[3]=s->interface_str; argz[4]=s->vi->myaddr_s; argz[5]=s->vi->hwaddr_s; argz[6]=NULL; envz[0]='\0'; execve(LISTENER_PATH, argz, envz); MSG(M_ERR, "execve %s fails", LISTENER_PATH); terminate(TERM_ERROR); } child_running++; s->forklocal &= ~(FORK_LOCAL_LISTENER); } else if (s->verbose > 5) { MSG(M_DBG2, "No local listener will be forked"); } /* we need these modules cause we are hardcoded as a output conduit for now XXX */ if (init_output_modules() < 0) { MSG(M_ERR, "Can't initialize output module structures, quiting"); terminate(TERM_ERROR); } if (init_report_modules() < 0) { MSG(M_ERR, "Can't initialize report module structures, quiting"); terminate(TERM_ERROR); } if (s->verbose > 2) MSG(M_DBG1, "drones: %s", s->drone_str); if (parse_drone_list((const char *)s->drone_str) < 0) { terminate(TERM_ERROR); } else if (s->verbose > 5) { MSG(M_DBG1, "Drone list `%s' parsed correctly", s->drone_str); } /* do stuff to figure out if there are working drones */ if (s->verbose > 4) MSG(M_DBG1, "Drone list is %d big, connecting to them.", s->dlh->size); do { uint8_t *dummy=NULL; struct sockaddr_in lbind; c=s->dlh->head; if (c == NULL) { MSG(M_ERR, "no drones?, thats not going to work"); terminate(TERM_ERROR); } for (c=s->dlh->head ; c != NULL ; c=c->next) { if (s->verbose > 6) MSG(M_DBG1, "THIS NODE -> status: %d type: %s host: %s port: %d socket: %d (%d out of %d ready)", c->status, (c->type == DRONE_TYPE_SENDER ? "Sender" : "Listener") , inet_ntoa(c->dsa.sin_addr), ntohs(c->dsa.sin_port), c->s, all_done, s->dlh->size); if (ecount > MAX_ERRORS) { MSG(M_ERR, "Too many errors, exiting now"); terminate(TERM_ERROR); } switch (c->status) { /* connect to it */ case DRONE_STATUS_UNKNOWN: memset(&lbind, 0, sizeof(lbind)); lbind.sin_port=htons(lports++); if (c->s == -1 && create_client_socket(c, (struct sockaddr_in *)&lbind) < 0) { c->s=-1; usleep(50000); ecount++; } else { c->status=DRONE_STATUS_CONNECTED; } break; /* find out what it is */ case DRONE_STATUS_CONNECTED: c->type=DRONE_TYPE_UNKNOWN; if (send_message(c->s, MSG_IDENT, MSG_STATUS_OK, dummy, 0) < 0) { ecount++; MSG(M_ERR, "Cant ident message node, marking as dead"); if (ecount > MAX_ERRORS) { mark_dead(c); break; } } else { if (get_singlemessage(c->s, &msg_type, &status, &ptr, &msg_len) != 1) { MSG(M_ERR, "Unexpected message response from fd %d, marking as dead", c->s); mark_dead(c); } switch (msg_type) { case MSG_IDENTSENDER: c->type=DRONE_TYPE_SENDER; s->senders++; break; case MSG_IDENTLISTENER: c->type=DRONE_TYPE_LISTENER; s->listeners++; break; default: MSG(M_ERR, "Unknown drone type from message %s", strmsgtype(msg_type)); c->type=DRONE_TYPE_UNKNOWN; } if (send_message(c->s, MSG_ACK, MSG_STATUS_OK, dummy, 0) < 0) { MSG(M_ERR, "Cant ack ident message from node on fd %d, marking as dead", c->s); mark_dead(c); } c->status=DRONE_STATUS_IDENT; } break; /* wait for it to say its ready */ case DRONE_STATUS_IDENT: if (get_singlemessage(c->s, &msg_type, &status, &ptr, &msg_len) != 1) { MSG(M_ERR, "Unexpected message reply from drone on fd %d, marking as dead", c->s); mark_dead(c); } else if (msg_type == MSG_READY) { c->status=DRONE_STATUS_READY; if (s->verbose > 3) MSG(M_DBG1, "drone on fd %d is ready", c->s); if (c->type == DRONE_TYPE_LISTENER) { union { listener_info_t *l; uint8_t *ptr; } l_u; struct in_addr ia; if (msg_len != sizeof(listener_info_t)) { MSG(M_ERR, "Listener didnt send me the correct information, marking dead"); mark_dead(c); } l_u.ptr=ptr; s->vi->myaddr.sin_addr.s_addr=l_u.l->myaddr; ia.s_addr=s->vi->myaddr.sin_addr.s_addr; s->vi->mtu=l_u.l->mtu; memcpy(s->vi->hwaddr, l_u.l->hwaddr, THE_ONLY_SUPPORTED_HWADDR_LEN); snprintf(s->vi->hwaddr_s, sizeof(s->vi->hwaddr_s) -1, "%.02x:%.02x:%.02x:%.02x:%.02x:%.02x", l_u.l->hwaddr[0], l_u.l->hwaddr[1], l_u.l->hwaddr[2], l_u.l->hwaddr[3], l_u.l->hwaddr[4], l_u.l->hwaddr[5]); snprintf(s->vi->myaddr_s, sizeof(s->vi->myaddr_s) -1, "%s", inet_ntoa(ia)); if (s->verbose > 2) MSG(M_DBG1, "Listener info gave me the following address information `%s [%s]' with mtu %u", s->vi->myaddr_s, s->vi->hwaddr_s, s->vi->mtu); } } else { MSG(M_ERR, "drone isnt ready on fd %d, marking as dead", c->s); mark_dead(c); } break; case DRONE_STATUS_READY: all_done++; break; case DRONE_STATUS_DEAD: all_done++; MSG(M_WARN, "Dead drone in list on fd %d", c->s); break; } /* switch node status */ } /* step though list */ } while (all_done < s->dlh->size); /* XXX remove this and fix */ if (s->senders == 0 && GET_SENDDRONE()) { /* XXX */ MSG(M_ERR, "No senders for scan, giving up and rudley disconnecting from other drones without warning"); terminate(TERM_ERROR); } if (s->listeners == 0 && GET_LISTENDRONE()) { /* XXX */ MSG(M_ERR, "No listeners for scan, giving up and rudley disconnecting from other drones without warning"); terminate(TERM_ERROR); } if (s->verbose > 5) MSG(M_DBG2, "Running scan"); run_mode(); time(&(s->e_time)); if (s->verbose > 4) MSG(M_DBG2, "Main shuting down output modules"); fini_output_modules(); fini_report_modules(); if (s->verbose > 4) MSG(M_DBG2, "Main exiting"); terminate(TERM_NORMAL); }
void run_scan(void) { uint8_t msg_type=0, status=0, *ptr=NULL; size_t wk_len=0, msg_len=0; xpoll_t spdf[4]; /* XXX dynamic */ union { uint8_t *cr; void *ptr; } w_k; drone_t *c=NULL; rfifo=fifo_init(); if (GET_DOCONNECT()) { pri_work=fifo_init(); state_tbl=TBLINIT(111); } if (s->ss->mode == MODE_TCPSCAN) s->ss->syn_key=arc4random(); for (c=s->dlh->head ; c != NULL ; c=c->next) { if (c->type == DRONE_TYPE_LISTENER && c->status == DRONE_STATUS_READY) { if ((w_k.ptr=get_lp_workunit(&wk_len)) != NULL) { if (s->verbose > 2) { if (s->verbose > 5) { MSG(M_DBG2, "Got listener workunit of size %d :]", wk_len); } MSG(M_DBG1, "sending workunit to listener"); } if (send_message(c->s, MSG_WORKUNIT, MSG_STATUS_OK, w_k.cr, wk_len) < 0) { MSG(M_ERR, "Cant Send Workunit to listener on fd %d", c->s); mark_dead(c, DRONE_STATUS_DEAD); } if (c->s == -1) PANIC("WOW!!!!"); if (get_singlemessage(c->s, &msg_type, &status, &ptr, &msg_len) != 1) { MSG(M_ERR, "Unexpected sequence of messages from listener on fd %d, marking dead", c->s); mark_dead(c, DRONE_STATUS_DEAD); } if (status != MSG_STATUS_OK) { MSG(M_ERR, "bad status `%d' from listener on fd %d, marking as dead", status, c->s); mark_dead(c, DRONE_STATUS_DEAD); } if (msg_type != MSG_READY) { MSG(M_ERR, "bad message `%s' from listener on fd %d, marking as dead", strmsgtype(msg_type), c->s); mark_dead(c, DRONE_STATUS_DEAD); } else if (s->verbose > 3) { MSG(M_DBG1, "Sent workunits to listener on fd %d", c->s); } } } } if (s->listeners == 0) { MSG(M_ERR, "Not enough listeners to run scan, bailing out"); return; } while (1) { int readorwrite=0, breakout=0, pret=0; uint32_t d_offset=0; c=s->dlh->head; assert(s->dlh->size <= sizeof(spdf)); /* XXX */ /* write loop */ for (c=s->dlh->head, d_offset=0 ; c != NULL ; c=c->next, d_offset++) { if (c->type == DRONE_TYPE_SENDER) { void *pw_ptr=NULL; if (GET_DOCONNECT()) { while ((pw_ptr=fifo_pop(pri_work)) != NULL) { if (send_message(c->s, MSG_WORKUNIT, MSG_STATUS_OK, pw_ptr, sizeof(send_pri_workunit_t)) < 0) { MSG(M_ERR, "Cant send priority workunit to sender on fd %d, marking dead", c->s); mark_dead(c, DRONE_STATUS_DEAD); } } } if (c->status == DRONE_STATUS_READY) { /* get to work! */ w_k.cr=NULL; if ((w_k.ptr=get_sp_workunit(&wk_len)) != NULL) { if (s->verbose > 2) { if (s->verbose > 5) { MSG(M_DBG2, "Got workunit of size %d :]", wk_len); } MSG(M_DBG1, "sending workunit to sender"); } if (send_message(c->s, MSG_WORKUNIT, MSG_STATUS_OK, w_k.cr, wk_len) < 0) { MSG(M_ERR, "Cant Send Workunit to sender on fd %d", c->s); mark_dead(c, DRONE_STATUS_DEAD); } else if (s->verbose > 3) { MSG(M_DBG1, "Sent workunits to senders"); } c->status=DRONE_STATUS_WORKING; readorwrite=1; } else { if (s->verbose > 3) MSG(M_DBG1, "Marking sender on fd %d as done, no more workunits to send", c->s); send_message(c->s, MSG_QUIT, MSG_STATUS_OK, ptr, 0); mark_dead(c, DRONE_STATUS_DONE); } } } spdf[d_offset].fd=c->s; } if (!(s->senders)) { breakout++; break; } if ((pret=xpoll(&spdf[0], s->dlh->size, -1)) < 0) { MSG(M_ERR, "Poll drone fd's fail: %s", strerror(errno)); } for (c=s->dlh->head, d_offset=0 ; c != NULL ; c=c->next, d_offset++) { c->s_rw=0; if (c->status != DRONE_STATUS_DEAD && c->status != DRONE_STATUS_DONE) { c->s_rw=spdf[d_offset].rw; } if (spdf[d_offset].rw & XPOLL_READABLE) { if (s->verbose > 4) MSG(M_DBG1, "Socket type %s is readable", (c->type == DRONE_TYPE_LISTENER) ? "Listener" : "Sender"); } } /* read loop */ for (c=s->dlh->head, d_offset=0 ; c != NULL ; c=c->next, d_offset++) { if (c->status != DRONE_STATUS_DEAD && c->status != DRONE_STATUS_DONE && c->s_rw & XPOLL_READABLE) { int getret=0; if (s->verbose > 5) MSG(M_DBG2, "Reading file descriptor %d type %s and %d senders left", c->s, (c->type == DRONE_TYPE_SENDER ? "Sender" : "Listener"), s->senders); if (recv_messages(c->s) < 0) { MSG(M_ERR, "Cant recieve messages from fd %d, marking as dead", c->s); mark_dead(c, DRONE_STATUS_DEAD); continue; } while (1) { if (c->status == DRONE_STATUS_DONE || c->status == DRONE_STATUS_DEAD) break; getret=get_message(c->s, &msg_type, &status, &ptr, &msg_len); if (getret < 1) break; if (msg_type == MSG_ERROR || status != MSG_STATUS_OK) { MSG(M_ERR, "Drone on fd %d is dead, closing socket and marking dead", c->s); mark_dead(c, DRONE_STATUS_DEAD); break; } else if (msg_type == MSG_WORKDONE && c->type == DRONE_TYPE_SENDER) { if (s->verbose > 5) MSG(M_DBG2, "Setting sender back to ready state after workdone message"); c->status=DRONE_STATUS_READY; } else if (msg_type == MSG_OUTPUT && c->type == DRONE_TYPE_LISTENER) { if (s->ss->mode == MODE_TCPSCAN || s->ss->mode == MODE_UDPSCAN) { if (msg_len < sizeof(ip_report_t)) { MSG(M_ERR, "Unknown report format from listener"); } else { handle_ipoutput(ptr); } } else if (s->ss->mode == MODE_ARPSCAN) { handle_arpoutput(ptr); } } else { MSG(M_ERR, "Unhandled message from `%s' drone message type `%s' with status %d", (c->type == DRONE_TYPE_SENDER ? "Sender" : "Listener"), strmsgtype(msg_type), status); } if (getret == 0) break; } /* multiple message read loop */ } /* readable fd */ } if (breakout) break; } if (s->verbose > 3) MSG(M_DBG1, "###### Waiting for listener packet timeout %d seconds", s->ss->recv_timeout); if (1) { unsigned int remain=s->ss->recv_timeout; while (1) { remain=sleep(remain); if (remain == 0) { break; } } } while (1) { uint32_t d_offset=0; int pret=0; for (c=s->dlh->head ; c != NULL ; c=c->next) { if (c->type != DRONE_TYPE_LISTENER) { if (s->verbose > 7) MSG(M_DBG2, "skipping drone type %d", c->type); continue; } if (c->status == DRONE_STATUS_DEAD) { if (s->verbose > 5) MSG(M_DBG2, "skipping dead drone type %d", c->type); continue; } if (c->status == DRONE_STATUS_READY && !(GET_LISTENDRONE())) { if (send_message(c->s, MSG_TERMINATE, MSG_STATUS_OK, NULL, 0) < 0) { MSG(M_ERR, "Can't tell listener to quit, this scan is useless"); mark_dead(c, DRONE_STATUS_DEAD); continue; } if (s->verbose > 6) MSG(M_DBG2, "Told listener on fd %d to go into reporting mode", c->s); c->status=DRONE_STATUS_WORKING; } } for (c=s->dlh->head, d_offset=0 ; c != NULL ; c=c->next, d_offset++) { spdf[d_offset].fd=c->s; } if (s->listeners && (pret=xpoll(&spdf[0], s->dlh->size, -1)) < 0) { MSG(M_ERR, "Poll drone fd's fail: %s", strerror(errno)); } for (c=s->dlh->head, d_offset=0 ; c != NULL ; c=c->next, d_offset++) { c->s_rw=0; if (c->status != DRONE_STATUS_DEAD) c->s_rw=spdf[d_offset].rw; if (spdf[d_offset].rw & XPOLL_READABLE) { if (s->verbose > 7) MSG(M_DBG1, "Socket type %s is readable", (c->type == DRONE_TYPE_LISTENER) ? "Listener" : "Sender"); } } for (c=s->dlh->head ; c != NULL ; c=c->next) { if (c->status != DRONE_STATUS_DEAD && c->status != DRONE_STATUS_DONE && c->s_rw & XPOLL_READABLE) { int getret=0; if (recv_messages(c->s) < 0) { MSG(M_ERR, "read fd %d fails, marking as dead", c->s); mark_dead(c, DRONE_STATUS_DEAD); continue; } while (1) { if (c->status == DRONE_STATUS_DONE || c->status == DRONE_STATUS_DEAD) break; getret=get_message(c->s, &msg_type, &status, &ptr, &msg_len); if (getret < 1) break; if (s->verbose > 5) MSG(M_DBG2, "Got message type `%s [%d]' from a Listener Drone with status %d and %p data", strmsgtype(msg_type), msg_type, status, ptr); if (msg_type == MSG_ERROR || status != MSG_STATUS_OK) { MSG(M_ERR, "Got bad message from listener on fd %d, marking as dead", c->s); mark_dead(c, DRONE_STATUS_DEAD); continue; } else if (msg_type == MSG_OUTPUT) { if (s->ss->mode == MODE_TCPSCAN || s->ss->mode == MODE_UDPSCAN) { if (msg_len < sizeof(ip_report_t)) { MSG(M_ERR, "Unknown report format from listener on fd %d", c->s); } else { handle_ipoutput(ptr); } } else if (s->ss->mode == MODE_ARPSCAN) { handle_arpoutput(ptr); } } else if (msg_type == MSG_QUIT) { mark_dead(c, DRONE_STATUS_DONE); } else { MSG(M_ERR, "Unknown message from listener %d on fd %d, marking as dead", msg_type, c->s); /* hrmm, welp i dont get this drone, lets stop talking to him */ mark_dead(c, DRONE_STATUS_DEAD); } if (getret == 0) break; } /* while messages are read */ } } /* for reading listeners */ if (s->listeners == 0) break; } if (s->ss->mode == MODE_UDPSCAN || s->ss->mode == MODE_TCPSCAN) { do_report(); } else if (s->ss->mode == MODE_ARPSCAN) { do_arpreport(); } }