int main(int argc, char ** argv) { char errbuf[PCAP_ERRBUF_SIZE], pfilter[2048]; pcap_t *pdev=NULL; bpf_u_int32 mask=0, net=0; struct bpf_program filter; ident=IDENT_ANY; ident_name_ptr=IDENT_ANY_NAME; memset(&conns, 0, sizeof(conns)); s=(settings_t *)xmalloc(sizeof(settings_t)); memset(s, 0, sizeof(settings_t)); s->vi=(interface_info_t **)xmalloc(sizeof(interface_info_t *)); s->vi[0]=(interface_info_t *)xmalloc(sizeof(interface_info_t)); memset(s->vi, 0, sizeof(interface_info_t)); s->ss=(scan_settings_t *)xmalloc(sizeof(scan_settings_t)); memset(s->ss, 0, sizeof(scan_settings_t)); s->verbose=3; s->_stdout=stdout; s->_stderr=stderr; if (argc == 2) { if (strcmp(argv[1], "-v") == 0) { verbose=1; } else { printf("%s: Sniff loopback device and decode ipc messages\n", argv[0]); exit(0); } } memset(errbuf, 0, sizeof(errbuf)); snprintf(pfilter, sizeof(pfilter) -1, "%s", FILTER); pcap_lookupnet("lo", &net, &mask, errbuf); pdev=pcap_open_live("lo", 16436, 1, 0, errbuf); if (pdev == NULL) { ERR("error: %s", errbuf); exit(1); } if ((header_len=util_getheadersize(pdev, errbuf)) < 0) { ERR("error getting header length: %s", errbuf); exit(1); } pcap_compile(pdev, &filter, pfilter, 0, net); pcap_setfilter(pdev, &filter); if (util_preparepcap(pdev, errbuf) < 0) { ERR("error putting pcap fd into immediate mode: %s", errbuf); exit(1); } pcap_loop(pdev, 0, &process_packet, NULL); exit(0); }
int main(int argc, char ** argv) { char errbuf[LIBNET_ERRBUF_SIZE]; char errors[PCAP_ERRBUF_SIZE], pfilter[2048]; struct ifreq ifr; bpf_u_int32 mask=0, net=0; int st=-1, tries=0; struct bpf_program filter; struct myetheraddr *e=NULL; pcap_t *pdev=NULL; memset(&ifr, 0, sizeof(ifr)); if (argc != 3) { printf("FantaIP by KIKI\nUsage: (example) %s eth0 192.168.13.211\n", argv[0]); exit(1); } bob.device=strdup(argv[1]); assert(bob.device != NULL); bob.saddr=(uint32_t)inet_addr(argv[2]); bob.addr_cleared=0; st=socket(AF_INET, SOCK_DGRAM, 0); if (st < 0) { fprintf(stderr, "create socket fails: %s", strerror(errno)); exit(1); } bob.l=libnet_init(LIBNET_LINK_ADV, bob.device, errbuf); if (bob.l == NULL) { fprintf(stderr, "libnet_init: %s\n", strerror(errno)); exit(1); } bob.arp=0; bob.eth=0; e=(struct myetheraddr *)libnet_get_hwaddr(bob.l); if (e == NULL) { perror("bad things batman"); exit(1); } memcpy(&bob.shwaddr, e, sizeof(bob.shwaddr)); snprintf(pfilter, sizeof(pfilter) -1, FILTER); memset(errors, 0, sizeof(errors)); pcap_lookupnet(bob.device, &net, &mask, errors); memset(errors, 0, sizeof(errors)); pdev=pcap_open_live(bob.device, 500, 1, 0, errors); if (util_getheadersize(pdev, errors) != 14) { fprintf(stderr, "You SURE this is an ethernet interface? doesnt look like one\n"); exit(1); } if (util_preparepcap(pdev, errors) < 0) { fprintf(stderr, "Can't prepare bpf socket: %s\n", strerror(errno)); exit(1); } pcap_compile(pdev, &filter, pfilter, 0, net); pcap_setfilter(pdev, &filter); /* look for dups */ if (pcap_setnonblock(pdev, 1, errors) < 0) { fprintf(stderr, "Can't set pcap dev nonblocking: %s\n", errors); exit(1); } bob.addr_cleared=0; while (bob.addr_cleared == 0 && tries < 3) { /* lets be sure about this ;] */ broadcast_arp(ARPOP_REQUEST, 0xFFFFFFFF); broadcast_arp(ARPOP_REQUEST, 0x00000000); broadcast_arp(ARPOP_REQUEST, bob.saddr); signal(SIGALRM, &alarm_hndlr); breakloop=0; alarm(1); while (1) { pcap_dispatch(pdev, -1, &process_packet, NULL); if (breakloop || bob.addr_cleared != 0) break; } alarm(0); signal(SIGALRM, SIG_DFL); tries++; } alarm(0); signal(SIGALRM, SIG_DFL); if (bob.addr_cleared == -1) { fprintf(stderr, "Error: Address already in use\n"); exit(1); } bob.addr_cleared=1; printf("arping for %s [", inet_ntoa(*((const struct in_addr *)&bob.saddr))); fflush(stdout); decode_mac(&bob.shwaddr.octet[0]); printf(" ]\n"); fflush(stdout); /* ok block now */ if (pcap_setnonblock(pdev, 0, errors) < 0) { fprintf(stderr, "Can't set pcap dev nonblocking: %s\n", errors); exit(1); } pcap_loop(pdev, 0, &process_packet, NULL); libnet_destroy(bob.l); exit(0); }
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); }