Hello,

I have made a patch set for ping(8). I'll appreciate your comments.

I did not include patches #3 and #4, they are stylistic mostly (based
on BDE's style patch).

A cumulative patch is there:

http://people.freebsd.org/~maxim/p.cumulative

#1, Print strict source routing option. Requested by David Wang
<[EMAIL PROTECTED]>.

Index: ping.c
===================================================================
RCS file: /home/maxim/cvs/ping/ping.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ping.c      15 Oct 2002 11:56:58 -0000      1.1
+++ ping.c      15 Oct 2002 11:57:53 -0000      1.2
@@ -953,7 +953,9 @@
                        hlen = 0;
                        break;
                case IPOPT_LSRR:
-                       (void)printf("\nLSRR: ");
+               case IPOPT_SSRR:
+                       (void)printf(*cp == IPOPT_LSRR ?
+                           "\nLSRR: " : "\nSSRR: ");
                        j = cp[IPOPT_OLEN] - IPOPT_MINOFF + 1;
                        hlen -= 2;
                        cp += 2;

%%%

#2, Implement -D (do not fragment) and -z (TOS) options. Obtained from
OpenBSD, bin/35843.

Index: ping.c
===================================================================
RCS file: /home/maxim/cvs/ping/ping.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ping.c      15 Oct 2002 11:57:53 -0000      1.2
+++ ping.c      15 Oct 2002 12:04:10 -0000      1.3
@@ -67,6 +67,7 @@
  */

 #include <sys/param.h>         /* NB: we rely on this for <sys/types.h> */
+#include <sys/sysctl.h>

 #include <ctype.h>
 #include <err.h>
@@ -107,6 +108,7 @@
 #define        MAXPAYLOAD      (IP_MAXPACKET - MAXIPLEN - MINICMPLEN)
 #define        MAXWAIT         10              /* max seconds to wait for response */
 #define        MAXALARM        (60 * 60)       /* max seconds for alarm timeout */
+#define        MAXTOS          255

 #define        A(bit)          rcvd_tbl[(bit)>>3]      /* identify byte in array */
 #define        B(bit)          (1 << ((bit) & 0x07))   /* identify bit in byte */
@@ -138,6 +140,7 @@
 #define        F_TTL           0x8000
 #define        F_MISSED        0x10000
 #define        F_ONCE          0x20000
+#define        F_HDRINCL       0x40000

 /*
  * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
@@ -151,7 +154,7 @@
 struct sockaddr_in whereto;    /* who to ping */
 int datalen = DEFDATALEN;
 int s;                         /* socket file descriptor */
-u_char outpack[MINICMPLEN + MAXPAYLOAD];
+u_char outpackhdr[IP_MAXPACKET], *outpack;
 char BSPACE = '\b';            /* characters written for flood */
 char BBELL = '\a';             /* characters written for MISSED and AUDIBLE */
 char DOT = '.';
@@ -201,6 +204,7 @@
 {
        struct in_addr ifaddr;
        struct iovec iov;
+       struct ip *ip;
        struct msghdr msg;
        struct sigaction si_sa;
        struct sockaddr_in from, sin;
@@ -209,13 +213,15 @@
        struct hostent *hp;
        struct sockaddr_in *to;
        double t;
+       size_t sz;
        u_char *datap, packet[IP_MAXPACKET];
        char *ep, *source, *target;
 #ifdef IPSEC_POLICY_IPSEC
        char *policy_in, *policy_out;
 #endif
        u_long alarmtimeout, ultmp;
-       int ch, hold, i, packlen, preload, sockerrno, almost_done = 0, ttl;
+       int ch, df, hold, i, mib[4], packlen, preload, sockerrno,
+           almost_done = 0, tos, ttl;
        char ctrl[CMSG_SPACE(sizeof(struct timeval))];
        char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN];
 #ifdef IP_OPTIONS
@@ -239,11 +245,12 @@
        setuid(getuid());
        uid = getuid();

-       alarmtimeout = preload = 0;
+       alarmtimeout = df = preload = tos = 0;

+       outpack = outpackhdr + sizeof(struct ip);
        datap = &outpack[MINICMPLEN + PHDR_LEN];
        while ((ch = getopt(argc, argv,
-               "AI:LQRS:T:c:adfi:l:m:nop:qrs:t:v"
+               "ADI:LQRS:T:c:adfi:l:m:nop:qrs:t:vz:"
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
                "P:"
@@ -266,6 +273,10 @@
                                    optarg);
                        npackets = ultmp;
                        break;
+               case 'D':
+                       options |= F_HDRINCL;
+                       df = 1;
+                       break;
                case 'd':
                        options |= F_SO_DEBUG;
                        break;
@@ -390,6 +401,13 @@
                        else
                                errx(1, "invalid security policy");
                        break;
+               case 'z':
+                       options |= F_HDRINCL;
+                       ultmp = strtoul(optarg, &ep, 0);
+                       if (*ep || ep == optarg || ultmp > MAXTOS)
+                               errx(EX_USAGE, "invalid TOS: `%s'", optarg);
+                       tos = ultmp;
+                       break;
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif /*IPSEC*/
                default:
@@ -509,6 +527,28 @@
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif /*IPSEC*/

+       if (options & F_HDRINCL) {
+               ip = (struct ip*)outpackhdr;
+               if (!(options & (F_TTL | F_MTTL))) {
+                       mib[0] = CTL_NET;
+                       mib[1] = PF_INET;
+                       mib[2] = IPPROTO_IP;
+                       mib[3] = IPCTL_DEFTTL;
+                       sz = sizeof(ttl);
+                       if (sysctl(mib, 4, &ttl, &sz, NULL, 0) == -1)
+                               err(1, "sysctl(net.inet.ip.ttl)");
+               }
+               setsockopt(s, IPPROTO_IP, IP_HDRINCL, &hold, sizeof(hold));
+               ip->ip_v = IPVERSION;
+               ip->ip_hl = sizeof(struct ip) >> 2;
+               ip->ip_tos = tos;
+               ip->ip_id = 0;
+               ip->ip_off = df ? IP_DF : 0;
+               ip->ip_ttl = ttl;
+               ip->ip_p = IPPROTO_ICMP;
+               ip->ip_src.s_addr = source ? sin.sin_addr.s_addr : INADDR_ANY;
+               ip->ip_dst = to->sin_addr;
+        }
        /* record route option */
        if (options & F_RROUTE) {
 #ifdef IP_OPTIONS
@@ -758,9 +798,12 @@
 static void
 pinger(void)
 {
+       struct ip *ip;
        struct icmp *icp;
        int cc, i;
+       u_char *packet;

+       packet = outpack;
        icp = (struct icmp *)outpack;
        icp->icmp_type = ICMP_ECHO;
        icp->icmp_code = 0;
@@ -779,7 +822,14 @@
        /* compute ICMP checksum here */
        icp->icmp_cksum = in_cksum((u_short *)icp, cc);

-       i = sendto(s, (char *)outpack, cc, 0, (struct sockaddr *)&whereto,
+       if (options & F_HDRINCL) {
+               cc += sizeof(struct ip);
+               ip = (struct ip *)outpackhdr;
+               ip->ip_len = cc;
+               ip->ip_sum = in_cksum((u_short *)outpackhdr, cc);
+               packet = outpackhdr;
+       }
+       i = sendto(s, (char *)packet, cc, 0, (struct sockaddr *)&whereto,
            sizeof(whereto));

        if (i < 0 || i != cc)  {
@@ -1448,7 +1498,7 @@
 usage()
 {
        (void)fprintf(stderr, "%s\n%s\n%s\n",
-"usage: ping [-AQRadfnoqrv] [-c count] [-i wait] [-l preload] [-m ttl]",
+"usage: ping [-ADQRadfnoqrv] [-c count] [-i wait] [-l preload] [-m ttl]",
 "            [-p pattern] "
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
@@ -1456,6 +1506,6 @@
 #endif
 #endif
 "[-s packetsize] [-S src_addr] [-t timeout]",
-"            [host | [-L] [-I iface] [-T ttl] mcast-group]");
+"            [-z tos ] [host | [-L] [-I iface] [-T ttl] mcast-group]");
        exit(EX_USAGE);
 }
Index: ping.8
===================================================================
RCS file: /home/maxim/cvs/ping/ping.8,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ping.8      15 Oct 2002 11:56:58 -0000      1.1
+++ ping.8      15 Oct 2002 12:04:10 -0000      1.2
@@ -42,7 +42,7 @@
 packets to network hosts
 .Sh SYNOPSIS
 .Nm
-.Op Fl AQRadfnoqrv
+.Op Fl ADQRadfnoqrv
 .Op Fl c Ar count
 .Op Fl i Ar wait
 .Op Fl l Ar preload
@@ -52,6 +52,7 @@
 .Op Fl s Ar packetsize
 .Op Fl S Ar src_addr
 .Op Fl t Ar timeout
+.Op Fl z Ar tos
 .Bo
 .Ar host |
 .Op Fl L
@@ -111,6 +112,8 @@
 Set the
 .Dv SO_DEBUG
 option on the socket being used.
+.It Fl D
+Set the Don't Fragment bit.
 .It Fl f
 Flood ping.
 Outputs packets as fast as they come back or one hundred times per second,
@@ -252,6 +255,8 @@
 packets other than
 .Tn ECHO_RESPONSE
 that are received are listed.
+.It Fl z Ar tos
+Use the specified type of service.
 .El
 .Pp
 When using

%%%

#5 Do not constantify maximum payload size. It is 65467 with -R
(record route), and 65507 without it.

Index: ping.c
===================================================================
RCS file: /home/maxim/cvs/ping/ping.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ping.c      15 Oct 2002 12:04:40 -0000      1.5
+++ ping.c      15 Oct 2002 12:04:59 -0000      1.6
@@ -104,7 +104,6 @@
 #define        MAXIPLEN        (sizeof(struct ip) + MAX_IPOPTLEN)
 #define        MAXICMPLEN      (ICMP_ADVLENMIN + MAX_IPOPTLEN)
 #define        MINICMPLEN      ICMP_MINLEN
-#define        MAXPAYLOAD      (IP_MAXPACKET - MAXIPLEN - MINICMPLEN)
 #define        MAXWAIT         10              /* max seconds to wait for response */
 #define        MAXALARM        (60 * 60)       /* max seconds for alarm timeout */
 #define        MAXTOS          255
@@ -151,6 +150,7 @@
 char rcvd_tbl[MAX_DUP_CHK / 8];

 struct sockaddr_in whereto;    /* who to ping */
+long maxpayload;
 int datalen = DEFDATALEN;
 int s;                         /* socket file descriptor */
 u_char outpackhdr[IP_MAXPACKET], *outpack;
@@ -351,18 +351,16 @@
                        options |= F_SO_DONTROUTE;
                        break;
                case 's':               /* size of packet to send */
-                       if (uid) {
-                               errno = EPERM;
-                               err(EX_NOPERM, "-s flag");
-                       }
                        ultmp = strtoul(optarg, &ep, 0);
-                       if (ultmp > MAXPAYLOAD)
-                               errx(EX_USAGE,
-                                   "packet size too large: %lu > %u",
-                                   ultmp, MAXPAYLOAD);
                        if (*ep || ep == optarg)
                                errx(EX_USAGE, "invalid packet size: `%s'",
                                    optarg);
+                       if (uid != 0 && ultmp > DEFDATALEN) {
+                               errno = EPERM;
+                               err(EX_NOPERM,
+                                   "packet size too large: %lu > %u",
+                                   ultmp, DEFDATALEN);
+                       }
                        datalen = ultmp;
                        break;
                case 'S':
@@ -418,6 +416,12 @@
                usage();
        target = argv[optind];

+       maxpayload = IP_MAXPACKET - sizeof(struct ip) - MINICMPLEN;
+       if (options & F_RROUTE)
+               maxpayload -= MAX_IPOPTLEN;
+       if (datalen > maxpayload)
+               errx(EX_USAGE, "packet size too large: %lu > %u", datalen,
+                   maxpayload);
        if (source) {
                bzero((char *)&sin, sizeof(sin));
                sin.sin_family = AF_INET;
@@ -1476,7 +1480,7 @@
            &pat[13], &pat[14], &pat[15]);

        if (ii > 0)
-               for (kk = 0; kk <= MAXPAYLOAD - (PHDR_LEN + ii); kk += ii)
+               for (kk = 0; kk <= maxpayload - (PHDR_LEN + ii); kk += ii)
                        for (jj = 0; jj < ii; ++jj)
                                bp[jj + kk] = pat[jj];
        if (!(options & F_QUIET)) {
Index: ping.8
===================================================================
RCS file: /home/maxim/cvs/ping/ping.8,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ping.8      15 Oct 2002 12:04:10 -0000      1.2
+++ ping.8      15 Oct 2002 12:04:59 -0000      1.3
@@ -235,7 +235,7 @@
 with the 8 bytes of
 .Tn ICMP
 header data.
-Only the super-user may use this option.
+Only the super-user may specify values more then default.
 .It Fl S Ar src_addr
 Use the following IP address as the source address in outgoing packets.
 On hosts with more than one IP address, this option can be used to

%%%

Thank you very much.

-- 
Maxim Konovalov, MAcomnet, Internet Dept., system engineer
phone: +7 (095) 796-9079, mailto:[EMAIL PROTECTED]


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-net" in the body of the message

Reply via email to