示例#1
0
文件: neighbor.c 项目: hgn/ospfd
int neighbor_start_inactive_timer(struct ospfd *ospfd,
		struct interface_data *i, struct neighbor *neighbor)
{
	int ret;
	struct inactivity_timer_data *inactivity_timer_data;
	/* FIXME: hardcoded time-out */
	struct timespec timespec = { 10, 0 };
	struct ev_entry *ev_entry;

	msg(ospfd, DEBUG, "prepare inactive timer for neighbor");

	inactivity_timer_data = xzalloc(sizeof(struct inactivity_timer_data));
	inactivity_timer_data->ospfd    = ospfd;
	inactivity_timer_data->neighbor = neighbor;
	inactivity_timer_data->interface_data = i;

	neighbor->inactivity_timer_data = inactivity_timer_data;

	ev_entry = ev_timer_new(&timespec, neighbor_inactive_timer_expired,
			inactivity_timer_data);
	if (!ev_entry) {
		err_msg_die(EXIT_FAILURE, "Cannot initialize a new timer");
	}

	inactivity_timer_data->neighbor->inactive_timer_entry = ev_entry;

	ret = ev_add(ospfd->ev, ev_entry);
	if (ret != EV_SUCCESS) {
		err_msg_die(EXIT_FAILURE, "Cannot add new timer to global event handler");
	}

	return SUCCESS;
}
示例#2
0
文件: ospfd.c 项目: hgn/ospfd
int main(int ac, char **av)
{
	int ret;
	struct ospfd *ospfd;
	int ev_flags = 0;

	ospfd = alloc_ospfd();

	ret = parse_cli_options(ospfd, ac, av);
	if (ret != SUCCESS)
		err_msg_die(EXIT_FAILURE, "Can't parse command line");

	msg(ospfd, GENTLE, PROGRAMNAME " - " VERSIONSTRING);

	/* seed pseudo number randon generator */
	init_pnrg(ospfd);

	/* initialize event subsystem. In this case this belongs
	 * to open a epoll filedescriptor */
	ospfd->ev = ev_new();
	if (!ospfd->ev)
		err_msg_die(EXIT_FAILURE, "Can't initialize event subsystem");


	ret = parse_rc_file(ospfd);
	if (ret != SUCCESS)
		err_msg_die(EXIT_FAILURE, "Can't parse configuration file");


	ret = init_network(ospfd);
	if (ret != SUCCESS)
		err_msg_die(EXIT_FAILURE, "Can't initialize network subsystem");

	/* and branch into the main loop
	 * This loop will never return (with the exception of SIGINT or failure
	 * condition) */
	ret = ev_loop(ospfd->ev, ev_flags);
	if (ret != SUCCESS)
		err_msg_die(EXIT_FAILURE, "Main loop returned unexpected - exiting now");


	fini_network(ospfd);
	free_options(ospfd);
	ev_free(ospfd->ev);
	free_ospfd(ospfd);

	return EXIT_SUCCESS;
}
示例#3
0
static void dump_tcp_opt(struct opts *optsp)
{

	switch (optsp->workmode) {
		case MODE_TRANSMIT:
			fprintf(stdout, "# workmode: transmit\n");
			fprintf(stdout, "# destination host: %s\n", optsp->hostname);
			fprintf(stdout, "# filename: %s\n", optsp->infile);
			break;
		case MODE_RECEIVE:
			fprintf(stdout, "# workmode: receive\n");
			break;
		default:
			err_msg_die(EXIT_FAILMISC, "Programmed Failure");
			break;
	};

	if (optsp->perform_rtt_probe) {
		fprintf(stdout, "# perform rtt probe: true\n");
	} else {
		fprintf(stdout, "# perform rtt probe: false\n");
	}


}
示例#4
0
/* probe_rtt read a rtt probe packet, set nse_nxt_hdr to zero,
** nse_len to the current packet size and send it back to origin
*/
static int
process_rtt_probe(int peer_fd, uint16_t nse_len)
{
	int ret = 0; uint16_t *intptr;
	struct ns_rtt_probe *ns_rtt_probe_ptr;
	char buf[nse_len * 4 + 4];
	ssize_t to_read = nse_len * 4;


	if (readn(peer_fd, buf + 4, to_read) != to_read)
		return -1;

	ns_rtt_probe_ptr = (struct ns_rtt_probe *) buf;

	msg(STRESSFUL, "process rtt probe (sequence: %d, type: %d packet_size: %d)",
			ntohs(ns_rtt_probe_ptr->seq_no), ntohs(ns_rtt_probe_ptr->type), to_read);

	ns_rtt_probe_ptr->type = htons(RTT_REPLY_TYPE);

	intptr = (uint16_t *)buf;
	*intptr = 0;

	intptr = (uint16_t *)buf + sizeof(uint16_t);
	*intptr = htons(nse_len);

	if (writen(peer_fd, buf, to_read + 4) != to_read + 4)
		err_msg_die(EXIT_FAILHEADER, "Can't reply to rtt probe!\n");

	return ret;
}
示例#5
0
/* get_sock_opts() appoint some socket specific
** values for further use ... (hopefully ;-)
** Values are determined by hand for the possibility
** to change something
** We should call this function after socket creation
** and at the and off our transmit/receive phase
**   --HGN
*/
int
get_sock_opts(int fd, struct net_stat *ns)
{
	int ret;

	if (opts.family != AF_INET && opts.family != AF_INET6)
		return 0;

	ret = get_ip_sock_opts(fd, ns);
	if (ret != 0) {
		return ret;
	}

	switch (opts.protocol) {
		case IPPROTO_TCP:
			return get_tcp_sock_opts(fd, ns);
			break;
		case IPPROTO_UDP:
		case IPPROTO_UDPLITE:
		case IPPROTO_DCCP:
		case IPPROTO_SCTP:
			return 0;
		default:
			err_msg_die(EXIT_FAILMISC, "Programmed Failure");
	}

	return 0;
}
示例#6
0
static int parse_sctp_opt(int ac, char *av[],struct opts *optsp)
{

	/* memorize protocol */
	optsp->ns_proto = NS_PROTO_SCTP;

	optsp->perform_rtt_probe = 1;
	optsp->protocol = IPPROTO_SCTP;
	optsp->socktype = SOCK_STREAM;

	/* this do/while loop parse options in the form '-x'.
	 * After the do/while loop the parse fork into transmit,
	 * receive specific code.
	 */
	for (;;) {
#define	FIRST_ARG_INDEX 0
		/* break if we reach the end of the OPTIONS */
		if (!av[FIRST_ARG_INDEX] || av[FIRST_ARG_INDEX][0] != '-')
			break;

		if (!av[FIRST_ARG_INDEX][1] || !isalnum(av[FIRST_ARG_INDEX][1]))
			print_usage(NULL, HELP_STR_TCP, 1);
	}
#undef FIRST_ARG_INDEX

	switch (optsp->workmode) {
	case MODE_TRANSMIT:
		/* sanity check first */
		if (ac <= 1)
			print_usage("sctp transmit mode requires file and destination address\n",
				HELP_STR_SCTP, 1);

		optsp->infile = xstrdup(av[0]);
		optsp->hostname = xstrdup(av[1]);
	break;
	case MODE_RECEIVE:
		switch (ac) {
		case 0: /* nothing to do */
			break;
		case 2:
			opts.hostname = xstrdup(av[1]);
			/* fallthrough */
		case 1:
			opts.outfile = xstrdup(av[0]);
			break;
		default:
			err_msg("You specify to many arguments!");
			print_usage(NULL, HELP_STR_GLOBAL, 1);
			break;
		};
		break;
	default:
		err_msg_die(EXIT_FAILINT,
				"Internal, programmed error - unknown tranmit mode: %d\n",
				optsp->workmode);
	}
	return SUCCESS;
}
示例#7
0
static void
timout_handler(int sig_no)
{
	if (sig_no != SIGALRM)
		err_msg_die(EXIT_FAILINT, "Programmed error (received an unknow signal)");

	alarm(TIMEOUT_SEC);

	msg(STRESSFUL, "timout occure while wait for rtt probe response");
}
示例#8
0
文件: neighbor.c 项目: hgn/ospfd
int process_state_init_to_new_state(struct ospfd *o, struct interface_data *i,
		struct neighbor *n, int s)
{
	switch (s) {
		case NEIGHBOR_EV_HELLO_RECEIVED:
			return process_state_init_ev_hello_received(o, i, n, s);
			break;
		default:
			err_msg_die(EXIT_FAILURE, "State no handled: %s:%d",
					__FILE__, __LINE__);
			break;
	}

	/* should not happened - to shut-up gcc warnings */
	return FAILURE;
}
示例#9
0
文件: neighbor.c 项目: hgn/ospfd
int neighbor_process_event(struct ospfd *ospfd, struct interface_data *interface_data,
		struct neighbor *neighbor, int event)
{
	switch (neighbor->state) {
		case NEIGHBOR_STATE_DOWN:
			return process_state_down_to_new_state(ospfd, interface_data, neighbor, event);
			break;
		case NEIGHBOR_STATE_INIT:
			return process_state_init_to_new_state(ospfd, interface_data, neighbor, event);
			break;
		case NEIGHBOR_STATE_ATTEMPT:
		case NEIGHBOR_STATE_TWO_WAY:
		case NEIGHBOR_STATE_EX_START:
		case NEIGHBOR_STATE_EXCHANGE:
		case NEIGHBOR_STATE_LOADING:
		case NEIGHBOR_STATE_FULL:
		default:
			err_msg_die(EXIT_FAILURE, "Programmed error in switch/case statement: "
					"state (%d) not known or not handled", neighbor->state);
			break;
	};

	return FAILURE;
}
示例#10
0
/* parse_tcp_opt set all tcp default values
 * within optsp and parse all tcp related options
 * ac is the number of arguments from MODE and av is
 * the correspond pointer into the array vector. We parse all tcp
 * related options first and within the switch/case statement we handle
 * transmit | receive specific options.
 */
static int parse_tcp_opt(int ac, char *av[], struct opts *optsp)
{

	/* memorize protocol */
	optsp->ns_proto = NS_PROTO_TCP;

	/* tcp has some default values too, set them here */
	optsp->perform_rtt_probe = 1;
	optsp->protocol = IPPROTO_TCP;
	optsp->socktype = SOCK_STREAM;

	while (av[0] && av[0][0] == '-') {
		if (av[0][1] == 'C')
			optsp->tcp_use_md5sig = true;

		if (optsp->workmode == MODE_RECEIVE) {
			/* need peer ip address */
			if (!av[1] || av[1][0] == '-')
				err_msg_die(EXIT_FAILOPT, "Option -C needs an argument (Peer IP Address)");
			optsp->tcp_md5sig_peeraddr = av[1];
			ac--;
			av++;
		}
		ac--;
		av++;
	}

	if (optsp->tcp_use_md5sig)
		msg(GENTLE, "Enabled TCP_MD5SIG option");
	/* Now parse all transmit | receive specific code, plus the most
	 * important options: the file- and hostname
	 */
	switch (optsp->workmode) {
		case MODE_TRANSMIT:
			/* sanity check first */
			if (ac <= 1)
				print_usage("tcp transmit mode required file and destination address\n",
						HELP_STR_GLOBAL, 1);

			optsp->infile = xstrdup(av[0]);
			optsp->hostname = xstrdup(av[1]);

			break;
		case MODE_RECEIVE:
			switch (ac) {
				case 0: /* nothing to do */
					break;

				case 2:
					opts.hostname = xstrdup(av[1]);
					/* fallthrough */
				case 1:
					opts.outfile = xstrdup(av[0]);
					break;
				default:
					err_msg("You specify to many arguments!");
					print_usage(NULL, HELP_STR_GLOBAL, 1);
					break;
			};

			break;
		default:
			err_msg_die(EXIT_FAILINT,
					"Internal, programmed error - unknown tranmit mode: %d\n",
					optsp->workmode);
	}

	return SUCCESS;
}
示例#11
0
文件: neighbor.c 项目: hgn/ospfd
void process_state_full_to_new_state(struct ospfd *ospfd,
		struct neighbor *neighbor, int new_state)
{
	err_msg_die(EXIT_FAILURE, "State handling not yet implemented: %s:%d",
			__FILE__, __LINE__);
}
示例#12
0
/* This is the plan:
** send n rtt packets into the wire and wait until all n reply packets
** arrived. If a timeout occur we count this packet as lost
*/
static int
probe_rtt(int peer_fd, int next_hdr, int probe_no, uint16_t backing_data_size)
{
	int i, j, current_next_hdr;
	double rtt_ms[probe_no + 1], deviation = 0, covariance = 0;
	double d_tmp = 0;
	uint16_t packet_len; ssize_t to_write;
	char rtt_buf[backing_data_size + sizeof(struct ns_rtt_probe)];
	struct ns_rtt_probe *ns_rtt_probe = (struct ns_rtt_probe *) rtt_buf;
	char *data_ptr = rtt_buf + sizeof(struct ns_rtt_probe);

	if (probe_no <= 0)
		err_msg_die(EXIT_FAILINT, "Programmed Failure");

	memset(ns_rtt_probe, 0, sizeof(struct ns_rtt_probe));
	memset(data_ptr, 'A', backing_data_size);

	/* packet backing data MUST a multiple of four */
	packet_len = ((uint16_t)(backing_data_size / 4)) * 4;
	to_write = packet_len + sizeof(struct ns_rtt_probe);

	/* we announce packetsize in 4 byte slices (32bit)
	** minus nse_nxt_hdr and nse_len header (4 byte)
	*/
	ns_rtt_probe->nse_len = htons((to_write - 4) / 4);

	ns_rtt_probe->ident = htons(getpid() & 0xffff);

	current_next_hdr = NSE_NXT_RTT_PROBE;

	/* FIXME:
	** The first rtt probe packet had nearly a rtt of additional
	** 200ms. So we ignore the first packet silently and calculate
	** rtt and variation. I think this increased measurement is caused
	** by "cold code paths"[TM], but these is to validate.
	*/
	for (i = 0; i <= probe_no; ) {

		char reply_buf[to_write];
		struct ns_rtt_probe *ns_rtt_reply;
		ssize_t to_read = to_write;
		struct timeval tv, tv_tmp, tv_res;

		if (i++ >= probe_no)
			current_next_hdr = next_hdr;

		ns_rtt_probe->nse_nxt_hdr = htons(current_next_hdr);
		ns_rtt_probe->type = (htons((uint16_t)RTT_REQUEST_TYPE));
		ns_rtt_probe->seq_no = htons(i);

		/* set timeval for packet */
		if (gettimeofday(&tv, NULL) != 0)
			err_sys("Can't call gettimeofday");

		ns_rtt_probe->sec = htonl(tv.tv_sec);
		ns_rtt_probe->usec = htonl(tv.tv_usec);

		/* transmitt rtt probe ... */
		if (writen(peer_fd, ns_rtt_probe, to_write) != to_write)
			err_msg_die(EXIT_FAILHEADER, "Can't send rtt extension header!\n");

		/* ... and receive probe */
		if (readn(peer_fd, reply_buf, to_read) != to_read)
			return -1;

		if (gettimeofday(&tv, NULL) != 0)
			err_sys("Can't call gettimeofday");

		ns_rtt_reply = (struct ns_rtt_probe *) reply_buf;

		tv_tmp.tv_sec = ntohl(ns_rtt_reply->sec);
		tv_tmp.tv_usec = ntohl(ns_rtt_reply->usec);

		subtime(&tv_tmp, &tv, &tv_res);

		/* sanity check (ident) */
		if (ntohs(ns_rtt_reply->ident) != (getpid() & 0xffff))
			err_msg("received a unknown rtt probe reply (ident  should: %d is: %d)",
					ntohs(ns_rtt_reply->ident),  (getpid() & 0xffff));

		/* XXX: if you change something here, then check all counter
		** variables, etc
		*/
		if (i == 1)
			continue;

		rtt_ms[i - 2] = (tv_res.tv_sec * 1000) + ((double)tv_res.tv_usec / 1000);

		msg(STRESSFUL, "receive rtt reply probe (sequence: %d, len %d, rtt: %.3fms)",
				ntohs(ns_rtt_reply->seq_no), to_read, rtt_ms[i - 2]);

	}

	/* average */
	for (j = 0; j < probe_no; j++)
		net_stat.rtt_probe.usec += rtt_ms[j];

	net_stat.rtt_probe.usec /= --j;

	/* ... covariance and standard deviation */
	for (j = 0; j < probe_no; j++)
		covariance += pow(rtt_ms[j] - net_stat.rtt_probe.usec, 2);

	covariance /= --j;
	deviation = sqrt(covariance);

	d_tmp = 0;

	/* low and high pass deviation based filter, calculates new rtt average */
	for (j = 0, i = 0; j < probe_no; j++) {

		if (((rtt_ms[j] > net_stat.rtt_probe.usec) &&
			(rtt_ms[j] < (net_stat.rtt_probe.usec +
				(deviation * opts.rtt_probe_opt.deviation_filter)))) ||
		   ((rtt_ms[j] < net_stat.rtt_probe.usec) &&
			(rtt_ms[j] > (net_stat.rtt_probe.usec -
				(deviation * opts.rtt_probe_opt.deviation_filter))))) {
			d_tmp += rtt_ms[j];
			++i;
		}
	}
	net_stat.rtt_probe.usec = d_tmp / i;

	msg(LOUDISH, "average rtt: %.3fms (after filter), covariance: %.3fms^2, standard deviation %.3fms",
			net_stat.rtt_probe.usec, covariance, deviation);

	return 0;
}
示例#13
0
/* return -1 if a failure occure, zero apart from that */
int
meta_exchange_rcv(int peer_fd, struct peer_header_info **hi)
{
	int ret;
	int invalid_ext_seen = 0;
	uint16_t extension_type, extension_size;
	struct peer_header_info *phi;
	unsigned char *ptr;
	ssize_t rc = 0, to_read = sizeof(struct ns_hdr);
	struct ns_hdr ns_hdr;

	memset(&ns_hdr, 0, sizeof(struct ns_hdr));

	/* allocate info header */
	phi = xzalloc(sizeof(struct peer_header_info));
	*hi = phi;

	ptr = (unsigned char *) &ns_hdr;

	msg(STRESSFUL, "fetch general header (%d byte)", sizeof(struct ns_hdr));

	/* read minimal ns header */
	if (readn(peer_fd, &ptr[rc], to_read) != to_read)
		return -1;

	/* ns header is in -> sanity checks and look if peer specified extension header */
	if (ntohs(ns_hdr.magic) != NS_MAGIC) {
		err_msg_die(EXIT_FAILHEADER, "received an corrupted header"
				"(should %d but is %d)!\n", NS_MAGIC, ntohs(ns_hdr.magic));
	}

	msg(STRESSFUL, "header info (magic: %d, version: %d, data_size: %d)",
			ntohs(ns_hdr.magic), ntohs(ns_hdr.version), ntohl(ns_hdr.data_size));

	phi->data_size = ntohl(ns_hdr.data_size);


	extension_type = ntohs(ns_hdr.nse_nxt_hdr);

	if (extension_type == NSE_NXT_DATA) {
		msg(STRESSFUL, "end of extension header processing (NSE_NXT_DATA, no extension header)");
		return 0;
	}

	while (invalid_ext_seen < INVALID_EXT_TRESH_NO) {

		/* FIXME: define some header size macros */
		uint16_t common_ext_head[2];
		to_read = sizeof(uint16_t) * 2;

		/* read first 4 octets of extension header, because we now
		** there IS a extension header and a extension header is always
		** 4 byte
		*/
		if (readn(peer_fd, common_ext_head, to_read) != to_read)
			return -1;

		extension_size = ntohs(common_ext_head[1]);

		switch (extension_type) {
			case NSE_NXT_DATA:
				msg(STRESSFUL, "end of extension header processing (NSE_NXT_DATA)");
				return 0;

			case NSE_NXT_NONXT:
				msg(STRESSFUL, "end of extension header processing (NSE_NXT_NONXT)");
				return process_nonxt(peer_fd, extension_size);
				break;

			case NSE_NXT_DIGEST:
				msg(STRESSFUL, "next extension header: %s", "NSE_NXT_DIGEST");
				err_msg("Not implementet yet: NSE_NXT_DIGEST\n");
				break;

			case NSE_NXT_RTT_PROBE:
				msg(STRESSFUL, "next extension header: %s", "NSE_NXT_RTT_PROBE");
				ret = process_rtt_probe(peer_fd, extension_size);
				if (ret == -1)
					return -1;
				break;

			case NSE_NXT_RTT_INFO:
				msg(STRESSFUL, "next extension header: %s", "NSE_NXT_RTT_INFO");
				ret = process_rtt_info(peer_fd, extension_size);
				if (ret == -1)
					return -1;
				break;

			default:
				++invalid_ext_seen;
				err_msg("received an unknown extension type (%d)!\n", extension_type);
				ret = process_nonxt(peer_fd, extension_size);
				if (ret == -1)
					return -1;
				break;
		}
		extension_type = ntohs(common_ext_head[0]);
		switch (extension_type) {
			case NSE_NXT_DATA:
				msg(STRESSFUL, "end of extension header processing (NSE_NXT_DATA)");
				return 0;

			case NSE_NXT_NONXT:
				msg(STRESSFUL, "end of extension header processing (NSE_NXT_NONXT)");
				return process_nonxt(peer_fd, extension_size);
				break;
		}
	};

	/* failure if we reach here (failure in previous while loop */
	return -1;
}
示例#14
0
int
meta_exchange_snd(int connected_fd, int file_fd)
{
	int ret = 0;
	ssize_t len;
	ssize_t file_size;
	struct ns_hdr ns_hdr;
	struct stat stat_buf;
	int perform_rtt;

	memset(&ns_hdr, 0, sizeof(struct ns_hdr));

	/* fetch file size */
	xfstat(file_fd, &stat_buf, opts.infile);

	file_size = S_ISREG(stat_buf.st_mode) ? stat_buf.st_size : 0;


	ns_hdr.magic = htons(NS_MAGIC);
	/* FIXME: catch overflow */
	ns_hdr.version = htons((uint16_t) strtol(VERSIONSTRING, (char **)NULL, 10));
	ns_hdr.data_size = htonl(file_size);

	perform_rtt = (opts.rtt_probe_opt.iterations > 0) ? 1 : 0;


	ns_hdr.nse_nxt_hdr = perform_rtt ? htons(NSE_NXT_RTT_PROBE) : htons(NSE_NXT_DATA);

	len = sizeof(struct ns_hdr);
	if (writen(connected_fd, &ns_hdr, len) != len)
		err_msg_die(EXIT_FAILHEADER, "Can't send netsend header!\n");

	/* probe for effective round trip time */
	if (opts.rtt_probe_opt.iterations > 0) {

		int flag_old;
		struct sigaction sa;

		/* initialize signalhandler for timeout handling */
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = SA_INTERRUPT;	/* don't restart system calls */
		sa.sa_handler = timout_handler;
		if (sigaction(SIGALRM, &sa, NULL) != 0)
			err_sys("Can't add signal handler");

		/* set TCP_NODELAY so tcp writes dont get buffered */
		if (opts.protocol == IPPROTO_TCP) {
			if ((flag_old = set_nodelay(connected_fd, 1)) < 0) {
				err_sys("Can't set TCP_NODELAY for socket (ret: %d)",
						flag_old);
			}
		}

		alarm(TIMEOUT_SEC);
		probe_rtt(connected_fd, NSE_NXT_DATA,
				opts.rtt_probe_opt.iterations, opts.rtt_probe_opt.data_size);
		alarm(0);

		/* and restore TCP_NOPUSH */
		if (opts.protocol == IPPROTO_TCP) {
			if ((set_nodelay(connected_fd, flag_old)) < 0) {
				err_sys("Can't set TCP_NODELAY for socket");
			}
		}

		/* transmitt our rtt probe results to our peer */
		send_rtt_info(connected_fd, NSE_NXT_DATA, &net_stat.rtt_probe);

	}

	/* XXX: add shasum next header if opts.sha, modify nse_nxt_hdr processing */

	return ret;
}
示例#15
0
文件: file.c 项目: hgn/netsend
int
open_input_file(void)
{
	int fd, ret;
	struct stat stat_buf;

	if (!strncmp(opts.infile, "-", 1)) {
		return STDIN_FILENO;
	}

	/* We don't want to read from a regular file
	** rather we want to execute a program and take
	** this output as our data source.
	*/
	if (opts.execstring) {
		pid_t pid;
		int pipefd[2];

		xpipe(pipefd);

		switch (pid = fork()) {
			case -1:
				err_sys_die(EXIT_FAILMISC, "Can't fork");
			case 0:
				close(STDOUT_FILENO);
				close(STDERR_FILENO);
				close(pipefd[0]);
				dup(pipefd[1]);
				dup(pipefd[1]);
				system(opts.execstring);
				exit(0);
				break;
			default:
				close(pipefd[1]);
				return pipefd[0];
				break;
		}

	}

	/* Thats the normal case: we open a regular file and take
	** the content as our source.
	*/
	ret = stat(opts.infile, &stat_buf);
	if (ret == -1)
		err_sys_die(EXIT_FAILMISC, "Can't stat file %s", opts.infile);

#if 0
	if (!(stat_buf.st_mode & S_IFREG)) {
		err_sys("Not an regular file %s", opts.infile);
		exit(EXIT_FAILOPT);
	}
#endif
#ifdef O_NOATIME
	fd = open(opts.infile, O_RDONLY|O_NOATIME);
#else
	fd = open(opts.infile, O_RDONLY);
#endif
	if (fd == -1)
		err_msg_die(EXIT_FAILMISC, "Can't open input file: %s", opts.infile);

	return fd;
}
示例#16
0
/*
 * performs all socketopts specified, except
 * for some highly protocol dependant options (e.g. TCP_MD5SIG).
 */
void set_socketopts(int fd)
{
	int i, ret;
	const void *optval;
	socklen_t optlen;

	/* loop over all selectable socket options */
	for (i = 0; socket_options[i].sockopt_name; i++) {
		if (!socket_options[i].user_issue)
			continue;
		/*
		 * this switch statement checks that the particular
		 * socket option matches our selected socket-type
		 */
		switch (socket_options[i].level) {
		case SOL_SOCKET: break; /* works on every socket */
		/* fall-through begins here ... */
		case IPPROTO_IP:
		case IPPROTO_IPV6:
		case IPPROTO_TCP:
			if (opts.protocol == IPPROTO_TCP)
				break;
		case IPPROTO_UDP:
			if (opts.protocol == IPPROTO_UDP)
				break;
		case IPPROTO_UDPLITE:
			if (opts.protocol == IPPROTO_UDPLITE)
				break;
		case IPPROTO_SCTP:
			if (opts.protocol == IPPROTO_SCTP)
				break;
		case SOL_DCCP:
			if (opts.protocol == IPPROTO_DCCP)
				break;
		default:
		/* and exit if socketoption and sockettype did not match */
		err_msg_die(EXIT_FAILMISC, "You selected an socket option which isn't "
					"compatible with this particular socket option");
		}

		/* ... and do the dirty: set the socket options */
		switch (socket_options[i].sockopt_type) {
		case SVT_BOOL:
		case SVT_INT:
		case SVT_TOINT:
			optlen = sizeof(socket_options[i].value);
			optval = &socket_options[i].value;
		break;
		case SVT_TIMEVAL:
			optlen = sizeof(socket_options[i].tv);
			optval = &socket_options[i].tv;
		break;
		case SVT_STR:
			optlen = strlen(socket_options[i].value_ptr) + 1;
			optval = socket_options[i].value_ptr;
		break;
		default:
			err_msg_die(EXIT_FAILNET, "Unknown sockopt_type %d\n",
					socket_options[i].sockopt_type);
		}

		ret = setsockopt(fd, socket_options[i].level, socket_options[i].option, optval, optlen);
		if (ret)
			err_sys_die(EXIT_FAILMISC, "setsockopt option %d (name %s) failed", socket_options[i].sockopt_type,
										socket_options[i].sockopt_name);
	}
}