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(<v, &tz);
send_probe(++seq, ttl);
while (cc = wait_for_reply(s, &from)) {
if ((i = packet_ok(lpacket, cc, &from, seq))) {
int dt = deltaT(<v);
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(<v, &tz);
tvsub(<v, 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);
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.