mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
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
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=100535
@ -109,7 +109,7 @@ path).
|
|||||||
.TP
|
.TP
|
||||||
.B \-P
|
.B \-P
|
||||||
Send packets of specified IP protocol. The currently supported protocols
|
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
|
name or by number), though
|
||||||
.I traceroute
|
.I traceroute
|
||||||
does not implement any special knowledge of their packet formats. This
|
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 seq; /* sequence number of this packet */
|
||||||
u_char ttl; /* ttl packet left with */
|
u_char ttl; /* ttl packet left with */
|
||||||
struct timeval tv; /* time packet left */
|
struct timeval tv; /* time packet left */
|
||||||
|
int optlen; /* length of ip options */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Descriptor structure for each outgoing protocol we support */
|
/* Descriptor structure for each outgoing protocol we support */
|
||||||
@ -326,6 +327,7 @@ extern char *optarg;
|
|||||||
|
|
||||||
/* Forwards */
|
/* Forwards */
|
||||||
double deltaT(struct timeval *, struct timeval *);
|
double deltaT(struct timeval *, struct timeval *);
|
||||||
|
u_short in_cksum(u_short *, int);
|
||||||
char *inetname(struct in_addr);
|
char *inetname(struct in_addr);
|
||||||
int main(int, char **);
|
int main(int, char **);
|
||||||
int packet_ok(u_char *, int, struct sockaddr_in *, int);
|
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);
|
int gre_check(const u_char *, int);
|
||||||
void gen_prep(struct outdata *);
|
void gen_prep(struct outdata *);
|
||||||
int gen_check(const u_char *, int);
|
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
|
/* List of supported protocols. The first one is the default. The last
|
||||||
one is the handler for generic protocols not explicitly listed. */
|
one is the handler for generic protocols not explicitly listed. */
|
||||||
@ -378,6 +382,14 @@ struct outproto protos[] = {
|
|||||||
gre_prep,
|
gre_prep,
|
||||||
gre_check
|
gre_check
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"icmp",
|
||||||
|
IPPROTO_ICMP,
|
||||||
|
sizeof(struct icmp),
|
||||||
|
0,
|
||||||
|
icmp_prep,
|
||||||
|
icmp_check
|
||||||
|
},
|
||||||
{
|
{
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
@ -785,6 +797,7 @@ main(int argc, char **argv)
|
|||||||
/* Prepare outgoing data */
|
/* Prepare outgoing data */
|
||||||
outdata.seq = ++seq;
|
outdata.seq = ++seq;
|
||||||
outdata.ttl = ttl;
|
outdata.ttl = ttl;
|
||||||
|
outdata.optlen = optlen;
|
||||||
|
|
||||||
/* Avoid alignment problems by copying bytewise: */
|
/* Avoid alignment problems by copying bytewise: */
|
||||||
(void)gettimeofday(&t1, &tz);
|
(void)gettimeofday(&t1, &tz);
|
||||||
@ -820,9 +833,21 @@ main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
precis = 3;
|
precis = 3;
|
||||||
Printf(" %.*f ms", precis, T);
|
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 */
|
/* time exceeded in transit */
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
code = i - 1;
|
code = i - 1;
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
||||||
@ -1030,6 +1055,10 @@ packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
|
|||||||
#endif
|
#endif
|
||||||
type = icp->icmp_type;
|
type = icp->icmp_type;
|
||||||
code = icp->icmp_code;
|
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) ||
|
if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
|
||||||
type == ICMP_UNREACH) {
|
type == ICMP_UNREACH) {
|
||||||
struct ip *hip;
|
struct ip *hip;
|
||||||
@ -1058,6 +1087,32 @@ packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
|
|||||||
return(0);
|
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
|
void
|
||||||
udp_prep(struct outdata *outdata)
|
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));
|
Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef notyet
|
|
||||||
/*
|
/*
|
||||||
* Checksum routine for Internet Protocol family headers (C Version)
|
* Checksum routine for Internet Protocol family headers (C Version)
|
||||||
*/
|
*/
|
||||||
|
u_short
|
||||||
in_cksum(register u_short *addr, register int len)
|
in_cksum(register u_short *addr, register int len)
|
||||||
{
|
{
|
||||||
register int nleft = len;
|
register int nleft = len;
|
||||||
@ -1192,7 +1246,6 @@ in_cksum(register u_short *addr, register int len)
|
|||||||
answer = ~sum; /* truncate to 16 bits */
|
answer = ~sum; /* truncate to 16 bits */
|
||||||
return (answer);
|
return (answer);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Subtract 2 timeval structs: out = out - in.
|
* Subtract 2 timeval structs: out = out - in.
|
||||||
|
Loading…
Reference in New Issue
Block a user