rem: for (i = 1; i <= lsrr; i++) *((struct in_addr *)p)++ = gateway[i];
add: for (i = 1; i <= lsrr; i++) { *(struct in_addr *)p = gateway[i]; p = (u_char*)((struct in_addr *)p + 1); }
context: int main(int argc, char **argv){	struct hostent *hp;	struct protoent *pe;	struct sockaddr_in from, to;	int ch, i, lsrr, on, probe, seq, tos, ttl, ttl_flag, incflag = 1;	struct ip *ip;	uint32 tmprnd;	int sump = 0;	if ((pe = getprotobyname("icmp")) == NULL) {		Fprintf(stderr, "icmp: unknown protocol\n");		exit(10);	}	if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)		err(5, "icmp socket");	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)		err(5, "raw socket");	/* revoke privs *///	seteuid(getuid());//	setuid(getuid());	ttl_flag = 0;	lsrr = 0;	on = 1;	seq = tos = 0;	while ((ch = getopt(argc, argv, "SDIdg:f:m:np:q:rs:t:w:vlP:c")) != -1)		switch (ch) {		case 'S':			sump = 1;			break;		case 'f':			first_ttl = atoi(optarg);			if (first_ttl < 1 || first_ttl > max_ttl) {				printf("min ttl must be 1 to %d.", max_ttl);				exit(1);			}			break;		case 'c':			incflag = 0;			break;		case 'd':			options |= SO_DEBUG;			break;		case 'D':			dump = 1;			break;		case 'g':			if (lsrr >= MAX_LSRR) {				printf("too many gateways; max %d", MAX_LSRR);				exit(1);			}			if (inet_aton(optarg, &gateway[lsrr]) == 0) {				hp = gethostbyname(optarg);				if (hp == 0)					errx(1, "unknown host %s", optarg);				memcpy(&gateway[lsrr], hp->h_addr, hp->h_length);			}			if (++lsrr == 1)				lsrrlen = 4;			lsrrlen += 4;			break;		case 'I':			proto = IPPROTO_ICMP;			break;		case 'l':			ttl_flag++;			break;		case 'm':			max_ttl = atoi(optarg);			if (max_ttl < first_ttl || max_ttl > MAXTTL) {				printf("max ttl must be %d to %d.", first_ttl,				    MAXTTL);				exit(1);			}			break;		case 'n':			nflag++;			break;		case 'p':			port = atoi(optarg);			if (port < 1)				err(1, "port must be >0.");			break;		case 'P':			proto = atoi(optarg);			if (proto < 1) {				struct protoent *pent;				pent = getprotobyname(optarg);				if (pent)					proto = pent->p_proto;				else					err(1, "proto must be >=1, or a name.");			}			break;		case 'q':			nprobes = atoi(optarg);			if (nprobes < 1)				err(1, "nprobes must be >0.");			break;		case 'r':			options |= SO_DONTROUTE;			break;		case 's':			/*			 * set the ip source address of the outbound			 * probe (e.g., on a multi-homed host).			 */			source = optarg;			break;		case 't':			tos = atoi(optarg);			if (tos < 0 || tos > 255)				err(1, "tos must be 0 to 255.");			break;		case 'v':			verbose++;			break;		case 'w':			waittime = atoi(optarg);			if (waittime <= 1)				err(1, "wait must be >1 sec.");			break;		default:			usage();		}	argc -= optind;	argv += optind;	if (argc < 1)		usage();	setlinebuf (stdout);	(void) memset(&to, 0, sizeof(struct sockaddr));	to.sin_family = AF_INET;	if (inet_aton(*argv, &to.sin_addr) != 0)		hostname = *argv;	else {		hp = gethostbyname(*argv);		if (hp == 0)			errx(1, "unknown host %s", *argv);		to.sin_family = hp->h_addrtype;		memcpy(&to.sin_addr, hp->h_addr, hp->h_length);		if ((hostname = strdup(hp->h_name)) == NULL)			err(1, "malloc");	}	if (*++argv)		datalen = atoi(*argv);	switch (proto) {	case IPPROTO_UDP:		headerlen = (sizeof(struct ip) + lsrrlen +		    sizeof(struct udphdr) + sizeof(struct packetdata));		break;	case IPPROTO_ICMP:		headerlen = (sizeof(struct ip) + lsrrlen +		    sizeof(struct icmp) + sizeof(struct packetdata));		break;	default:		headerlen = (sizeof(struct ip) + lsrrlen +		    sizeof(struct packetdata));	}	if (datalen < 0 || datalen > IP_MAXPACKET - headerlen) {		printf("packet size must be 0 to %d.",		    IP_MAXPACKET - headerlen);		exit(1);	}	datalen += headerlen;	outpacket = (u_char *)malloc(datalen);	if (outpacket == 0)		err(1, "malloc");	(void) memset(outpacket, 0, datalen);	ip = (struct ip *)outpacket;	if (lsrr != 0) {		u_char *p;		p = (u_char *)(ip + 1);		*p++ = IPOPT_NOP;		*p++ = IPOPT_LSRR;		*p++ = lsrrlen - 1;		*p++ = IPOPT_MINOFF;		gateway[lsrr] = to.sin_addr;		for (i = 1; i <= lsrr; i++)			*((struct in_addr *)p)++ = gateway[i];		ip->ip_dst = gateway[0];	} else		ip->ip_dst = to.sin_addr;	ip->ip_off = htons(0);	ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2;	ip->ip_p = proto;	ip->ip_v = IPVERSION;	ip->ip_tos = tos;	ident = (getpid() & 0xffff) | 0x8000;	tmprnd = arc4random();	sec_perturb = (tmprnd & 0x80000000) ? -(tmprnd & 0x7ff) :						(tmprnd & 0x7ff);	usec_perturb = arc4random();	if (options & SO_DEBUG)		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,				  (char *)&on, sizeof(on));	if (options & SO_DONTROUTE)		(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,				  (char *)&on, sizeof(on));#ifdef SO_SNDBUF	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,	    sizeof(datalen)) < 0)		err(6, "SO_SNDBUF");#endif /* SO_SNDBUF */#ifdef IP_HDRINCL	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,	    sizeof(on)) < 0)		err(6, "IP_HDRINCL");#endif /* IP_HDRINCL */	if (options & SO_DEBUG)		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,				  (char *)&on, sizeof(on));	if (options & SO_DONTROUTE)		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,				  (char *)&on, sizeof(on));	if (source) {		(void) memset(&from, 0, sizeof(struct sockaddr));		from.sin_family = AF_INET;		if (inet_aton(source, &from.sin_addr) == 0)			errx(1, "unknown host %s", source);		ip->ip_src = from.sin_addr;		if (getuid() != 0 &&		    (ntohl(from.sin_addr.s_addr) & 0xff000000U) == 0x7f000000U &&		    (ntohl(to.sin_addr.s_addr) & 0xff000000U) != 0x7f000000U)			err(1, "source is on 127/8, destination is not");		if (getuid() &&		    bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)			err(1, "bind");	}	Fprintf(stderr, "traceroute to %s (%s)", hostname,		inet_ntoa(to.sin_addr));	if (source)		Fprintf(stderr, " from %s", source);	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);	(void) fflush(stderr);	if (first_ttl > 1)		Printf("Skipping %d intermediate hops\n", first_ttl - 1);	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {		in_addr_t lastaddr = 0;		int got_there = 0;		int unreachable = 0;		int timeout = 0;		uint64 dt;		int loss;		Printf("%2d ", ttl);		for (probe = 0, loss = 0; probe < nprobes; ++probe) {			int cc;			struct timeval t1, t2;			struct timezone tz;			int code;			(void) gettimeofday(&t1, &tz);			send_probe(++seq, ttl, incflag, &to);			while ((cc = wait_for_reply(s, &from, &t1))) {				(void) gettimeofday(&t2, &tz);				if (t2.tv_sec - t1.tv_sec > waittime) {					cc = 0;					break;				}				i = packet_ok(packet, cc, &from, seq, incflag);				/* Skip short packet */				if (i == 0)					continue;				if (from.sin_addr.s_addr != lastaddr) {					print(packet, cc, &from);					lastaddr = from.sin_addr.s_addr;				}				dt = (uint64)(t2.tv_sec - t1.tv_sec) * 1000000					+ (uint64)(t2.tv_usec - t1.tv_usec);				Printf("  %u", (u_int)(dt / 1000));				if (dt % 1000)					Printf(".%u", (u_int)(dt % 1000));				Printf(" ms");				ip = (struct ip *)packet;				if (ttl_flag)					Printf(" (%d)", ip->ip_ttl);				if (i == -2) {#ifndef ARCHAIC					ip = (struct ip *)packet;					if (ip->ip_ttl <= 1)						Printf(" !");#endif					++got_there;					break;				}				/* time exceeded in transit */				if (i == -1)					break;				code = i - 1;				switch (code) {				case ICMP_UNREACH_PORT:#ifndef ARCHAIC					ip = (struct ip *)packet;					if (ip->ip_ttl <= 1)						Printf(" !");#endif /* ARCHAIC */					++got_there;					break;				case ICMP_UNREACH_NET:					++unreachable;					Printf(" !N");					break;				case ICMP_UNREACH_HOST:					++unreachable;					Printf(" !H");					break;				case ICMP_UNREACH_PROTOCOL:					++got_there;					Printf(" !P");					break;				case ICMP_UNREACH_NEEDFRAG:					++unreachable;					Printf(" !F");					break;				case ICMP_UNREACH_SRCFAIL:					++unreachable;					Printf(" !S");					break;				case ICMP_UNREACH_FILTER_PROHIB:				case ICMP_UNREACH_NET_PROHIB: /*misuse*/					++unreachable;					Printf(" !A");					break;				case ICMP_UNREACH_HOST_PROHIB:					++unreachable;					Printf(" !C");					break;				case ICMP_UNREACH_NET_UNKNOWN:				case ICMP_UNREACH_HOST_UNKNOWN:					++unreachable;					Printf(" !U");					break;				case ICMP_UNREACH_ISOLATED:					++unreachable;					Printf(" !I");					break;				case ICMP_UNREACH_TOSNET:				case ICMP_UNREACH_TOSHOST:					++unreachable;					Printf(" !T");					break;				default:					++unreachable;					Printf(" !<%d>", i - 1);					break;				}				break;			}			if (cc == 0) {				Printf(" *");				timeout++;				loss++;			}			(void) fflush(stdout);		}		if (sump)			Printf(" (%d%% loss)", (loss * 100) / nprobes);		putchar('\n');		if (got_there || (unreachable && (unreachable + timeout) >= nprobes))			break;	}	exit(0);}