xref: /illumos-gate/usr/src/cmd/ipf/lib/common/ipft_tx.c (revision 9b4c7145)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright (C) 1995-2001 by Darren Reed.
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
57c478bd9Sstevel@tonic-gate  *
6*9b4c7145Sjojemann  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
7*9b4c7145Sjojemann  * Use is subject to license terms.
87c478bd9Sstevel@tonic-gate  */
9*9b4c7145Sjojemann 
10*9b4c7145Sjojemann #pragma ident	"%Z%%M%	%I%	%E% SMI"
11*9b4c7145Sjojemann 
127c478bd9Sstevel@tonic-gate #if !defined(lint)
137c478bd9Sstevel@tonic-gate static const char sccsid[] = "@(#)ipft_tx.c	1.7 6/5/96 (C) 1993 Darren Reed";
14ab25eeb5Syz static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 1.15.2.3 2005/06/18 02:41:34 darrenr Exp $";
157c478bd9Sstevel@tonic-gate #endif
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include <ctype.h>
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate #include "ipf.h"
207c478bd9Sstevel@tonic-gate #include "ipt.h"
217c478bd9Sstevel@tonic-gate 
22ab25eeb5Syz #ifndef linux
237c478bd9Sstevel@tonic-gate #include <netinet/ip_var.h>
24ab25eeb5Syz #endif
257c478bd9Sstevel@tonic-gate #include <netinet/tcpip.h>
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate extern	int	opts;
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate static	char	*tx_proto = "";
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate static	int	text_open __P((char *)), text_close __P((void));
337c478bd9Sstevel@tonic-gate static	int	text_readip __P((char *, int, char **, int *));
347c478bd9Sstevel@tonic-gate static	int	parseline __P((char *, ip_t *, char **, int *));
357c478bd9Sstevel@tonic-gate 
36ab25eeb5Syz static	char	myflagset[] = "FSRPAUEC";
37ab25eeb5Syz static	u_char	myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
387c478bd9Sstevel@tonic-gate 				TH_ACK, TH_URG, TH_ECN, TH_CWR };
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate struct	ipread	iptext = { text_open, text_close, text_readip, R_DO_CKSUM };
417c478bd9Sstevel@tonic-gate static	FILE	*tfp = NULL;
427c478bd9Sstevel@tonic-gate static	int	tfd = -1;
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate static	u_32_t	tx_hostnum __P((char *, int *));
457c478bd9Sstevel@tonic-gate static	u_short	tx_portnum __P((char *));
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate  * returns an ip address as a long var as a result of either a DNS lookup or
507c478bd9Sstevel@tonic-gate  * straight inet_addr() call
517c478bd9Sstevel@tonic-gate  */
tx_hostnum(host,resolved)527c478bd9Sstevel@tonic-gate static	u_32_t	tx_hostnum(host, resolved)
537c478bd9Sstevel@tonic-gate char	*host;
547c478bd9Sstevel@tonic-gate int	*resolved;
557c478bd9Sstevel@tonic-gate {
56*9b4c7145Sjojemann 	i6addr_t ipa;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 	*resolved = 0;
59ab25eeb5Syz 	if (!strcasecmp("any", host))
607c478bd9Sstevel@tonic-gate 		return 0L;
61ab25eeb5Syz 	if (ISDIGIT(*host))
627c478bd9Sstevel@tonic-gate 		return inet_addr(host);
637c478bd9Sstevel@tonic-gate 
64*9b4c7145Sjojemann 	if (gethost(host, &ipa, 0) == -1) {
65ab25eeb5Syz 		*resolved = -1;
66ab25eeb5Syz 		fprintf(stderr, "can't resolve hostname: %s\n", host);
67ab25eeb5Syz 		return 0;
687c478bd9Sstevel@tonic-gate 	}
69*9b4c7145Sjojemann 	return ipa.in4_addr;
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * find the port number given by the name, either from getservbyname() or
757c478bd9Sstevel@tonic-gate  * straight atoi()
767c478bd9Sstevel@tonic-gate  */
tx_portnum(name)777c478bd9Sstevel@tonic-gate static	u_short	tx_portnum(name)
787c478bd9Sstevel@tonic-gate char	*name;
797c478bd9Sstevel@tonic-gate {
807c478bd9Sstevel@tonic-gate 	struct	servent	*sp, *sp2;
817c478bd9Sstevel@tonic-gate 	u_short	p1 = 0;
827c478bd9Sstevel@tonic-gate 
83ab25eeb5Syz 	if (ISDIGIT(*name))
847c478bd9Sstevel@tonic-gate 		return (u_short)atoi(name);
857c478bd9Sstevel@tonic-gate 	if (!tx_proto)
867c478bd9Sstevel@tonic-gate 		tx_proto = "tcp/udp";
877c478bd9Sstevel@tonic-gate 	if (strcasecmp(tx_proto, "tcp/udp")) {
887c478bd9Sstevel@tonic-gate 		sp = getservbyname(name, tx_proto);
897c478bd9Sstevel@tonic-gate 		if (sp)
907c478bd9Sstevel@tonic-gate 			return ntohs(sp->s_port);
917c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "unknown service \"%s\".\n", name);
927c478bd9Sstevel@tonic-gate 		return 0;
937c478bd9Sstevel@tonic-gate 	}
947c478bd9Sstevel@tonic-gate 	sp = getservbyname(name, "tcp");
957c478bd9Sstevel@tonic-gate 	if (sp)
967c478bd9Sstevel@tonic-gate 		p1 = sp->s_port;
977c478bd9Sstevel@tonic-gate 	sp2 = getservbyname(name, "udp");
987c478bd9Sstevel@tonic-gate 	if (!sp || !sp2) {
997c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n",
1007c478bd9Sstevel@tonic-gate 			name);
1017c478bd9Sstevel@tonic-gate 		return 0;
1027c478bd9Sstevel@tonic-gate 	}
1037c478bd9Sstevel@tonic-gate 	if (p1 != sp2->s_port) {
1047c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s %d/tcp is a different port to ",
1057c478bd9Sstevel@tonic-gate 			name, p1);
1067c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port);
1077c478bd9Sstevel@tonic-gate 		return 0;
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 	return ntohs(p1);
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate char	*tx_icmptypes[] = {
1147c478bd9Sstevel@tonic-gate 	"echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
1157c478bd9Sstevel@tonic-gate 	"redir", (char *)NULL, (char *)NULL, "echo", "routerad",
1167c478bd9Sstevel@tonic-gate 	"routersol", "timex", "paramprob", "timest", "timestrep",
1177c478bd9Sstevel@tonic-gate 	"inforeq", "inforep", "maskreq", "maskrep", "END"
1187c478bd9Sstevel@tonic-gate };
1197c478bd9Sstevel@tonic-gate 
text_open(fname)1207c478bd9Sstevel@tonic-gate static	int	text_open(fname)
1217c478bd9Sstevel@tonic-gate char	*fname;
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate 	if (tfp && tfd != -1) {
1247c478bd9Sstevel@tonic-gate 		rewind(tfp);
1257c478bd9Sstevel@tonic-gate 		return tfd;
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	if (!strcmp(fname, "-")) {
1297c478bd9Sstevel@tonic-gate 		tfd = 0;
1307c478bd9Sstevel@tonic-gate 		tfp = stdin;
1317c478bd9Sstevel@tonic-gate 	} else {
1327c478bd9Sstevel@tonic-gate 		tfd = open(fname, O_RDONLY);
1337c478bd9Sstevel@tonic-gate 		if (tfd != -1)
1347c478bd9Sstevel@tonic-gate 			tfp = fdopen(tfd, "r");
1357c478bd9Sstevel@tonic-gate 	}
1367c478bd9Sstevel@tonic-gate 	return tfd;
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 
text_close()1407c478bd9Sstevel@tonic-gate static	int	text_close()
1417c478bd9Sstevel@tonic-gate {
1427c478bd9Sstevel@tonic-gate 	int	cfd = tfd;
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	tfd = -1;
1457c478bd9Sstevel@tonic-gate 	return close(cfd);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 
text_readip(buf,cnt,ifn,dir)1497c478bd9Sstevel@tonic-gate static	int	text_readip(buf, cnt, ifn, dir)
1507c478bd9Sstevel@tonic-gate char	*buf, **ifn;
1517c478bd9Sstevel@tonic-gate int	cnt, *dir;
1527c478bd9Sstevel@tonic-gate {
1537c478bd9Sstevel@tonic-gate 	register char *s;
1547c478bd9Sstevel@tonic-gate 	char	line[513];
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	*ifn = NULL;
1577c478bd9Sstevel@tonic-gate 	while (fgets(line, sizeof(line)-1, tfp)) {
1587c478bd9Sstevel@tonic-gate 		if ((s = strchr(line, '\n')))
1597c478bd9Sstevel@tonic-gate 			*s = '\0';
1607c478bd9Sstevel@tonic-gate 		if ((s = strchr(line, '\r')))
1617c478bd9Sstevel@tonic-gate 			*s = '\0';
1627c478bd9Sstevel@tonic-gate 		if ((s = strchr(line, '#')))
1637c478bd9Sstevel@tonic-gate 			*s = '\0';
1647c478bd9Sstevel@tonic-gate 		if (!*line)
1657c478bd9Sstevel@tonic-gate 			continue;
1667c478bd9Sstevel@tonic-gate 		if (!(opts & OPT_BRIEF))
1677c478bd9Sstevel@tonic-gate 			printf("input: %s\n", line);
1687c478bd9Sstevel@tonic-gate 		*ifn = NULL;
1697c478bd9Sstevel@tonic-gate 		*dir = 0;
1707c478bd9Sstevel@tonic-gate 		if (!parseline(line, (ip_t *)buf, ifn, dir))
1717c478bd9Sstevel@tonic-gate #if 0
1727c478bd9Sstevel@tonic-gate 			return sizeof(ip_t) + sizeof(tcphdr_t);
1737c478bd9Sstevel@tonic-gate #else
1747c478bd9Sstevel@tonic-gate 			return sizeof(ip_t);
1757c478bd9Sstevel@tonic-gate #endif
1767c478bd9Sstevel@tonic-gate 	}
1777c478bd9Sstevel@tonic-gate 	return -1;
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
parseline(line,ip,ifn,out)1807c478bd9Sstevel@tonic-gate static	int	parseline(line, ip, ifn, out)
1817c478bd9Sstevel@tonic-gate char	*line;
1827c478bd9Sstevel@tonic-gate ip_t	*ip;
1837c478bd9Sstevel@tonic-gate char	**ifn;
1847c478bd9Sstevel@tonic-gate int	*out;
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate 	tcphdr_t	th, *tcp = &th;
1877c478bd9Sstevel@tonic-gate 	struct	icmp	icmp, *ic = &icmp;
1887c478bd9Sstevel@tonic-gate 	char	*cps[20], **cpp, c, ipopts[68];
1897c478bd9Sstevel@tonic-gate 	int	i, r;
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	if (*ifn)
1927c478bd9Sstevel@tonic-gate 		free(*ifn);
1937c478bd9Sstevel@tonic-gate 	bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip));
1947c478bd9Sstevel@tonic-gate 	bzero((char *)tcp, sizeof(*tcp));
1957c478bd9Sstevel@tonic-gate 	bzero((char *)ic, sizeof(*ic));
1967c478bd9Sstevel@tonic-gate 	bzero(ipopts, sizeof(ipopts));
1977c478bd9Sstevel@tonic-gate 	IP_HL_A(ip, sizeof(*ip) >> 2);
1987c478bd9Sstevel@tonic-gate 	IP_V_A(ip, IPVERSION);
1997c478bd9Sstevel@tonic-gate 	for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && i < 19; )
2007c478bd9Sstevel@tonic-gate 		cps[++i] = strtok(NULL, " \b\t\r\n");
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 	cpp = cps;
2037c478bd9Sstevel@tonic-gate 	if (!*cpp)
2047c478bd9Sstevel@tonic-gate 		return 1;
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	c = **cpp;
207ab25eeb5Syz 	if (!ISALPHA(c) || (TOLOWER(c) != 'o' && TOLOWER(c) != 'i')) {
2087c478bd9Sstevel@tonic-gate 		fprintf(stderr, "bad direction \"%s\"\n", *cpp);
2097c478bd9Sstevel@tonic-gate 		return 1;
2107c478bd9Sstevel@tonic-gate 	}
211ab25eeb5Syz 	*out = (TOLOWER(c) == 'o') ? 1 : 0;
2127c478bd9Sstevel@tonic-gate 	cpp++;
2137c478bd9Sstevel@tonic-gate 	if (!*cpp)
2147c478bd9Sstevel@tonic-gate 		return 1;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	if (!strcasecmp(*cpp, "on")) {
2177c478bd9Sstevel@tonic-gate 		cpp++;
2187c478bd9Sstevel@tonic-gate 		if (!*cpp)
2197c478bd9Sstevel@tonic-gate 			return 1;
2207c478bd9Sstevel@tonic-gate 		*ifn = strdup(*cpp++);
2217c478bd9Sstevel@tonic-gate 		if (!*cpp)
2227c478bd9Sstevel@tonic-gate 			return 1;
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	c = **cpp;
2267c478bd9Sstevel@tonic-gate 	ip->ip_len = sizeof(ip_t);
2277c478bd9Sstevel@tonic-gate 	if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") ||
2287c478bd9Sstevel@tonic-gate 	    !strcasecmp(*cpp, "icmp")) {
2297c478bd9Sstevel@tonic-gate 		if (c == 't') {
2307c478bd9Sstevel@tonic-gate 			ip->ip_p = IPPROTO_TCP;
2317c478bd9Sstevel@tonic-gate 			ip->ip_len += sizeof(struct tcphdr);
2327c478bd9Sstevel@tonic-gate 			tx_proto = "tcp";
2337c478bd9Sstevel@tonic-gate 		} else if (c == 'u') {
2347c478bd9Sstevel@tonic-gate 			ip->ip_p = IPPROTO_UDP;
2357c478bd9Sstevel@tonic-gate 			ip->ip_len += sizeof(struct udphdr);
2367c478bd9Sstevel@tonic-gate 			tx_proto = "udp";
2377c478bd9Sstevel@tonic-gate 		} else {
2387c478bd9Sstevel@tonic-gate 			ip->ip_p = IPPROTO_ICMP;
2397c478bd9Sstevel@tonic-gate 			ip->ip_len += ICMPERR_IPICMPHLEN;
2407c478bd9Sstevel@tonic-gate 			tx_proto = "icmp";
2417c478bd9Sstevel@tonic-gate 		}
2427c478bd9Sstevel@tonic-gate 		cpp++;
243ab25eeb5Syz 	} else if (ISDIGIT(**cpp) && !index(*cpp, '.')) {
2447c478bd9Sstevel@tonic-gate 		ip->ip_p = atoi(*cpp);
2457c478bd9Sstevel@tonic-gate 		cpp++;
2467c478bd9Sstevel@tonic-gate 	} else
2477c478bd9Sstevel@tonic-gate 		ip->ip_p = IPPROTO_IP;
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 	if (!*cpp)
2507c478bd9Sstevel@tonic-gate 		return 1;
2517c478bd9Sstevel@tonic-gate 	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) {
2527c478bd9Sstevel@tonic-gate 		char	*last;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 		last = strchr(*cpp, ',');
2557c478bd9Sstevel@tonic-gate 		if (!last) {
2567c478bd9Sstevel@tonic-gate 			fprintf(stderr, "tcp/udp with no source port\n");
2577c478bd9Sstevel@tonic-gate 			return 1;
2587c478bd9Sstevel@tonic-gate 		}
2597c478bd9Sstevel@tonic-gate 		*last++ = '\0';
2607c478bd9Sstevel@tonic-gate 		tcp->th_sport = htons(tx_portnum(last));
261ab25eeb5Syz 		if (ip->ip_p == IPPROTO_TCP) {
262ab25eeb5Syz 			tcp->th_win = htons(4096);
263ab25eeb5Syz 			TCP_OFF_A(tcp, sizeof(*tcp) >> 2);
264ab25eeb5Syz 		}
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 	ip->ip_src.s_addr = tx_hostnum(*cpp, &r);
2677c478bd9Sstevel@tonic-gate 	cpp++;
2687c478bd9Sstevel@tonic-gate 	if (!*cpp)
2697c478bd9Sstevel@tonic-gate 		return 1;
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) {
2727c478bd9Sstevel@tonic-gate 		char	*last;
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 		last = strchr(*cpp, ',');
2757c478bd9Sstevel@tonic-gate 		if (!last) {
2767c478bd9Sstevel@tonic-gate 			fprintf(stderr, "tcp/udp with no destination port\n");
2777c478bd9Sstevel@tonic-gate 			return 1;
2787c478bd9Sstevel@tonic-gate 		}
2797c478bd9Sstevel@tonic-gate 		*last++ = '\0';
2807c478bd9Sstevel@tonic-gate 		tcp->th_dport = htons(tx_portnum(last));
2817c478bd9Sstevel@tonic-gate 	}
2827c478bd9Sstevel@tonic-gate 	ip->ip_dst.s_addr = tx_hostnum(*cpp, &r);
2837c478bd9Sstevel@tonic-gate 	cpp++;
2847c478bd9Sstevel@tonic-gate 	if (*cpp && ip->ip_p == IPPROTO_TCP) {
2857c478bd9Sstevel@tonic-gate 		char	*s, *t;
2867c478bd9Sstevel@tonic-gate 
287ab25eeb5Syz 		tcp->th_flags = 0;
2887c478bd9Sstevel@tonic-gate 		for (s = *cpp; *s; s++)
289ab25eeb5Syz 			if ((t  = strchr(myflagset, *s)))
290ab25eeb5Syz 				tcp->th_flags |= myflags[t - myflagset];
2917c478bd9Sstevel@tonic-gate 		if (tcp->th_flags)
2927c478bd9Sstevel@tonic-gate 			cpp++;
2937c478bd9Sstevel@tonic-gate 		if (tcp->th_flags == 0)
2947c478bd9Sstevel@tonic-gate 			abort();
295ab25eeb5Syz 		if (tcp->th_flags & TH_URG)
296ab25eeb5Syz 			tcp->th_urp = htons(1);
2977c478bd9Sstevel@tonic-gate 	} else if (*cpp && ip->ip_p == IPPROTO_ICMP) {
2987c478bd9Sstevel@tonic-gate 		extern	char	*tx_icmptypes[];
2997c478bd9Sstevel@tonic-gate 		char	**s, *t;
3007c478bd9Sstevel@tonic-gate 		int	i;
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 		for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END");
3037c478bd9Sstevel@tonic-gate 		     s++, i++)
3047c478bd9Sstevel@tonic-gate 			if (*s && !strncasecmp(*cpp, *s, strlen(*s))) {
3057c478bd9Sstevel@tonic-gate 				ic->icmp_type = i;
3067c478bd9Sstevel@tonic-gate 				if ((t = strchr(*cpp, ',')))
3077c478bd9Sstevel@tonic-gate 					ic->icmp_code = atoi(t+1);
3087c478bd9Sstevel@tonic-gate 				cpp++;
3097c478bd9Sstevel@tonic-gate 				break;
3107c478bd9Sstevel@tonic-gate 			}
3117c478bd9Sstevel@tonic-gate 	}
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	if (*cpp && !strcasecmp(*cpp, "opt")) {
3147c478bd9Sstevel@tonic-gate 		u_long	olen;
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 		cpp++;
3177c478bd9Sstevel@tonic-gate 		olen = buildopts(*cpp, ipopts, (IP_HL(ip) - 5) << 2);
3187c478bd9Sstevel@tonic-gate 		if (olen) {
3197c478bd9Sstevel@tonic-gate 			bcopy(ipopts, (char *)(ip + 1), olen);
3207c478bd9Sstevel@tonic-gate 			IP_HL_A(ip, IP_HL(ip) + (olen >> 2));
3217c478bd9Sstevel@tonic-gate 		}
3227c478bd9Sstevel@tonic-gate 	}
3237c478bd9Sstevel@tonic-gate 	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
3247c478bd9Sstevel@tonic-gate 		bcopy((char *)tcp, ((char *)ip) + (IP_HL(ip) << 2),
3257c478bd9Sstevel@tonic-gate 			sizeof(*tcp));
3267c478bd9Sstevel@tonic-gate 	else if (ip->ip_p == IPPROTO_ICMP)
3277c478bd9Sstevel@tonic-gate 		bcopy((char *)ic, ((char *)ip) + (IP_HL(ip) << 2),
3287c478bd9Sstevel@tonic-gate 			sizeof(*ic));
3297c478bd9Sstevel@tonic-gate 	ip->ip_len = htons(ip->ip_len);
3307c478bd9Sstevel@tonic-gate 	return 0;
3317c478bd9Sstevel@tonic-gate }
332