Add an ICMP protocol handler, partly based on LBL's traceroute 1.4 .
Submitted by: dcs
This commit is contained in:
parent
88c39af35f
commit
290006640b
@ -109,7 +109,7 @@ path).
|
||||
.TP
|
||||
.B \-P
|
||||
Send packets of specified IP protocol. The currently supported protocols
|
||||
are: UDP, TCP and GRE. Other protocols may also be specified (either by
|
||||
are: UDP, TCP, GRE and ICMP. Other protocols may also be specified (either by
|
||||
name or by number), though
|
||||
.I traceroute
|
||||
does not implement any special knowledge of their packet formats. This
|
||||
|
@ -275,6 +275,7 @@ struct outdata {
|
||||
u_char seq; /* sequence number of this packet */
|
||||
u_char ttl; /* ttl packet left with */
|
||||
struct timeval tv; /* time packet left */
|
||||
int optlen; /* length of ip options */
|
||||
};
|
||||
|
||||
/* Descriptor structure for each outgoing protocol we support */
|
||||
@ -326,6 +327,7 @@ extern char *optarg;
|
||||
|
||||
/* Forwards */
|
||||
double deltaT(struct timeval *, struct timeval *);
|
||||
u_short in_cksum(u_short *, int);
|
||||
char *inetname(struct in_addr);
|
||||
int main(int, char **);
|
||||
int packet_ok(u_char *, int, struct sockaddr_in *, int);
|
||||
@ -350,6 +352,8 @@ void gre_prep(struct outdata *);
|
||||
int gre_check(const u_char *, int);
|
||||
void gen_prep(struct outdata *);
|
||||
int gen_check(const u_char *, int);
|
||||
void icmp_prep(struct outdata *);
|
||||
int icmp_check(const u_char *, int);
|
||||
|
||||
/* List of supported protocols. The first one is the default. The last
|
||||
one is the handler for generic protocols not explicitly listed. */
|
||||
@ -378,6 +382,14 @@ struct outproto protos[] = {
|
||||
gre_prep,
|
||||
gre_check
|
||||
},
|
||||
{
|
||||
"icmp",
|
||||
IPPROTO_ICMP,
|
||||
sizeof(struct icmp),
|
||||
0,
|
||||
icmp_prep,
|
||||
icmp_check
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
0,
|
||||
@ -785,6 +797,7 @@ main(int argc, char **argv)
|
||||
/* Prepare outgoing data */
|
||||
outdata.seq = ++seq;
|
||||
outdata.ttl = ttl;
|
||||
outdata.optlen = optlen;
|
||||
|
||||
/* Avoid alignment problems by copying bytewise: */
|
||||
(void)gettimeofday(&t1, &tz);
|
||||
@ -820,9 +833,21 @@ main(int argc, char **argv)
|
||||
#endif
|
||||
precis = 3;
|
||||
Printf(" %.*f ms", precis, T);
|
||||
if (i == -2) {
|
||||
#ifdef 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) {
|
||||
|
||||
@ -1030,6 +1055,10 @@ packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
|
||||
#endif
|
||||
type = icp->icmp_type;
|
||||
code = icp->icmp_code;
|
||||
if (type == ICMP_ECHOREPLY
|
||||
&& proto->num == IPPROTO_ICMP
|
||||
&& (*proto->check)((u_char *)icp,seq))
|
||||
return -2;
|
||||
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
|
||||
type == ICMP_UNREACH) {
|
||||
struct ip *hip;
|
||||
@ -1058,6 +1087,32 @@ packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
icmp_prep(struct outdata *outdata)
|
||||
{
|
||||
struct icmp *const icmpheader = (struct icmp *) outprot;
|
||||
|
||||
icmpheader->icmp_type = ICMP_ECHO;
|
||||
icmpheader->icmp_id = htons(ident);
|
||||
icmpheader->icmp_seq = htons(outdata->seq);
|
||||
|
||||
icmpheader->icmp_cksum = 0;
|
||||
icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader,
|
||||
packlen - (sizeof(*outip) + outdata->optlen));
|
||||
if (icmpheader->icmp_cksum == 0)
|
||||
icmpheader->icmp_cksum = 0xffff;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
icmp_check(const u_char *data, int seq)
|
||||
{
|
||||
struct icmp *const icmpheader = (struct icmp *) data;
|
||||
|
||||
return (icmpheader->icmp_id == htons(ident)
|
||||
&& icmpheader->icmp_seq == htons(seq));
|
||||
}
|
||||
|
||||
void
|
||||
udp_prep(struct outdata *outdata)
|
||||
{
|
||||
@ -1157,11 +1212,10 @@ print(register u_char *buf, register int cc, register struct sockaddr_in *from)
|
||||
Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
|
||||
}
|
||||
|
||||
|
||||
#ifdef notyet
|
||||
/*
|
||||
* Checksum routine for Internet Protocol family headers (C Version)
|
||||
*/
|
||||
u_short
|
||||
in_cksum(register u_short *addr, register int len)
|
||||
{
|
||||
register int nleft = len;
|
||||
@ -1192,7 +1246,6 @@ in_cksum(register u_short *addr, register int len)
|
||||
answer = ~sum; /* truncate to 16 bits */
|
||||
return (answer);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Subtract 2 timeval structs: out = out - in.
|
||||
|
Loading…
Reference in New Issue
Block a user