コード例 #1
0
ファイル: unicycle.c プロジェクト: IFGHou/Unicornscan
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);
}
コード例 #2
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);
}
コード例 #3
0
ファイル: recv_packet.c プロジェクト: IFGHou/Unicornscan
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);
}