*ifn = *cpp++;
*ifn = strdup(*cpp++);
static	int	parseline(line, ip, ifn, out)char	*line;struct	ip	*ip;char	**ifn;int	*out;{	tcphdr_t	th, *tcp = &th;	struct	icmp	icmp, *ic = &icmp;	char	*cps[20], **cpp, c, ipopts[68];	int	i, r;	bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip));	bzero((char *)tcp, sizeof(*tcp));	bzero((char *)ic, sizeof(*ic));	bzero(ipopts, sizeof(ipopts));	ip->ip_hl = sizeof(*ip) >> 2;	ip->ip_v = IPVERSION;	for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && i < 19; )		cps[++i] = strtok(NULL, " \b\t\r\n");	if (i < 2)		return 1;	cpp = cps;	c = **cpp;	if (!isalpha(c) || (tolower(c) != 'o' && tolower(c) != 'i')) {		fprintf(stderr, "bad direction \"%s\"\n", *cpp);		return 1;	}	*out = (tolower(c) == 'o') ? 1 : 0;	cpp++;	if (!strcasecmp(*cpp, "on")) {		cpp++;		if (!*cpp)			return 1;		*ifn = *cpp++;	}	c = **cpp;	ip->ip_len = sizeof(struct ip);	if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") ||	    !strcasecmp(*cpp, "icmp")) {		if (c == 't') {			ip->ip_p = IPPROTO_TCP;			ip->ip_len += sizeof(struct tcphdr);			tx_proto = "tcp";		} else if (c == 'u') {			ip->ip_p = IPPROTO_UDP;			ip->ip_len += sizeof(struct udphdr);			tx_proto = "udp";		} else {			ip->ip_p = IPPROTO_ICMP;			ip->ip_len += sizeof(struct icmp);			tx_proto = "icmp";		}		cpp++;	} else		ip->ip_p = IPPROTO_IP;	if (!*cpp)		return 1;	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) {		char	*last;		last = index(*cpp, ',');		if (!last) {			fprintf(stderr, "tcp/udp with no source port\n");			return 1;		}		*last++ = '\0';		tcp->th_sport = htons(tx_portnum(last));	}	ip->ip_src.s_addr = tx_hostnum(*cpp, &r);	cpp++;	if (!*cpp)		return 1;	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) {		char	*last;		last = index(*cpp, ',');		if (!last) {			fprintf(stderr, "tcp/udp with no destination port\n");			return 1;		}		*last++ = '\0';		tcp->th_dport = htons(tx_portnum(last));	}	ip->ip_dst.s_addr = tx_hostnum(*cpp, &r);	cpp++;	if (*cpp && ip->ip_p == IPPROTO_TCP) {		extern	char	tcp_flagset[];		extern	u_char	tcp_flags[];		char	*s, *t;		for (s = *cpp; *s; s++)			if ((t  = index(tcp_flagset, *s)))				tcp->th_flags |= tcp_flags[t - tcp_flagset];		if (tcp->th_flags)			cpp++;		assert(tcp->th_flags != 0);	} else if (*cpp && ip->ip_p == IPPROTO_ICMP) {		extern	char	*tx_icmptypes[];		char	**s, *t;		int	i;		for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END");		     s++, i++)			if (*s && !strncasecmp(*cpp, *s, strlen(*s))) {				ic->icmp_type = i;				if ((t = index(*cpp, ',')))					ic->icmp_code = atoi(t+1);				cpp++;				break;			}	}	if (*cpp && !strcasecmp(*cpp, "opt")) {		u_long	olen;		cpp++;		olen = buildopts(*cpp, ipopts);		if (olen) {			bcopy(ipopts, (char *)(ip + 1), olen);			ip->ip_hl += olen >> 2;		}	}	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)		bcopy((char *)tcp, ((char *)ip) + (ip->ip_hl << 2),			sizeof(*tcp));	else if (ip->ip_p == IPPROTO_ICMP)		bcopy((char *)ic, ((char *)ip) + (ip->ip_hl << 2),			sizeof(*ic));	return 0;}