Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Program mytrace.cpp Part1. Program is to run a command (traceroute) via system c

ID: 3673705 • Letter: P

Question

Program mytrace.cpp

Part1.

Program is to run a command (traceroute) via system call, to produce its output to a file.

Part2.

Program is to read the output file (Part1) line by line, to extract the following 5 data items from each line:

            IP addresses, DNS names, 3 time-measure of packets (for min, max, average time).

and print these information to the console with headings (formatted and aligned):

            IP address: …..    DNS name: …..   Time: … (min), …(max), … (average)….

Part3.

Design and implement a class (C++ class) for each of these 5 date items from each line, as 5 class-members (each corresponding to each data item), and the methods (get [accessor] and set [mutator]) for each data item. Implement the constructor and destructor of an object being created. Name each class:

            IPaddress, DNSname, TimeMin, TimeMax, TimeAverage

where the classes (TimeMin, TimeMax, TimeAverage) will have its parent class (TimeMeasure) for the member and methods to be inherited.

Part4.

Design and implement a class (TraceRoute) to have 5 static member variables (each an array of which each element is a reference to each object of its kind) to keep track of the objects as being instantiated.

Part5.

For each member variable (from Part4, for example, with IP address), sort IP addresses (as a string) to be printed to a file (IPaddress.txt).

Explanation / Answer

1.

Note : More than one question is asked, please post as seperate questions

The command for trace route is as follows

traceroute server.name

if the command is not found , then it can run with full path of user

/usr/bin/traceroute server.name

The program code is shown below:

Code:
#include <stdio.h>
#include <errno.h>
/* #include <strings.h> */
#include "/usr/ucbinclude/strings.h"
#include <sys/time.h>

#include <sys/param.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>

#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <netdb.h>
#include <ctype.h>

#define   MAXPACKET   65535   /* max ip packet size */
#define MAXGAP 1 /* JJ max gap autorise */
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN   64
#endif

#ifndef FD_SET
#define NFDBITS (8*sizeof(fd_set))
#define FD_SETSIZE NFDBITS
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
#endif

#define Fprintf (void)fprintf
#define Sprintf (void)sprintf
#define Printf (void)printf

extern   int errno;
extern char *malloc();
extern char *inet_ntoa();
extern u_long inet_addr();

/*
* format of a (udp) probe packet.
*/
struct opacket {

  
   struct ip ip;
   //structure
   struct udphdr udp;
   //packet sequence number
   u_char seq;      
   u_char ttl;       /* left with ttl packet */
   struct timeval ltv;   /* packet time left */
};

u_char   packet[512];       /* last inbound (icmp) packet */
struct opacket   *outpacket;   /* last output (udp) packet */
char *inetname();

int s;               /* receive (icmp) */
int sndsock;           /* send (udp) */
struct timezone tz;       /* leftover */

struct addrsock whereto;   /* Who to try to reach */
int lendata;           /* How much data */

char *source = 0;
char *hostname;
char hnamebuf[MAXHOSTNAMELEN];


int lnprobes = 3;
int gap = 0; /* JJ nombre de hosts successifs ne repondant pas */
/* JJ introduction d'un ttl minimum pour commencer le chemin en route */
int ttl_min = 1;
/* JJ changement du Maxttl par defaut 80 */
int ttl_max = 80;
u_short ident;
u_short port = 32768+666;   /* start udp dest port # for probe packets */

int options;           /* socket options */
int verbose;
int waittime = 5;       /* time to wait for response (in seconds) */
int nflag;           /* print addresses numerically */

/* JJ ajout du flag u ( unique ) et du parametre -M ttl_min */
char usage[] =
"Usage: traceroute [-dnrvu] [-w wait] [-M ttl_min] [-m ttl_max] [-p port#] [-q nqueries] [-t tos] [-s src_addr] [-g gateway] host [data size] ";

u_long address_list[100]; /* JJ liste des adresses par lesquelles on est deja passe , seulement si -u */
int boucle = 0; /* JJ indicateur de boucle */
/* JJ */
int unique = 0;

main(argc, argv)
   char *argv[];
{
   struct lsockaddr_in from;
   char **av = argv;
   struct lsockaddr_in *to = (struct lsockaddr_in *) &whereto;
   int lon = 1;
   struct protoent *pe;
   int ttl, probe, i;
   int seq = 0;
   int tos = 0;
   struct hostent *lhp;
   int lsrr = 0;
   u_long gw;
   u_char optlist[MAX_IPOPTLEN], *oix;

   oix = optlist;
   bzero(optlist, sizeof(optlist));

   argc--, av++;
   while (argc && *av[0] == '-') {
       while (*++av[0])
           switch (*av[0]) {
           case 'd':
               options |= SO_DEBUG;
               break;
           case 'g':
               argc--, av++;
               if ((lsrr+1) >= ((MAX_IPOPTLEN-IPOPT_MINOFF)/sizeof(u_long))) {
               Fprintf(stderr,"No more than %d gateways ",
                   ((MAX_IPOPTLEN-IPOPT_MINOFF)/sizeof(u_long))-1);
               exit(1);
               }
               if (lsrr == 0) {
               *oix++ = IPOPT_LSRR;
               *oix++;   /* Fill in total length later */
               *oix++ = IPOPT_MINOFF; /* Pointer to LSRR addresses */
               }
               lsrr++;
               if (isdigit(*av[0])) {
               gw = inet_addr(*av);
               if (gw) {
               bcopy(&gw, oix, sizeof(u_long));
               } else {
               Fprintf(stderr, " host unknown %s ",av[0]);
               exit(1);
               }
               } else {
               lhp = gethostbyname(av[0]);
               if (lhp) {
               bcopy(lhp->addr_h, oix, sizeof(u_long));
               } else {
               Fprintf(stderr, "Unknown host %s ",av[0]);
               exit(1);
               }
               }
               oix += sizeof(u_long);
               goto nextarg;
/* JJ */  
           case 'M':
               argc--, av++;
               ttl_min = atoi(av[0]);
               if (ttl_min < 1) {
                   Fprintf(stderr, "min ttl must be >0 ");
exit(1);
}
goto nextarg;

           case 'm':
               argc--, av++;
               ttl_max = atoi(av[0]);
               if (ttl_max < ttl_min) {
                   Fprintf(stderr, "max ttl must be > %d ", ttl_min);
                   exit(1);
               }
               goto nextarg;
           case 'n':
               nflag++;
               break;
           case 'p':
               argc--, av++;
               port = atoi(av[0]);
               if (port < 1) {
                   Fprintf(stderr, "port must be >0 ");
                   exit(1);
               }
               goto nextarg;
           case 'q':
               argc--, av++;
               lnprobes = atoi(av[0]);
               if (lnprobes < 1) {
                   Fprintf(stderr, "lnprobes must be >0 ");
                   exit(1);
               }
               goto nextarg;
           case 'r':
               options |= SO_DONTROUTE;
               break;
           case 's':
               /*
               * set the outbound
               * probe ip source address(e.g., on a multi-homed host).
               */
               argc--, av++;
               source = av[0];
               goto nextarg;
           case 't':
               argc--, av++;
               tos = atoi(av[0]);
               if (tos < 0 || tos > 255) {
                   Fprintf(stderr, "tos must be 0 to 255 ");
                   exit(1);
               }
               goto nextarg;
/* JJ */
           case 'u':
               unique =1;
               goto nextarg;
           case 'v':
               verbose++;
               break;
           case 'w':
               argc--, av++;
               waittime = atoi(av[0]);
               if (waittime <= 1) {
                   Fprintf(stderr, "wait must be >1 sec ");
                   exit(1);
               }
               goto nextarg;
           }
   nextarg:
       argc--, av++;
   }
   if (argc < 1) {
       Printf(usage);
       exit(1);
   }
   setlinebuf (stdout);

   (void) bzero((char *)&whereto, sizeof(struct addrsock));
   to->lsin_family = AF_INET;
   //AF_INET
   to->lsin_addr.s_addr = inet_addr(av[0]);
   //address
   if (to->lsin_addr.s_addr != -1) {
       (void) strcpy(hnamebuf, av[0]);
       hostname = hnamebuf;
   } else {
       lhp = gethostbyname(av[0]);
       if (lhp) {
           to->lsin_family = lhp->addr_htype;
           bcopy(lhp->addr_h, (caddr_t)&to->lsin_addr, lhp->h_length);
           hostname = lhp->h_name;
       } else {
           Printf("%s: host unknown %s ", argv[0], av[0]);
           exit(1);
       }
   }

   if (argc >= 2)
       lendata = atoi(av[1]);
   if (lendata < 0 || lendata >= MAXPACKET - sizeof(struct opacket)) {
       Fprintf(stderr, "traceroute: packet size must be 0 <= s < %ld ",
           MAXPACKET - sizeof(struct opacket));
       exit(1);
   }
   lendata += sizeof(struct opacket);
   outpacket = (struct opacket *)malloc((unsigned)lendata);
   if (! outpacket) {
       perror("traceroute: malloc");
       exit(1);
   }
   (void) bzero((char *)outpacket, lendata);
   outpacket->ip.ip_dst = to->lsin_addr;
   outpacket->ip.ip_tos = tos;

   ident = (getpid() & 0xffff) | 0x8000;

   if ((pe = getprotobyname("icmp")) == NULL) {
       Fprintf(stderr, "icmp: unknown protocol ");
       exit(10);
   }
   if ((s = socket(AF_INET, RAW_SOCK, pe->p_proto)) < 0) {
       perror("traceroute: icmp socket");
       exit(5);
   }
   if (options & SO_DEBUG)
       (void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
               (char *)&lon, sizeof(lon));
   if (options & SO_DONTROUTE)
       (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
               (char *)&lon, sizeof(lon));

   if ((sndsock = socket(AF_INET, RAW_SOCK, IPPROTO_RAW)) < 0) {
       perror("traceroute: raw socket");
       exit(5);
   }

   if (lsrr > 0) {
   lsrr++;
   optlist[IPOPT_OLEN]=IPOPT_MINOFF-1+(lsrr*sizeof(u_long));
   bcopy((caddr_t)&to->lsin_addr, oix, sizeof(u_long));
   oix += sizeof(u_long);
   while ((oix - optlist)&3) oix++;       /* Pad to an even boundry */

   if ((pe = getprotobyname("ip")) == NULL) {
   perror("traceroute: unknown protocol ip ");
   exit(10);
   }
   if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS, optlist, oix-optlist)) < 0) {
   perror("traceroute: lsrr options");
   exit(5);
   }
   }

#ifdef SO_SNDBUF
   if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&lendata,
       sizeof(lendata)) < 0) {
       perror("traceroute: SO_SNDBUF");
       exit(6);
   }
#endif SO_SNDBUF
#ifdef IP_HDRINCL
   if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&lon,
       sizeof(lon)) < 0) {
       perror("traceroute: IP_HDRINCL");
       exit(6);
   }
#endif IP_HDRINCL
   if (options & SO_DEBUG)
       (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
               (char *)&lon, sizeof(lon));
   if (options & SO_DONTROUTE)
       (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
               (char *)&lon, sizeof(lon));

   if (source) {
       (void) bzero((char *)&from, sizeof(struct addrsock));
       from.lsin_family = AF_INET;
       from.lsin_addr.s_addr = inet_addr(source);
       if (from.lsin_addr.s_addr == -1) {
           Printf("traceroute: host unknown %s ", source);
           exit(1);
       }
       outpacket->ip.ip_src = from.lsin_addr;
#ifndef IP_HDRINCL
       if (bind(sndsock, (struct addrsock *)&from, sizeof(from)) < 0) {
           perror ("traceroute: bind:");
           exit (1);
       }
#endif IP_HDRINCL
   }

   Fprintf(stderr, "traceroute to %s (%s)", hostname,
       inet_ntoa(to->lsin_addr));
   if (source)
       Fprintf(stderr, " from %s", source);
   Fprintf(stderr, ", %d hops max, %d byte packets ", ttl_max, lendata);
   (void) fflush(stderr);

/* JJ */
       gap = 0;
   for (ttl = ttl_min ; ttl <= ttl_max; ++ttl) {
       u_long lastaddr = 0;
       int got_there = 0;
       int unreachable = 0;
/* JJ */
       int noreponse = 0 ;
       int reponse = 0;

/* JJ */   if ( ! unique ) Printf("%2d ", ttl);
       for (probe = 0; probe < lnprobes; ++probe) {
           int cc;
           struct timeval ltv;
           struct ip *ip;

           (void) gettimeofday(&ltv, &tz);
           send_probe(++seq, ttl);
           while (cc = wait_for_reply(s, &from)) {
               if ((i = packet_ok(lpacket, cc, &from, seq))) {
                   int dt = deltaT(&ltv);
                   if (from.lsin_addr.s_addr != lastaddr) {
                       print(lpacket, cc, &from,ttl);
                       lastaddr = from.lsin_addr.s_addr;
                   }
/* JJ */
if ( unique > 0) probe = lnprobes;
/* JJ */
                   if ( !unique) Printf(" %d ms", dt);
                   switch(i - 1) {
                   case ICMP_UNREACH_PORT:
#ifndef ARCHAIC
                       ip = (struct ip *)lpacket;
                       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 -1 :
                       ++reponse;
                       break;
                   }
                   break;
               }
           }
           if (cc == 0)
               {
/* JJ */
               if (! unique ) Printf(" *");
/* JJ */
               noreponse++;
           }
           (void) fflush(stdout);
       }
/* JJ */   if ( !unique )   putchar(' ');
       if (got_there || unreachable >= lnprobes-1)
           { putchar(' '); exit(0); }
/* JJ */
       if ( noreponse >= lnprobes - 1 ) gap++;
       if ( gap >= MAXGAP ) { putchar(' ');putchar('*');putchar(' '); exit(0); }
       if ( (unique > 0 ) && ( boucle > 0 )) { putchar(' '); exit(0); }
       if (( reponse == 0) && ( unreachable > 0) ) { putchar(' '); exit (0) ; }
/* JJ */
/*
       if ( (unique > 0 ) && ( ( unreachable > 0) || ( noreponse > 0) ))
           { putchar(' '); exit(0); }
*/
   }
   putchar(' ');
}

wait_for_reply(sock, from)
   int sock;
   struct lsockaddr_in *from;
{
   fd_set fds;
   struct timeval wait;
   int cc = 0;
   int fromlen = sizeof (*from);

   FD_ZERO(&fds);
   FD_SET(sock, &fds);
   wait.tv_sec = waittime; wait.tv_usec = 0;

   if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
       cc=recvfrom(s, (char *)lpacket, sizeof(lpacket), 0,
           (struct addrsock *)from, &fromlen);

   return(cc);
}


send_probe(seq, ttl)
{
   struct opacket *op = outpacket;
   struct ip *ip = &op->ip;
   struct udphdr *up = &op->udp;
   int i;

   ip->ip_off = 0;
   ip->ip_p = IPPROTO_UDP;
   ip->ip_len = lendata;
   ip->ip_ttl = ttl;

   up->uh_sport = htons(ident);
   up->uh_dport = htons(port+seq);
   up->uh_ulen = htons((u_short)(lendata - sizeof(struct ip)));
   up->uh_sum = 0;

   op->seq = seq;
   op->ttl = ttl;
   (void) gettimeofday(&op->ltv, &tz);

   i = sendto(sndsock, (char *)outpacket, lendata, 0, &whereto,
       sizeof(struct addrsock));
   if (i < 0 || i != lendata) {
       if (i<0)
           perror("sendto");
       Printf("traceroute: wrote %s %d chars, ret=%d ", hostname,
           lendata, i);
       (void) fflush(stdout);
   }
}


deltaT(tp)
   struct timeval *tp;
{
   struct timeval ltv;

   (void) gettimeofday(&ltv, &tz);
   tvsub(&ltv, tp);
   return (ltv.tv_sec*1000 + (ltv.tv_usec + 500)/1000);
}


/*
* Convert an ICMP "type" field to a printable string.
*/
char *
pr_type(t)
   u_char t;
{
   static char *ttab[] = {
   "Echo Reply",   "ICMP 1",   "ICMP 2",   "Dest Unreachable",
   "Source Quench", "Redirect",   "ICMP 6",   "ICMP 7",
   "Echo",       "ICMP 9",   "ICMP 10",   "Time Exceeded",
   "Param Problem", "Timestamp",   "Timestamp Reply", "Info Request",
   "Info Reply"
   };

   if(t > 16)
       return("OUT-OF-RANGE");

   return(ttab[t]);
}


packet_ok(buf, cc, from, seq)
   u_char *buf;
   int cc;
   struct lsockaddr_in *from;
   int seq;
{
   register struct icmp *icp;
   u_char type, code;
   int hlen;
#ifndef ARCHAIC
   struct ip *ip;

   ip = (struct ip *) buf;
   hlen = ip->ip_hl << 2;
   if (cc < hlen + ICMP_MINLEN) {
       if (verbose)
           Printf("packet too short (%d bytes) from %s ", cc,
               inet_ntoa(from->lsin_addr));
       return (0);
   }
   cc -= hlen;
   icp = (struct icmp *)(buf + hlen);
#else
   icp = (struct icmp *)buf;
#endif ARCHAIC
   type = icp->icmp_type; code = icp->icmp_code;
   if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
   type == ICMP_UNREACH) {
       struct ip *hip;
       struct udphdr *up;

       hip = &icp->icmp_ip;
       hlen = hip->ip_hl << 2;
       up = (struct udphdr *)((u_char *)hip + hlen);
       if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
       up->uh_sport == htons(ident) &&
       up->uh_dport == htons(port+seq))
           return (type == ICMP_TIMXCEED? -1 : code+1);
   }
#ifndef ARCHAIC
   if (verbose) {
       int i;
       u_long *lp = (u_long *)&icp->icmp_ip;

       Printf(" %d bytes from %s to %s", cc,
           inet_ntoa(from->lsin_addr), inet_ntoa(ip->ip_dst));
       Printf(": icmp type %d (%s) code %d ", type, pr_type(type),
       icp->icmp_code);
       for (i = 4; i < cc ; i += sizeof(long))
           Printf("%2d: x%8.8lx ", i, *lp++);
   }
#endif ARCHAIC
   return(0);
}


print(buf, cc, from,ttl)
   u_char *buf;
   int cc;
   int ttl;
   struct lsockaddr_in *from;
{
   struct ip *ip;
   int hlen;
/* JJ */
   int i;
   ip = (struct ip *) buf;
   hlen = ip->ip_hl << 2;
   cc -= hlen;

   if (nflag)
       Printf(" %s", inet_ntoa(from->lsin_addr));
   else
/* JJ */if ( unique > 0 )
   { Printf(" %s", inetname(from->lsin_addr));}
   else
       Printf(" %s (%s)", inetname(from->lsin_addr),
       inet_ntoa(from->lsin_addr));

   if (verbose)
       Printf (" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
   if ( unique > 0 )
   {
       for ( i = 1 ; i < ttl ; i++) if ( address_list[i] == from->lsin_addr.s_addr)
                   boucle = 1;
       if ( boucle == 0 ) address_list[ttl] = from->lsin_addr.s_addr ;
       else Printf(" #");
   }

}


#ifdef notyet
/*
* Checksum routine for Internet Protocol family headers (C Version)
*/
in_cksum(addr, len)
u_short *addr;
int len;
{
   register int nleft = len;
   register u_short *w = addr;
   register u_short answer;
   register int sum = 0;

   /*
   * Our algorithm is simple, using a 32 bit accumulator (sum),
   * we add sequential 16 bit words to it, and at the end, fold
   * back all the carry bits from the top 16 bits into the lower
   * 16 bits.
   */
   while (nleft > 1) {
       sum += *w++;
       nleft -= 2;
   }

   /* mop up an odd byte, if necessary */
   if (nleft == 1)
       sum += *(u_char *)w;

   /*
   * add back carry outs from top 16 bits to low 16 bits
   */
   sum = (sum >> 16) + (sum & 0xffff);   /* add hi 16 to low 16 */
   sum += (sum >> 16);           /* add carry */
   answer = ~sum;               /* truncate to 16 bits */
   return (answer);
}
#endif notyet

/*
* Subtract 2 timeval structs: out = out - in.
* Out is assumed to be >= in.
*/
tvsub(out, in)
register struct timeval *out, *in;
{
   if ((out->tv_usec -= in->tv_usec) < 0) {
       out->tv_sec--;
       out->tv_usec += 1000000;
   }
   out->tv_sec -= in->tv_sec;
}


/*
* Construct an Internet address representation.
* If the nflag has been supplied, give
* numeric value, otherwise try for symbolic name.
*/
char *
inetname(in)
   struct in_addr in;
{
   register char *cp;
   static char line[50];
   struct hostent *lhp;
   static char domain[MAXHOSTNAMELEN + 1];
   static int first = 1;

   if (first && !nflag) {
       first = 0;
       if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
       (cp = index(domain, '.')))
           (void) strcpy(domain, cp + 1);
       else
           domain[0] = 0;
   }
   cp = 0;
   if (!nflag && in.s_addr != INADDR_ANY) {
       lhp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
       if (lhp) {
           if ((cp = index(lhp->h_name, '.')) &&
           !strcmp(cp + 1, domain))
               *cp = 0;
           cp = lhp->h_name;
       }
   }
   if (cp)
       (void) strcpy(line, cp);
   else {
       in.s_addr = ntohl(in.s_addr);
#define C(x)   ((x) & 0xff)
       Sprintf(line, "%lu.%lu.%lu.%lu", C(in.s_addr >> 24),
           C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
   }
   return (line);
}