Beispiel #1
0
int main(int argc, char *argv[])                                                                    
{       
        int x;
	char buf[256];
	const char *s;
	struct pmllex *lex;
	struct pmll_val v;

	lex = pmll_alloc();
        if (lex == NULL)
                errsys("pmll_new():");                                             

	if (pmll_add_infile(lex, stdin, 0, "stdin") < 0)
		errsys("pmll_add_input_file():");

        while ( (x = pmll_nexttok(lex, &v)) > 0 ) {
                printf("%-15s'%s'", pml_tok_strs[x], pmll_get_text(lex));
		s = strof(&v, x, buf, sizeof(buf));
		if (s != NULL)
			printf(" -- '%s'\n", s);
		else
			printf("\n");
		pmllv_clear(&v);
	}
        if ( x < 0 ) {
                printf("unknown token on line: %lu\n", pmll_get_lineno(lex));       
		printf("\t%s\n", pmll_get_err(lex));
        } else {
                printf("End of file\n");                                            
        }
        pmll_free(lex);                                                    

        return 0;                                                                   
}
Beispiel #2
0
void parse_args(int argc, char *argv[], int *ifd, int *ofd)
{
	int rv;
	struct clopt *opt;
	const char *fn;

	optparse_reset(&g_oparser, argc, argv);
	while (!(rv = optparse_next(&g_oparser, &opt))) {
		switch (opt->ch) {
		case 'd':
			g_start_delay = opt->val.dbl_val;
			break;
		case 'h':
			usage(NULL);
			break;
		case 'i':
			g_interval = opt->val.dbl_val;
			g_bps = 0.0;
			break;
		case 'p':
			g_interval = 1.0 / (double)opt->val.uint_val;
			g_bps = 0.0;
			break;
		case 'r':
			g_bps = opt->val.dbl_val;
			if (g_bps < 1.0)
				err("Can not have a rate less than 1 bps\n");
			g_interval = 0;
			break;
		}
	}
	if (rv < 0)
		usage(g_oparser.errbuf);

	if (rv < argc) {
		fn = argv[rv++];
		*ifd = open(fn, O_RDONLY);
		if (*ifd < 0)
			errsys("unable to open file '%s'", fn);
	}

	if (rv < argc) {
		fn = argv[rv++];
		*ofd = open(fn, O_RDONLY);
		if (*ofd < 0)
			errsys("unable to open file '%s'", fn);
	}

	if (rv < argc)
		usage(NULL);
}
Beispiel #3
0
void * emalloc(size_t size)
{
	void *m;
	if ( !(m = malloc(size)) )
		errsys("emalloc: ");
	return m;
}
Beispiel #4
0
static void load_prlib(const char *path)
{
	struct oproto_library *lib;

	abort_unless(path != NULL);

	if (oprliblist == NULL)
		oprliblist = cl_new(NULL, 1);

	lib = ecalloc(sizeof(*lib), 1);

	lib->path = path;

	lib->handle = dlopen(path, RTLD_LAZY);
	if (lib->handle == NULL)
		err("%s\n", dlerror());

	lib->load = dlsym(lib->handle, "load");
	if (lib->load == NULL)
		err("%s\n", dlerror());

	lib->unload = dlsym(lib->handle, "unload");
	if (lib->unload == NULL)
		err("%s\n", dlerror());

	if ((*lib->load)() < 0)
		errsys("Error loading %s: ");

	cl_push(oprliblist, lib);
}
Beispiel #5
0
int main(int argc,char **argv,char **envp)
{
  int piin[2];
  int piout[2];

  if (argc < 2)
    errint(EINVAL,"usage: fixcrio program [ arg ... ]");
  if (pipe(piin) == -1)
    errint(errno,"unable to create pipe");
  if (pipe(piout) == -1)
    errint(errno,"unable to create pipe");

  switch(fork()) {
    case -1:
      errint(errno,"unable to fork");
    case 0:
      sig_ignore(sig_pipe);
      close(piin[0]);
      close(piout[1]);
      doit(piin[1],piout[0]);
  }

  close(piin[1]);
  close(piout[0]);
  if (fd_move(0,piin[0]) == -1)
    errint(errno,"unable to move descriptors");
  if (fd_move(1,piout[1]) == -1)
    errint(errno,"unable to move descriptors");

  pathexec_run(argv[1],argv + 1,envp);
  errsys(errno);
  return(0);
}
Beispiel #6
0
void * erealloc(void *old, size_t size)
{
	void *m;
	if ( !(m = realloc(old, size)) )
		errsys("erealloc: ");
	return m;
}
Beispiel #7
0
void * std_ealloc(struct memsys *mc, unsigned size) 
{
	void *m;
	assert(mc && size > 0);
	if ( !(m = malloc(size)) )
		errsys("malloc: ");
	return m;
}
Beispiel #8
0
void * std_eresize(struct memsys *mc, void *old, unsigned newsize) 
{
	void *m;
	assert(mc && newsize >= 0);
	if ( !(m = realloc(old, newsize)) )
		errsys("realloc: ");
	return m;
}
Beispiel #9
0
static unsigned int
__listen (SOCKET *self)
{
	vvprintf("Listening for connections...");

	socket_t *sock = self->data;
	if (listen(sock->fd, sock->backlog) == -1)
		return errsys("Could not listen out on socket.");

	return SUCCESS;
}
Beispiel #10
0
static unsigned int	
__bind (SOCKET *self)
{
	vvprintf("Binding to socket...");

	socket_t *sock = self->data;
	if (bind(sock->fd, (struct sockaddr *)sock->srvaddrinfo, sizeof(struct sockaddr_in)) == -1)
		return errsys("Could not bind to socket.");  

	return SUCCESS;
}
Beispiel #11
0
void packet_loop()
{
	int rv;
	int rlen = 0;
	struct pktbuf pkb;
	struct bpf_hdr *bh;
	byte_t *bpfbuf = emalloc(g_buflen);
	byte_t *bp;

	while (1) {
		if (rlen <= 0) {
			rlen = read(g_ifsock, bpfbuf, g_buflen);
			if (rlen <= 0) {
				if (rlen < 0) {
					rlen = 0;
					if (errno == EINTR)
						continue;
					errsys("error receiving packet: ");
				}
				break;
			}

			bp = bpfbuf;
		}

		bh = (struct bpf_hdr *)bp;
		setup_pkb(&pkb, bp + bh->bh_hdrlen, bh);

		rv = pkb_pack(&pkb);
		abort_unless(rv == 0);

		if (pkb_file_write(&pkb, g_outfile) < 0)
			errsys("pkb_file_write: ");

		bp += BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen);
		rlen -= BPF_WORDALIGN(bh->bh_hdrlen + bh->bh_caplen);
	}
}
Beispiel #12
0
void dbg_mem_free(struct memmgr *mm, void *p)
{
	struct hnode *hn;
	struct dbg_header *dh;

	abort_unless(mm == &dbgmem);

	hn = ht_lkup(&dbg_htab, p, NULL); 
	if ( hn == NULL )
		errsys("dbg_mem_free: attempt to free non-dynamic pointer: %p",
					 p);
	dh = container(hn, struct dbg_header, dh_hnode);
	dbg_alloc_amt -= dh->dh_amt;
	--dbg_num_alloc;
	free(dh);
}
Beispiel #13
0
int readpkt(void *arg, struct callback *cb)
{
	int rv;
	struct pktbuf *p;
	struct ue_ioevent *ioe = container(cb, struct ue_ioevent, cb);
	struct xpkt_tag_iface *xifp;
	struct xpkt_tag_iface xif;
	int n;

	if ((rv = pkb_fd_read_a(&p, ioe->fd, NULL, NULL)) <= 0) {
		if (rv < 0)
			logsys(1, "Error reading from fd %d\n", ioe->fd);
		ue_io_del(ioe);
		return 0;
	}
	++g_npkts;
	xifp = (struct xpkt_tag_iface *)pkb_find_tag(p, XPKT_TAG_INIFACE, 0);
	if (xifp) {
		/* there's an existing tag:  so modify it */
		if (ioe->fd >= 3) {
			xifp->iface = ioe->fd - 3;
		} else {
			/* these should always succeed */
			n = pkb_find_tag_idx(p, (struct xpkt_tag_hdr *)xifp);
			abort_unless(n >= 0);
			rv = pkb_del_tag(p, xifp->type, n);
			abort_unless(rv == 0);
		}
	} else {
		if (ioe->fd >= 3) {
			xpkt_tag_oif_init(&xif, ioe->fd - 3);
			rv = pkb_add_tag(p, (struct xpkt_tag_hdr *)&xif);
			if (rv < 0) {
				pkb_free(p);
				return 0;
			}
		}
	}

	rv = pkb_pack(p);
	abort_unless(rv == 0);
	if (pkb_fd_write(p, 1) < 0)
		errsys("Error writing packet %lu\n", g_npkts);
	pkb_free(p);

	return 0;
}
Beispiel #14
0
void *dbg_mem_resize(struct memmgr *mm, void *p, size_t newsize)
{
	size_t ramt;
	struct dbg_header *dh;
	struct hnode *hn;
	void *p2;
	size_t osize;

	abort_unless(mm == &dbgmem);

	hn = ht_lkup(&dbg_htab, p, NULL); 
	if ( hn == NULL )
		errsys("dbg_mem_resize: attempt to reallocate non dynamic"
					 "pointer: %p", p);
	dh = container(hn, struct dbg_header, dh_hnode);
	osize = dh->dh_amt;

	if ( newsize > 0 ) {
		ramt = ROUNDUP(newsize);
		abort_unless(ramt >= newsize);
	} else {
		ramt = 0;
	}

	p2 = realloc(dh, ramt);
	if ( p2 == NULL || ramt == 0 ) {
		if ( ramt == 0 ) {
			dbg_alloc_amt -= osize;
			--dbg_num_alloc;
		}
		return NULL;
	}

	dbg_alloc_amt = dbg_alloc_amt - osize + newsize;
	dh = p2;
	dh->dh_amt = newsize;
	p = TOMEM(dh);
	ht_ninit(&dh->dh_hnode, p);
	ht_ins_h(&dbg_htab, &dh->dh_hnode);

	return p;
}
Beispiel #15
0
void parse_args(int argc, char *argv[])
{
	int rv;
	struct clopt *opt;
	const char *ofname;

	optparse_reset(&g_oparse, argc, argv);
	while (!(rv = optparse_next(&g_oparse, &opt))) {
		switch (opt->ch) {
		case 'h':
			usage(argv[0], NULL);
			break;
		case 'n':
			g_ifnum = opt->val.uint_val;
			break;
		case 'I':
			g_inonly = 1;
			break;
		case 'p':
			g_promisc = 0;
			break;
		}
	}

	if (rv < 0 || rv >= argc)
		usage(argv[0], g_oparse.errbuf);

	g_iifname = argv[rv++];
	if (rv < argc) {
		ofname = argv[rv++];
		g_outfile = fopen(ofname, "w");
		if (g_outfile == NULL)
			errsys("Error opening file %s: ", ofname);

	}
	if (rv < argc)
		usage(argv[0], NULL);
}
Beispiel #16
0
void init_ifsock()
{
	struct ifreq ifr;
	uint arg;

	g_ifsock = bpfdev_open();
	if (g_ifsock < 0)
		errsys("opening BPF device: ");

	str_copy(ifr.ifr_name, g_iifname, sizeof(ifr.ifr_name));
	if (ioctl(g_ifsock, BIOCSETIF, &ifr) < 0)
		errsys("ioctl() BIOCSETIF: ");

	if (ioctl(g_ifsock, BIOCGDLT, &arg) < 0)
		errsys("ioctl() BIOCGDLT: ");

	if (arg == DLT_EN10MB) {
		g_prid = PRID_ETHERNET2;
	} else {
		err("unknown datalink type: %u", arg);
	}

	if (g_promisc)
		ioctl(g_ifsock, BIOCPROMISC, NULL);

	if (ioctl(g_ifsock, BIOCGBLEN, &g_buflen) < 0)
		errsys("ioctl(BIOCGBLEN...): ");

	if (g_inonly) {
#ifdef BIOCSDIRFILT /* OpenBSD */
		arg = BPF_DIRECTION_OUT;
		if (ioctl(g_ifsock, BIOCSDIRFILT, &arg) < 0)
			errsys("ioctl(BIOCSDIRFILT, OUT)...");
#elif defined(BIOCSSEESENT) /* osX */
		arg = 0;
		if (ioctl(g_ifsock, BIOCSSEESENT, &arg) < 0)
			errsys("ioctl(BIOCSSEESENT, 0)...");
#else
		err("Option -I not supported on this platform\n");
#endif
	}

}
Beispiel #17
0
int main(int argc, char *argv[])
{
	int tok;
	struct pmllex *scanner;
	pml_parser_t parser;
	struct pml_ast tree;
	struct pmll_val extra;
	int printmask = VERBOSE|LEX|TREE1|TREE2;

	if (argc > 1) {
		if (strcmp(argv[1], "-h") == 0) {
			fprintf(stderr, "usage: %s <printmask>\n"
					"\tBit 0: enables verbose\n"
					"\tBit 1: enables lex analyzer output\n"
					"\tBit 2: prints pre-optimized AST\n"
					"\tBit 3: prints optimized AST\n",
				argv[0]);
			exit(1);
		}
		printmask = atoi(argv[1]);
	}

	if (printmask & VERBOSE) {
		printf("#########\n");
		printf("Initializing parse data structures\n");
		printf("#########\n");
	}

	register_std_proto();

	if ((scanner = pmll_alloc()) == NULL)
		errsys("pmllex_init:");
	if (pmll_add_infile(scanner, stdin, 0, "-") < 0)
		errsys("pmll_add_input_file:");

	if (!(parser = pml_alloc()))
		errsys("pml_alloc:");
	pml_ast_init(&tree);
	pml_ast_add_std_intrinsics(&tree);
	pml_ast_set_parser(&tree, scanner, parser);

	if (printmask & VERBOSE) {
		printf("#########\n");
		printf("Starting Parse\n");
		printf("#########\n");
	}

	if (printmask & LEX)
		PMLTrace(stdout, "  ---  ");

	do {
		tok = pmll_nexttok(scanner, &extra);
		if (tok < 0)
			err("Syntax error: %s\n", pmll_get_err(scanner));
		if (printmask & LEX)
			printf("Token -- %d -> '%s'\n", tok,
			       pmll_get_text(scanner));
		if (pml_parse(parser, &tree, tok, extra)) {
			err("parse error on file %s line %d: %s\n",
			    pmll_get_iname(scanner),
			    pmll_get_lineno(scanner), tree.errbuf);
		}
	} while (tok > 0);

	if (!tree.done)
		err("File did not reduce to a complete tree\n");

	if (printmask & VERBOSE) {
		printf("\n\n########\n");
		printf("Done parsing, destroying scanner and parser\n");
		printf("########\n");
	}

	if (printmask & TREE1) {
		if (printmask & VERBOSE) {
			printf("\n\n########\n");
			printf("Printing base tree\n");
			printf("#########\n");
		}
		pml_ast_print(&tree);
	}

	if (printmask & TREE2) {
		if (printmask & VERBOSE) {
			printf("\n\n########\n");
			printf("Optimizing tree:\n");
			printf("########\n");
		}

		if (pml_ast_optimize(&tree) < 0)
			err("Error optimizing PML tree: %s\n", tree.errbuf);

		if (printmask & VERBOSE) {
			printf("Done... printing optimized tree\n");
		}

		pml_ast_print(&tree);
	}

	if (printmask & VERBOSE) {
		printf("\n\n########\n");
		printf("Clearing tree:\n");
		printf("########\n");
	}

	pml_ast_clear(&tree);

	return 0;
}
Beispiel #18
0
/* This definition is stupid.  Think of something better */
SOCKET *
NEW(socket) (SOCKET *sk, int type, int domain, int proto, char sr, unsigned int port, const char *hostname, void *ssl_ctx)
{
	/* Object allocation */
	iiprintf(SOCKET);
	SOCKET *s;
	socket_t *sock;

	/* Check memory */
	if (!sk) {
		if (!(s = nalloc(sizeof(SOCKET), "socket.object")))
			return NULL;

		if (!(sock = (socket_t *)nalloc(sizeof(socket_t), "socket.socket")))
		{
			free(s);
			return NULL;
		}
		memset(sock, 0, sizeof(socket_t));
	}
	else {
		s = sk;
		sock = sk->data;
		memset(sock, 0, sizeof(socket_t));
	}

	/* All of this can be done with a macro */
	sock->buffer = NULL;
	sock->connection_type = type;
	sock->domain = domain;
	sock->protocol = proto;
	sock->addrsize = sizeof(struct sockaddr);
	sock->bufsz = 1024;
	sock->opened = 0;
	sock->backlog = 500;
	sock->waittime = 5000;  // 3000 microseconds
	sock->hostname = !hostname ? NULL : (char *)hostname;

	/* Check port number (clients are zero until a request is made) */
	if (port < 0 || port > 65536) {
		/* Free allocated socket */
		vvprintf("Invalid port specified.");
		return errnull("Invalid port specified.");
	}
	else if (!port)
		sock->port = 0;
	else
		sock->port = port;

#if 0	
	/* Service check (part of struct in the future) */
	fprintf(stderr, "Checking that port binds to a real service...");
	if (!services[port])
		sock->service = "UNKNOWN";
	else
		sock->service = (char *)services[port];
#endif

	/* Set up the address data structure for use as either client or server */	
	sock->_class = sr;
	if (sock->_class == 's')
	{
		if ((sock->srvaddrinfo = (struct sockaddr_in *)nalloc(sizeof(struct sockaddr_in), "sockaddr.info")) == NULL)
			return errnull("Could not allocate structure specified.");

		/* Some type of gethosting must be done */
		memset(sock->srvaddrinfo, 0, sizeof(struct sockaddr_in));
		struct sockaddr_in *saa = sock->srvaddrinfo; 
		saa->sin_family = AF_INET;
		saa->sin_port = htons(sock->port);
		/* A smart string function can decide whether or not this is IPv6 */
		(&saa->sin_addr)->s_addr = htonl(INADDR_ANY);
	}
	else if (sock->_class == 'c') 
	{
		/* Set up the addrinfo structure for a future client request. */
		struct addrinfo *h; 
		memset(&sock->hints, 0, sizeof(sock->hints));
		h = &sock->hints;
		h->ai_family = sock->domain;
		h->ai_socktype = sock->connection_type;
	}

	#if 0
	/* Show the buffer pointer... */
	fprintf(stderr, "tcp socket buffer: %p (%s)\n", sock->buffer,
		sock->_class == 'c' ? "client" : \
			sock->_class == 'd' ? "child" : "server");
	#endif


	/* Set up an SSL context if asked. */
	if (!ssl_ctx)
		sock->ssl_ctx = NULL;
	else
		sock->ssl_ctx = ssl_ctx;


	/* Finally, create a socket. */
	sock->fd = socket(sock->domain, sock->connection_type, sock->protocol);
	sock->opened = 1;


	/* Set timeout, reusable bit and any other options */
	struct timeval to;
	to.tv_sec = 2;
	to.tv_usec = 0;
	if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &to, sizeof(to)) == -1) {
		// sock->free(sock);
		errsys("Could not reopen socket.");
		return NULL;
	}


	/* Set private data */
	s->data = sock;        /* Set the socket info as part of the object. */
	s->data->urn = NULL;   /* Set the URN to NULL */

	/* The standard */
	s->free = &__free;
	s->info = &__printf;

	/* The rest */
	s->connect = &__connect;
	s->bind = &__bind;
	s->listen = &__listen;
	s->accept = &__accept;
	s->shutdown = &__shutdown;
	s->close = &__close;
	s->send = &__send;
	s->recv = &__recv;
	s->addrinfo = &__addrinfo;
	s->recvd = &recvd;
	s->parsed = &parsed;
	s->release = &__release;
	return INITIALIZED(s);
}
Beispiel #19
0
static unsigned int	
__recv (SOCKET *self)
{
	/* Initialize */
	BUFFER *ff = NULL; 
	int rcvd = 0;
	int rd = 0;
	socket_t *sock = self->data;
	char msg[(const int)sock->bufsz];
	unsigned int ws = sock->bufsz - 1;

#if 1
	#define CC "child"
	#define SS "server"
	#define CL "client"
	char c = sock->_class;
	fprintf(stderr, "tcp socket buffer: %p (%s)\n", \
		ff, (c=='c') ? CL : (c=='d') ? CC : SS);
#endif

	/* Create a new fresh buffer (clean this up...) */
	if (!(ff = NEW(buffer)(binary, 0)))
		return errstat(0, "Failed to create buffer for socket data.");
		
#if 1
	fprintf(stderr, "Current size: %d\n", ff->size(ff));
	fprintf(stderr, "tcp socket buffer is now: %p (%s)\n", \
		ff, (c=='c') ? CL : (c=='d') ? CC : SS);
#endif
	sock->buffer = ff;

	/* Use a buffer and connection here */
	switch (sock->connection_type) 
	{
		case SOCK_STREAM:
			/* If it's -1, die.  If it's less than buffer, die */
			while (1) {
				rcvd = recv(sock->fd, &msg, ws, 0);
				rd += rcvd;
				vvprintf("rcvd %d bytes so far\n", rd);
			#if 0
				int c = 0;
				for (c=0;c<(ws > rcvd ? rcvd : ws); c++) 
					fprintf(stderr, "'%c' ", msg[c]);
			#endif

				/* Error occurred, free or reset the buffer and die */
				if (rcvd == -1)
					return errsys("recv() error occurred");
				/* End of message reached before end of buffer */
				else if (rcvd < ws) {	
					ff->append(ff, msg, rcvd);
					vvprintf("Finally rcvd %d bytes.", rd);
					vvprintf("Current buffer size: %d\n", ff->contents(ff)->size);
					return SUCCESS;
				}

				/* Write the entire buffer otherwise */
				ff->append(ff, msg, ws);
			}
				
#if 0
		case SOCK_DGRAM:
			rcvd = recvfrom(sock->fd, msg, ws, 0,
				NULL, NULL);
				//sock->cliaddr, &sock->cliaddrlen);

			if (rcvd == -1) return 0;
			msg[rcvd] = 0;
			fprintf(stderr, "udp recv'd bytes: %d\n", rcvd);
			fprintf(stderr, "%s\n", msg);	

			while (1) {
				rcvd = recvfrom(sock->fd, msg, ws, 0,
					NULL, NULL);
				fprintf(stderr, "udp recv'd bytes: %d\n", rcvd);
				fprintf(stderr, "%s\n", msg);	

				if (rcvd == -1)
					return 0;  // return false and sock->error = errno;
				if (rcvd < ws)
					break;	
			}
			return 1;
#endif

		default:
			fprintf(stderr, "%s\n", "Got unknown socket option.");
			return 0;	
	}

	return SUCCESS;
}
Beispiel #20
0
int main(int argc, char *argv[])
{
	int rv;
	struct pktbuf *p;
	cat_time_t pts, now, next, nnext, start_time, start_ts = { 0 };
	struct xpkt_tag_ts *ts;
	int infd = 0;
	int outfd = 1;
	ulong bits;

	pkb_init_pools(1);

	parse_args(argc, argv, &infd, &outfd);

	now = tm_uget();
	if (g_start_delay > 0) {
		next = tm_add(now, tm_dset(g_start_delay));
		sleep_until(&next, &now);
	}
	start_time = now;
	next = now;


	while ((rv = pkb_fd_read_a(&p, infd, NULL, NULL)) > 0) {
		now = tm_uget();
		++g_npkts;

		if (g_interval > 0.0) {
			nnext = tm_add(next, tm_dset(g_interval));
			sleep_until(&next, &now);
			next = nnext;
		} else if (g_bps > 1.0) {
			bits = pkb_get_len(p) * 8;
			nnext = tm_add(next, tm_dset(bits / g_bps));
			sleep_until(&next, &now);
			next = nnext;
		} else {
			ts = (struct xpkt_tag_ts *)
				pkb_find_tag(p, XPKT_TAG_TIMESTAMP, 0);

			if ( ts == NULL ) {
				fprintf(stderr,
					"no timestamp on packet %lu: sending\n",
					g_npkts);
				goto send;
			}

			pts = tm_lset(ts->sec, ts->nsec);
			if (tm_ltz(pts)) {
				fprintf(stderr,
					"Invalid timestamp on packet %lu "
					"(%ld,%ld)\n",
					g_npkts, tm_sec(pts), tm_nsec(pts));
				pkb_free(p);
				continue;
			}

			if (g_npkts == 1)
				start_ts = pts;

			next = tm_add(tm_sub(pts, start_ts), start_time);
			sleep_until(&next, &now);
		}

send:
		rv = pkb_pack(p);
		abort_unless(rv == 0);
		if (pkb_fd_write(p, outfd) < 0)
			errsys("Error writing packet %lu", g_npkts);
		pkb_free(p);
	}
	if (rv < 0)
		errsys("Error reading packet %lu: ", g_npkts + 1);

	return 0;
}