Exemple #1
0
// one sender thread
int send_run(sock_t st, shard_t *s)
{
	log_trace("send", "send thread started");
	pthread_mutex_lock(&send_mutex);
	// Allocate a buffer to hold the outgoing packet
	char buf[MAX_PACKET_SIZE];
	memset(buf, 0, MAX_PACKET_SIZE);

	// OS specific per-thread init
	if (send_run_init(st)) {
		return -1;
	}

	// MAC address length in characters
	char mac_buf[(ETHER_ADDR_LEN * 2) + (ETHER_ADDR_LEN - 1) + 1];
	char *p = mac_buf;
	for(int i=0; i < ETHER_ADDR_LEN; i++) {
		if (i == ETHER_ADDR_LEN-1) {
			snprintf(p, 3, "%.2x", zconf.hw_mac[i]);
			p += 2;
		} else {
			snprintf(p, 4, "%.2x:", zconf.hw_mac[i]);
			p += 3;
		}
	}
	log_debug("send", "source MAC address %s",
			mac_buf);
	void *probe_data;
	if (zconf.probe_module->thread_initialize) {
		zconf.probe_module->thread_initialize(buf, zconf.hw_mac, zconf.gw_mac,
					      zconf.target_port, &probe_data);
	}
	pthread_mutex_unlock(&send_mutex);

	// adaptive timing to hit target rate
	uint32_t count = 0;
	uint32_t last_count = count;
	double last_time = now();
	uint32_t delay = 0;
	int interval = 0;
	uint32_t max_targets = s->state.max_targets;
	volatile int vi;
	if (zconf.rate > 0) {
		// estimate initial rate
		delay = 10000;
		for (vi = delay; vi--; )
			;
		delay *= 1 / (now() - last_time) / (zconf.rate / zconf.senders);
		interval = (zconf.rate / zconf.senders) / 20;
		last_time = now();
	}
	uint32_t curr = shard_get_cur_ip(s);
	int attempts = zconf.num_retries + 1;
	uint32_t idx = 0;
	while (1) {
		// adaptive timing delay
		if (delay > 0) {
			count++;
			for (vi = delay; vi--; )
				;
			if (!interval || (count % interval == 0)) {
				double t = now();
				delay *= (double)(count - last_count)
					/ (t - last_time) / (zconf.rate / zconf.senders);
				if (delay < 1)
					delay = 1;
				last_count = count;
				last_time = t;
			}
		}
		if (zrecv.complete) {
			s->cb(s->id, s->arg);
			break;
		}
		if (s->state.sent >= max_targets) {
			s->cb(s->id, s->arg);
			break;
		}
		if (zconf.max_runtime && zconf.max_runtime <= now() - zsend.start) {
			s->cb(s->id, s->arg);
			break;
		}
		if (curr == 0) {
			s->cb(s->id, s->arg);
			break;
		}
		s->state.sent++;
		for (int i=0; i < zconf.packet_streams; i++) {
			uint32_t src_ip = get_src_ip(curr, i);

		  	uint32_t validation[VALIDATE_BYTES/sizeof(uint32_t)];
			validate_gen(src_ip, curr, (uint8_t *)validation);
			zconf.probe_module->make_packet(buf, src_ip, curr, validation, i, probe_data);

			if (zconf.dryrun) {
				lock_file(stdout);
				zconf.probe_module->print_packet(stdout, buf);
				unlock_file(stdout);
			} else {
				int length = zconf.probe_module->packet_length;
				void *contents = buf + zconf.send_ip_pkts*sizeof(struct ether_header);
				for (int i = 0; i < attempts; ++i) {
					int rc = send_packet(st, contents, length, idx);
					if (rc < 0) {
						struct in_addr addr;
						addr.s_addr = curr;
						log_debug("send", "send_packet failed for %s. %s",
								  inet_ntoa(addr), strerror(errno));
						s->state.failures++;
					} else {
						break;
					}
				}
				idx++;
				idx &= 0xFF;
			}
		}

		curr = shard_get_next_ip(s);
	}
	if (zconf.dryrun) {
		pthread_mutex_lock(&send_mutex);
		fflush(stdout);
		pthread_mutex_unlock(&send_mutex);
	}
	log_debug("send", "thread %hu finished", s->id);
	return EXIT_SUCCESS;
}
Exemple #2
0
int send_run(int sock)
#endif
{
	log_debug("send", "thread started");
	pthread_mutex_lock(&send_mutex);
#ifdef ZMAP_PCAP_INJECT
	/* Using pcap, mirror the linux SOCK_RAW behaviour as closely
	   as possible */
	unsigned char mac[ETHER_ADDR_LEN];
	struct in_addr src_ip = {0};
	//pcap_t *pc = get_pcap_t();
	/* We don't need the index; we have a pcap handle to the proper
	   interface */
	get_hwaddr(mac);
	get_ipaddr(&src_ip);

#else
	//int sock = get_socket();
	struct sockaddr_ll sockaddr;
	// get source interface index
	struct ifreq if_idx;
	memset(&if_idx, 0, sizeof(struct ifreq));
	if (strlen(zconf.iface) >= IFNAMSIZ) {
		log_error("send", "device interface name (%s) too long\n",
				zconf.iface);
		return -1;
	}
	strncpy(if_idx.ifr_name, zconf.iface, IFNAMSIZ-2);
	if (ioctl(sock, SIOCGIFINDEX, &if_idx) < 0) {
		perror("SIOCGIFINDEX");
		return -1;
	}
	int ifindex = if_idx.ifr_ifindex;
	// get source interface mac
	struct ifreq if_mac;
	memset(&if_mac, 0, sizeof(struct ifreq));
	strncpy(if_mac.ifr_name, zconf.iface, IFNAMSIZ-1);
	if (ioctl(sock, SIOCGIFHWADDR, &if_mac) < 0) {
		perror("SIOCGIFHWADDR");
		return -1;
	}
	// find source IP address associated with the dev from which we're sending.
	// while we won't use this address for sending packets, we need the address
	// to set certain socket options and it's easiest to just use the primary
	// address the OS believes is associated.
	struct ifreq if_ip;
	memset(&if_ip, 0, sizeof(struct ifreq));
	strncpy(if_ip.ifr_name, zconf.iface, IFNAMSIZ-1);
	if (ioctl(sock, SIOCGIFADDR, &if_ip) < 0) {
		perror("SIOCGIFADDR");
		return -1;
	}
	// wbk TODO: gateway MAC.
	// destination address for the socket
	memset((void*) &sockaddr, 0, sizeof(struct sockaddr_ll));
	sockaddr.sll_ifindex = ifindex;
	sockaddr.sll_halen = ETH_ALEN;
	memcpy(sockaddr.sll_addr, zconf.gw_mac, ETH_ALEN);

#endif /* not ZMAP_PCAP_INJECT */ /* may move down... TODO wbk */

	char buf[MAX_PACKET_SIZE];
	memset(buf, 0, MAX_PACKET_SIZE);
	zconf.probe_module->thread_initialize(buf, 
#ifdef ZMAP_PCAP_INJECT
					mac,
#else
					(unsigned char *)if_mac.ifr_hwaddr.sa_data, 
#endif
					zconf.gw_mac, zconf.target_port);	
	pthread_mutex_unlock(&send_mutex);

	// adaptive timing to hit target rate
	uint32_t count = 0;
	uint32_t last_count = count;
	double last_time = now();
	uint32_t delay = 0;
	int interval = 0;
	volatile int vi;
	if (zconf.rate > 0) {
		// estimate initial rate
		delay = 10000;
		for (vi = delay; vi--; )
			;
		delay *= 1 / (now() - last_time) / (zconf.rate / zconf.senders);
		interval = (zconf.rate / zconf.senders) / 20;
		last_time = now();
	}
	while (1) {
		// adaptive timing delay
		if (delay > 0) {
			count++;
			for (vi = delay; vi--; )
				;
			if (!interval || (count % interval == 0)) {
				double t = now();
				delay *= (double)(count - last_count) 
					/ (t - last_time) / (zconf.rate / zconf.senders);
				if (delay < 1)
					delay = 1;
				last_count = count;
				last_time = t;
			}
		}
		// generate next ip from cyclic group and update global state
		// (everything locked happens here)
		pthread_mutex_lock(&send_mutex);
		if (zsend.complete) {
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		if (zsend.sent >= zconf.max_targets) {
			zsend.complete = 1;
			zsend.finish = now();
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		if (zconf.max_runtime && zconf.max_runtime <= now() - zsend.start) {
			zsend.complete = 1;
			zsend.finish = now();
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		uint32_t curr = cyclic_get_next_ip();
		if (curr == zsend.first_scanned) {
			zsend.complete = 1;
			zsend.finish = now();
		}
		zsend.sent++;
		pthread_mutex_unlock(&send_mutex);
		for (int i=0; i < zconf.packet_streams; i++) {
			uint32_t src_ip = get_src_ip(curr, i);

		  	uint32_t validation[VALIDATE_BYTES/sizeof(uint32_t)];
			validate_gen(src_ip, curr, (uint8_t *)validation);
			zconf.probe_module->make_packet(buf, src_ip, curr, validation, i);

			if (zconf.dryrun) {
				zconf.probe_module->print_packet(stdout, buf);
			} else {
					int l = zconf.probe_module->packet_length;

#ifdef ZMAP_PCAP_INJECT
					int rc = pcap_inject(pc, buf, (size_t)l);
					if (rc == -1) {
						struct in_addr addr;
						addr.s_addr = curr;
						log_fatal("send", "pcap_inject() failed for %s. %s", /* TODO: make log_debug */
								  inet_ntoa(addr), strerror(errno));
						pthread_mutex_lock(&send_mutex);
						zsend.sendto_failures++;
						pthread_mutex_unlock(&send_mutex);
					}
#else /* TODO: error handling can be shared. */
					int rc = sendto(sock, buf + zconf.send_ip_pkts*sizeof(struct ethhdr),
							l, 0,
							(struct sockaddr *)&sockaddr,
							sizeof(struct sockaddr_ll));
					if (rc < 0) {
						struct in_addr addr;
						addr.s_addr = curr;
						log_debug("send", "sendto failed for %s. %s",
								  inet_ntoa(addr), strerror(errno));
						pthread_mutex_lock(&send_mutex);
						zsend.sendto_failures++;
						pthread_mutex_unlock(&send_mutex);
					}
#endif
			}
		}
	}
	log_debug("send", "thread finished");
	return EXIT_SUCCESS;
}
Exemple #3
0
// one sender thread
int send_run(int sock)
{
	log_trace("send", "send thread started");
	pthread_mutex_lock(&send_mutex);

	// Allocate a buffer to hold the outgoing packet
	char buf[MAX_PACKET_SIZE];
	memset(buf, 0, MAX_PACKET_SIZE);

	// OS specific per-thread init
	if (send_run_init(sock)) {
		return -1;
	}

	// Get the source hardware address, and give it to the probe
	// module
	if (get_iface_hw_addr(zconf.iface, zconf.hw_mac)) {
		log_fatal("send", "could not retrieve hardware address for"
			  "interface: %s", zconf.iface);
		return -1;
	}
	char mac_buf[(ETHER_ADDR_LEN * 2) + (ETHER_ADDR_LEN - 1) + 1];
	char *p = mac_buf;
	for(int i=0; i < ETHER_ADDR_LEN; i++) {
		if (i == ETHER_ADDR_LEN-1) {
			snprintf(p, 3, "%.2x", zconf.hw_mac[i]);
			p += 2;
		} else {
			snprintf(p, 4, "%.2x:", zconf.hw_mac[i]);
			p += 3;
		}
	}
	log_debug("send", "source MAC address %s",
			mac_buf);

	zconf.probe_module->thread_initialize(buf, zconf.hw_mac, zconf.gw_mac,
					      zconf.target_port);
	pthread_mutex_unlock(&send_mutex);
	
	// adaptive timing to hit target rate
	uint32_t count = 0;
	uint32_t last_count = count;
	double last_time = now();
	uint32_t delay = 0;
	int interval = 0;
	volatile int vi;
	if (zconf.rate > 0) {
		// estimate initial rate
		delay = 10000;
		for (vi = delay; vi--; )
			;
		delay *= 1 / (now() - last_time) / (zconf.rate / zconf.senders);
		interval = (zconf.rate / zconf.senders) / 20;
		last_time = now();
	}
	while (1) {
		// adaptive timing delay
		if (delay > 0) {
			count++;
			for (vi = delay; vi--; )
				;
			if (!interval || (count % interval == 0)) {
				double t = now();
				delay *= (double)(count - last_count) 
					/ (t - last_time) / (zconf.rate / zconf.senders);
				if (delay < 1)
					delay = 1;
				last_count = count;
				last_time = t;
			}
		}
		// generate next ip from cyclic group and update global state
		// (everything locked happens here)
		pthread_mutex_lock(&send_mutex);
		if (zsend.complete) {
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		if (zsend.sent >= zconf.max_targets) {
			zsend.complete = 1;
			zsend.finish = now();
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		if (zconf.max_runtime && zconf.max_runtime <= now() - zsend.start) {
			zsend.complete = 1;
			zsend.finish = now();
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		uint32_t curr = cyclic_get_next_ip(c);
		if (curr == zsend.first_scanned) {
			zsend.complete = 1;
			zsend.finish = now();
		}
		zsend.sent++;
		pthread_mutex_unlock(&send_mutex);
		for (int i=0; i < zconf.packet_streams; i++) {
			uint32_t src_ip = get_src_ip(curr, i);

		  	uint32_t validation[VALIDATE_BYTES/sizeof(uint32_t)];
			validate_gen(src_ip, curr, (uint8_t *)validation);
			zconf.probe_module->make_packet(buf, src_ip, curr, validation, i);

			if (zconf.dryrun) {
				zconf.probe_module->print_packet(stdout, buf);
			} else {
				int length = zconf.probe_module->packet_length;
				void *contents = buf + zconf.send_ip_pkts*sizeof(struct ether_header);
				int rc = send_packet(sock, contents, length);
				if (rc < 0) {
					struct in_addr addr;
					addr.s_addr = curr;
					log_debug("send", "send_packet failed for %s. %s",
							  inet_ntoa(addr), strerror(errno));
					pthread_mutex_lock(&send_mutex);
					zsend.sendto_failures++;
					pthread_mutex_unlock(&send_mutex);
				}
			}
		}
	}
	cyclic_free(c);
	log_debug("send", "thread finished");
	return EXIT_SUCCESS;
}
Exemple #4
0
Fichier : send.c Projet : Gank/zmap
// one sender thread
int send_run(void)
{
	log_debug("send", "thread started");
	pthread_mutex_lock(&send_mutex);
	int sock = get_socket();
	struct sockaddr_ll sockaddr;
	// get source interface index
	struct ifreq if_idx;
	memset(&if_idx, 0, sizeof(struct ifreq));
	if (strlen(zconf.iface) >= IFNAMSIZ) {
		log_error("send", "device interface name (%s) too long\n",
				zconf.iface);
		return -1;
	}
	strncpy(if_idx.ifr_name, zconf.iface, IFNAMSIZ-1);
	if (ioctl(sock, SIOCGIFINDEX, &if_idx) < 0) {
		perror("SIOCGIFINDEX");
		return -1;
	}
	int ifindex = if_idx.ifr_ifindex;
	// get source interface mac
	struct ifreq if_mac;
	memset(&if_mac, 0, sizeof(struct ifreq));
	strncpy(if_mac.ifr_name, zconf.iface, IFNAMSIZ-1);
	if (ioctl(sock, SIOCGIFHWADDR, &if_mac) < 0) {
		perror("SIOCGIFHWADDR");
		return -1;
	}
	// find source IP address associated with the dev from which we're sending.
	// while we won't use this address for sending packets, we need the address
	// to set certain socket options and it's easiest to just use the primary
	// address the OS believes is associated.
	struct ifreq if_ip;
	memset(&if_ip, 0, sizeof(struct ifreq));
	strncpy(if_ip.ifr_name, zconf.iface, IFNAMSIZ-1);
	if (ioctl(sock, SIOCGIFADDR, &if_ip) < 0) {
		perror("SIOCGIFADDR");
		return -1;
	}
	// destination address for the socket
	memset((void*) &sockaddr, 0, sizeof(struct sockaddr_ll));
	sockaddr.sll_ifindex = ifindex;
	sockaddr.sll_halen = ETH_ALEN;
	memcpy(sockaddr.sll_addr, zconf.gw_mac, ETH_ALEN);

	char buf[MAX_PACKET_SIZE];
	memset(buf, 0, MAX_PACKET_SIZE);
	zconf.probe_module->thread_initialize(buf, 
					(unsigned char *)if_mac.ifr_hwaddr.sa_data, 
					zconf.gw_mac, zconf.target_port);	
	pthread_mutex_unlock(&send_mutex);

	// adaptive timing to hit target rate
	uint32_t count = 0;
	uint32_t last_count = count;
	double last_time = now();
	uint32_t delay = 0;
	int interval = 0;
	volatile int vi;
	if (zconf.rate > 0) {
		// estimate initial rate
		delay = 10000;
		for (vi = delay; vi--; )
			;
		delay *= 1 / (now() - last_time) / (zconf.rate / zconf.senders);
		interval = (zconf.rate / zconf.senders) / 20;
		last_time = now();
	}
	while (1) {
		// adaptive timing delay
		if (delay > 0) {
			count++;
			for (vi = delay; vi--; )
				;
			if (!interval || (count % interval == 0)) {
				double t = now();
				delay *= (double)(count - last_count) 
					/ (t - last_time) / (zconf.rate / zconf.senders);
				if (delay < 1)
					delay = 1;
				last_count = count;
				last_time = t;
			}
		}
		// generate next ip from cyclic group and update global state
		// (everything locked happens here)
		pthread_mutex_lock(&send_mutex);
		if (zsend.complete) {
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		if (zsend.sent >= zconf.max_targets) {
			zsend.complete = 1;
			zsend.finish = now();
			pthread_mutex_unlock(&send_mutex);
			break;
		}
		if (zconf.max_runtime && zconf.max_runtime <= now() - zsend.start) {
			zsend.complete = 1;
			zsend.finish = now();
			pthread_mutex_unlock(&send_mutex);
			break;
		}

		uint32_t curr;



		//if has CIDR
		if(zconf.cidr != '\0'){

			//Get next IP and convert to correct format
			// uint32_t val = zsend.first_scanned++;
			curr = cidr_get_next_ip();

			if (zsend.last_to_scan == 1) {
				zsend.complete = 1;
				zsend.finish = now();
			}
		}
		else{
			curr = cyclic_get_next_ip();

			if (curr == zsend.first_scanned) {
				zsend.complete = 1;
				zsend.finish = now();
			}
		}

		zsend.sent++;
		pthread_mutex_unlock(&send_mutex);
		for (int i=0; i < zconf.packet_streams; i++) {
			uint32_t src_ip = get_src_ip(curr, i);

		  	uint32_t validation[VALIDATE_BYTES/sizeof(uint32_t)];
			validate_gen(src_ip, curr, (uint8_t *)validation);
			zconf.probe_module->make_packet(buf, src_ip, curr, validation, i);

			if (zconf.dryrun) {
				zconf.probe_module->print_packet(stdout, buf);
			} else {
					int l = zconf.probe_module->packet_length;
					int rc = sendto(sock, buf, 
							l, 0,
							(struct sockaddr *)&sockaddr,
							sizeof(struct sockaddr_ll));
					if (rc < 0) {
						struct in_addr addr;
						addr.s_addr = curr;
						log_debug("send", "sendto failed for %s. %s",
								  inet_ntoa(addr), strerror(errno));
						pthread_mutex_lock(&send_mutex);
						zsend.sendto_failures++;
						pthread_mutex_unlock(&send_mutex);
					}
			}
		}
	}
	log_debug("send", "thread finished");
	return EXIT_SUCCESS;
}
Exemple #5
0
void handle_packet(uint32_t buflen, const u_char *bytes) {
	if ((sizeof(struct ip) + (zconf.send_ip_pkts ? 0 : sizeof(struct ether_header))) > buflen) {
		// buffer not large enough to contain ethernet
		// and ip headers. further action would overrun buf
		return;
	}
	struct ip *ip_hdr = (struct ip *) &bytes[(zconf.send_ip_pkts ? 0 : sizeof(struct ether_header))];

	uint32_t src_ip = ip_hdr->ip_src.s_addr;

	uint32_t validation[VALIDATE_BYTES/sizeof(uint8_t)];
	// TODO: for TTL exceeded messages, ip_hdr->saddr is going to be different
	// and we must calculate off potential payload message instead
	validate_gen(ip_hdr->ip_dst.s_addr, ip_hdr->ip_src.s_addr, (uint8_t *) validation);

	if (!zconf.probe_module->validate_packet(ip_hdr, buflen - (zconf.send_ip_pkts ? 0 : sizeof(struct ether_header)),
				&src_ip, validation)) {
		return;
	}

	int is_repeat = pbm_check(seen, ntohl(src_ip));

	//HACK vgiannin for multiple port
	is_repeat=0;

	fieldset_t *fs = fs_new_fieldset();

	//struct tcphdr *tcp = (struct tcphdr*)((char *) ip_hdr + 4*ip_hdr->ip_hl);
	//uint16_t sport = ntohs(tcp->th_sport);
	//printf("port : %d\n",sport);
	// char line[50];
	// struct in_addr t;
	// t.s_addr = ip_hdr->ip_src.s_addr;
	// const char *temp = inet_ntoa(t);
	// sprintf(line,"%s:%d",temp,sport);
	//printf("%s\n",line );


	fs_add_ip_fields(fs, ip_hdr);
	// HACK:
	// probe modules (for whatever reason) expect the full ethernet frame
	// in process_packet. For VPN, we only get back an IP frame.
	// Here, we fake an ethernet frame (which is initialized to
	// have ETH_P_IP proto and 00s for dest/src).
	if (zconf.send_ip_pkts) {
		if (buflen > sizeof(fake_eth_hdr)) {
			buflen = sizeof(fake_eth_hdr);
		}
		memcpy(&fake_eth_hdr[sizeof(struct ether_header)], bytes, buflen);
		bytes = fake_eth_hdr;
	}
	zconf.probe_module->process_packet(bytes, buflen, fs);
	fs_add_system_fields(fs, is_repeat, zsend.complete);
	int success_index = zconf.fsconf.success_index;
	assert(success_index < fs->len);
	int is_success = fs_get_uint64_by_index(fs, success_index);

	if (is_success) {
		zrecv.success_total++;
		if (!is_repeat) {
			zrecv.success_unique++;
			pbm_set(seen, ntohl(src_ip));
		}
		if (zsend.complete) {
			zrecv.cooldown_total++;
			if (!is_repeat) {
				zrecv.cooldown_unique++;
			}
		}
	} else {
		zrecv.failure_total++;
	}
	// probe module includes app_success field
	if (zconf.fsconf.app_success_index >= 0) {
		int is_app_success = fs_get_uint64_by_index(fs,
				zconf.fsconf.app_success_index);
		if (is_app_success) {
			zrecv.app_success_total++;
			if (!is_repeat) {
				zrecv.app_success_unique++;
			}
		}
	}

	fieldset_t *o = NULL;
	// we need to translate the data provided by the probe module
	// into a fieldset that can be used by the output module
	if (!is_success && zconf.filter_unsuccessful) {
		goto cleanup;
	}
	if (is_repeat && zconf.filter_duplicates) {
		goto cleanup;
	}
	if (!evaluate_expression(zconf.filter.expression, fs)) {
		goto cleanup;
	}
	o = translate_fieldset(fs, &zconf.fsconf.translation);
	if (zconf.output_module && zconf.output_module->process_ip) {
		zconf.output_module->process_ip(o);
	}
cleanup:
	fs_free(fs);
	free(o);
	if (zconf.output_module && zconf.output_module->update
			&& !(zrecv.success_unique % zconf.output_module->update_interval)) {
		zconf.output_module->update(&zconf, &zsend, &zrecv);
	}
}