From 55a529f50f59ea8eec1563a7dadbf19bde23dcc9 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:22:25 -0500 Subject: [PATCH 01/14] Create trout --- exercises/ex04/trout | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/ex04/trout diff --git a/exercises/ex04/trout b/exercises/ex04/trout new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/exercises/ex04/trout @@ -0,0 +1 @@ + From 49280c81694f0de04f5e1eba5c1005a76d432aa2 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:22:58 -0500 Subject: [PATCH 02/14] Delete trout --- exercises/ex04/trout | 1 - 1 file changed, 1 deletion(-) delete mode 100644 exercises/ex04/trout diff --git a/exercises/ex04/trout b/exercises/ex04/trout deleted file mode 100644 index 8b137891..00000000 --- a/exercises/ex04/trout +++ /dev/null @@ -1 +0,0 @@ - From 5acea19f44d9b745ac42f7e5ac4c736b4cbd8d1e Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:26:43 -0500 Subject: [PATCH 03/14] Create .#util.c --- exercises/ex04/trout/.#util.c | 1 + 1 file changed, 1 insertion(+) create mode 100644 exercises/ex04/trout/.#util.c diff --git a/exercises/ex04/trout/.#util.c b/exercises/ex04/trout/.#util.c new file mode 100644 index 00000000..206c9b5d --- /dev/null +++ b/exercises/ex04/trout/.#util.c @@ -0,0 +1 @@ +downey@rocky.colby.edu.25374:1 From 9774fe85656f5fe5b5d94268e1b7ef594c3e6d15 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:28:12 -0500 Subject: [PATCH 04/14] Create COPYRIGHT --- exercises/ex04/trout/COPYRIGHT | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 exercises/ex04/trout/COPYRIGHT diff --git a/exercises/ex04/trout/COPYRIGHT b/exercises/ex04/trout/COPYRIGHT new file mode 100644 index 00000000..6c703ce6 --- /dev/null +++ b/exercises/ex04/trout/COPYRIGHT @@ -0,0 +1,47 @@ +TROUT is a simple version of traceroute. + +It is based on code written by W. Richard Stevens and published in +"UNIX Network Programming Volume 1, Second Edition Networking APIs: +Sockets and XTI," Prentice Hall PTR, Upper Saddle River, NJ 07458. + +It has been modified a fair amount by Allen Downey +(downey@colby.edu). Among other things, I did the following + +1) I collected all the procedures from Stevens's extensive library + and put them in util.c, and put their prototypes in trout.h + +2) I killed all the IPv6 support, because I didn't need it and + because I hate ifdefs and pointers to functions. + +3) For the same reason, I took out some of the configuration + ifdefs. As a result, I don't know if this will still run + on anything other than Linux. + +4) I fixed a race condition that may or may not have been the + cause of some early problems I had. Anyway, the fix also + came from Stevens, in Section 18.5 of Unix Network Programming. + +5) I split things up into more procedures. + +The copyright for the original code is held by Prentice Hall, +but they make it available under a license that is more or +less identical to the GNU GPL. + +This version is Copyright (C) 1999 Allen B. Downey. + +I am making it available under the GNU General Public License +(which does not, I think, violate the original copyright). + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. From d5560128bb811776c7b675a33dc448e716258079 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:29:09 -0500 Subject: [PATCH 05/14] Checking in trout files --- exercises/ex04/trout/Makefile | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 exercises/ex04/trout/Makefile diff --git a/exercises/ex04/trout/Makefile b/exercises/ex04/trout/Makefile new file mode 100644 index 00000000..0fcbc669 --- /dev/null +++ b/exercises/ex04/trout/Makefile @@ -0,0 +1,2 @@ +trout: trout.h trout.c util.h util.c main.c + gcc -Wall -g -o trout trout.c main.c util.c From ce3197bb6aa1216d62dd9def8b52b0df11d90fd4 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:29:29 -0500 Subject: [PATCH 06/14] Checking in trout files --- exercises/ex04/trout/COPYRIGHT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ex04/trout/COPYRIGHT b/exercises/ex04/trout/COPYRIGHT index 6c703ce6..ec58690f 100644 --- a/exercises/ex04/trout/COPYRIGHT +++ b/exercises/ex04/trout/COPYRIGHT @@ -19,7 +19,7 @@ It has been modified a fair amount by Allen Downey 4) I fixed a race condition that may or may not have been the cause of some early problems I had. Anyway, the fix also - came from Stevens, in Section 18.5 of Unix Network Programming. + came from Stevens, in Section 18.5 of Unix Network Programming. 5) I split things up into more procedures. From 7818afe502541ecf0d7494a87b64fdd1eef842b8 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:29:49 -0500 Subject: [PATCH 07/14] Checking in trout files --- exercises/ex04/trout/.#util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/ex04/trout/.#util.c b/exercises/ex04/trout/.#util.c index 206c9b5d..c922e404 100644 --- a/exercises/ex04/trout/.#util.c +++ b/exercises/ex04/trout/.#util.c @@ -1 +1 @@ -downey@rocky.colby.edu.25374:1 +downey@rocky.colby.edu.25374:1 From 9cc1b03a301397639e02c5a7435984943d0955fd Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:30:29 -0500 Subject: [PATCH 08/14] Checking in trout files --- exercises/ex04/trout/main.c | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 exercises/ex04/trout/main.c diff --git a/exercises/ex04/trout/main.c b/exercises/ex04/trout/main.c new file mode 100644 index 00000000..b9551102 --- /dev/null +++ b/exercises/ex04/trout/main.c @@ -0,0 +1,45 @@ +#include "trout.h" + +int main (int argc, char **argv) +{ + int c; + struct addrinfo *ai; + char *host; + + opterr = 0; + while ( (c = getopt (argc, argv, "m:")) != -1) { + switch (c) { + case 'm': + if ( (max_ttl = atoi(optarg)) <= 1) { + err_quit ("invalid -m value"); + } + break; + default: + err_quit ("unrecognizd option: %c", c); + } + } + + if (optind != argc - 1) { + err_quit ("usage: trout [ -m ] "); + } + host = argv[optind]; + ai = Host_serv (host, NULL, 0, 0); + + printf ("trout to %s (%s): %d hops max, %d data bytes\n", + ai->ai_canonname, + Sock_ntop_host (ai->ai_addr, ai->ai_addrlen), + max_ttl, datalen); + + if (ai->ai_family != AF_INET) { + err_quit ("unknown address family %d", ai->ai_family); + } + + sasend = ai->ai_addr; + salen = ai->ai_addrlen; + sarecv = Calloc (1, salen); + salast = Calloc (1, salen); + sabind = Calloc (1, salen); + + loop_ttl (); + exit (0); +} From eec8a4b7e47cc53cceaefe92ec6f26c32579b001 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:31:35 -0500 Subject: [PATCH 09/14] Add files via upload --- exercises/ex04/trout/trout (1) | Bin 0 -> 42576 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 exercises/ex04/trout/trout (1) diff --git a/exercises/ex04/trout/trout (1) b/exercises/ex04/trout/trout (1) new file mode 100644 index 0000000000000000000000000000000000000000..f7f2b2771a4d383742d5973235db94b891abaa32 GIT binary patch literal 42576 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 sN0zt#wBKmI;QXTd9$@OI{ Date: Thu, 27 Feb 2020 21:32:32 -0500 Subject: [PATCH 10/14] finally compiles --- exercises/ex04/trout/trout.c | 305 +++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 exercises/ex04/trout/trout.c diff --git a/exercises/ex04/trout/trout.c b/exercises/ex04/trout/trout.c new file mode 100644 index 00000000..a9bf21e4 --- /dev/null +++ b/exercises/ex04/trout/trout.c @@ -0,0 +1,305 @@ +#include "trout.h" + +/* variables we might want to configure */ +Rec *rec = (Rec *) sendbuf; + +/* NOTES: system calls beginning with a capital letter are Stevens's + wrapper functions. Each one invokes the method and checks the + return value. If the call fails, it invokes err_sys, which prints + the error message and quits. + Types that begin with a capital letter are usually typedefs + that I added because (1) I hate seeing the word struct all over + the place, and (2) it lets me pretend I am writing Java. */ + +/* sig_alrm: alarm handler sends a message to the process through + a pipe, causing select to return */ + +void sig_alrm (int signo) +{ + Write (pipefd[1], "", 1); /* write 1 null byte to pipe */ + return; +} + +/* process_ip: extracts all the info from an incoming ICMP packet + Just for kicks, I changed the BSD-style names of the ICMP + errors to Linux-style names, mostly so that they will be + consistent with the changes I made in the kernel and so my + head won't explode. */ + +int process_ip (struct ip *ip, int len) +{ + int hlen1, hlen2, icmplen; + struct icmp *icmp; + struct ip *hip; + struct udphdr *udp; + seq = 0; + u_short dport = 32768 + 668; /* destination port -- hopefully unused */ + + hlen1 = ip->ip_hl << 2; /* length of IP header */ + icmp = (struct icmp *) (recvbuf + hlen1); + icmplen = len - hlen1; + + if (icmplen < 8 + 20 + 8) return 0; + + if (icmp->icmp_type != ICMP_TIME_EXCEEDED && + icmp->icmp_type != ICMP_DEST_UNREACH) + return 0; + + /* hip is the header of the enclosed IP packets, supposedly + the header of the packet that caused the error */ + + hip = (struct ip *) (recvbuf + hlen1 + 8); + if (hip->ip_p != IPPROTO_UDP) return 0; + + hlen2 = hip->ip_hl << 2; + udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2); + + if (udp->source != htons (sport)) return 0; + if (udp->dest != htons (dport + seq)) return 0; + + /* now we know it's an ICMP packet caused by a UDP + datagram sent by us and sent to the port we happen to + be sending to. It's probably one of ours. */ + + if (icmp->icmp_type == ICMP_TIME_EXCEEDED) { + if (icmp->icmp_code == ICMP_EXC_TTL) { + return -2; + } else { + return 0; + } + } + + if (icmp->icmp_type == ICMP_DEST_UNREACH) { + if (icmp->icmp_code == ICMP_PORT_UNREACH) { + return -1; + } else { + return 0; + } + } + return 0; +} + +/* recv_dgram: reads all incoming datagrams and checks for + returning ICMP packets. + returns -3 on timeout, + -2 on ICMP time exceeded in transit (we reached a router) + -1 on ICMP port unreachable (we reached the destination) + 0 on ICMP that has nothing to do with us */ + + /* as Stevens points out in Section 18.5 of Unix Network Programming, + many programs with alarms have a race condition, which is that + the alarm might go off before we get to the recvfrom, in which + case it does nothing and the recvfrom might wait indefinitely. + In earlier versions of this code, this problem seemed to pop + up occasionally (although I am not positive about that). + The use of select here solves that problem. When the alarm + goes off, the alarm handler sends a message through the pipe, + which is one of the things select waits for. + When select returns, we know that we have received a datagram + OR the alarm has gone off OR both. We then use rset to find + out which, and deal with it. + According to the specification of select, it should not be possible + to get to the recvfrom unless there is a datagram waiting, and + therefore the recvfrom should never block. Nevertheless, it sometimes + does, which is why, when we opened it, we set the NONBLOCK flag + and why, if it fails (errno = EAGAIN) we just go on. */ + +int recv_dgram () +{ + int err; + socklen_t len; + ssize_t n; + struct ip *ip; + int maxfdp1 = max (recvfd, pipefd[0]) + 1; + fd_set rset[1]; + FD_ZERO (rset); + + alarm(3); /* set the timeout alarm to handle dropped packets */ + + while (1) { + FD_SET (recvfd, rset); + FD_SET (pipefd[0], rset); + + n = select (maxfdp1, rset, NULL, NULL, NULL); + if (n < 0 && errno != EINTR) { + err_sys ("select error"); + } + + if (FD_ISSET (recvfd, rset)) { + len = salen; + n = recvfrom (recvfd, recvbuf, sizeof(recvbuf), 0, sarecv, &len); + err = errno; + Gettimeofday (recvtv, NULL); /* get time of packet arrival */ + if (n < 0 && err != EAGAIN) { + err_sys ("recvfrom error"); + } + } + + if (FD_ISSET (pipefd[0], rset)) { + Read (pipefd[0], &n, 1); + return -3; /* timeout */ + } + + ip = (struct ip *) recvbuf; + return process_ip (ip, n); + } +} + +/* sub_tv: subtract minus from plus and put the result in res */ + +void sub_tv (Timeval *plus, Timeval *minus, Timeval *res) +{ + res->tv_sec = plus->tv_sec - minus->tv_sec; + res->tv_usec = plus->tv_usec - minus->tv_usec; + + if (res->tv_usec < 0) { + res->tv_sec--; + res->tv_usec += 1000000; + } +} + +/* time_to_double: convert a Timeval to a double. This only + works with Timevals that are small (like the difference between + two real Timevals) */ + +double time_to_double (Timeval *time) +{ + return time->tv_sec * 1000.0 + time->tv_usec / 1000.0; +} + +/* print_report: prints all the information about a successful round trip */ + +void print_report () +{ + int stat; + char str[NI_MAXHOST]; + + stat = sock_cmp_addr (sarecv, salast, salen); + + /* if this reply comes from source different from the previous + one, print the full host information */ + + if (stat != 0) { + stat = getnameinfo (sarecv, salen, str, sizeof(str), NULL, 0, 0); + if (stat == 0) { + printf (" %s (%s)", str, Sock_ntop_host (sarecv, salen)); + } else { + printf (" %s", Sock_ntop_host (sarecv, salen)); + } + memcpy (salast, sarecv, salen); + } + + /* calculate and print the round trip time using user-level timestamps */ + + sub_tv (recvtv, sendtv, difftv); + + printf (" %.3f", time_to_double (difftv)); +} + +/* send_dgram: generate an outgoing UDP packet */ + + /* the second effort send is a kludge to handle a funny + thing, which is that the last host seems to refuse the + second or third connection consistently, which might + might mean that something breaks when we get the + ICMP_DEST_UNREACH error. The second attempt seems + to succeed consistently. */ + +void send_dgram (int ttl) +{ + int n; + datalen = sizeof (Rec); /* length of the data in a datagram */ + seq = 0; + u_short dport = 32768 + 668; /* destination port -- hopefully unused */ + + rec->seq = seq++; + sock_set_port (sasend, salen, htons(dport+seq)); + + Gettimeofday (sendtv, NULL); + n = sendto(sendfd, sendbuf, datalen, 0, sasend, salen); + + if (n==-1 && errno == ECONNREFUSED) { + Gettimeofday (sendtv, NULL); + n = sendto(sendfd, sendbuf, datalen, 0, sasend, salen); + } + + if (n != datalen) { + err_sys("sendto error"); + } +} + +/* send_probes: sends a set of probes with the given ttl and + then waits for the replies. The weird TOS options are there + as a signal to the kernel to identify clink packets so it can + fill in the timestamps. I am assuming that they don't have + any actual effect. */ + +int send_probes (int ttl) +{ + int probe, code, done; + + Setsockopt (sendfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(int)); + bzero (salast, salen); + int nprobes = 2; + + printf ("%2d ", ttl); + fflush (stdout); + + done = 0; /* count the number of probes that generate an ICMP_DEST_UNREACH */ + + for (probe = 0; probe < nprobes; probe++) { + send_dgram (ttl); + code = recv_dgram (); + + if (code == -3) { + printf (" *"); + } else { + print_report (); + } + + if (code == -1) done++; + fflush (stdout); + } + printf ("ms\n"); + return done; +} + +/* loop_ttl: starting with ttl=1, gradually increase ttl until + we start getting ICMP_DEST_UNREACH instead of ICMP_TIME_EXCEEDED */ + +void loop_ttl () +{ + int ttl, done; + + Pipe (pipefd); /* the pipe for the alarm handler */ + max_ttl = 30; + + + recvfd = socket (sasend->sa_family, SOCK_RAW, IPPROTO_ICMP); + if (recvfd == -1) { + if (errno == EPERM) { + printf ("\nclink was unable to open a raw socket. The most\n"); + printf ("likely cause is that you are not running it as root.\n"); + exit (1); + } else { + err_sys ("opening raw socket in clink"); + } + } + + fcntl (recvfd, F_SETFL, O_NONBLOCK); + setuid (getuid ()); + + sendfd = socket (sasend->sa_family, SOCK_DGRAM, 0); + + sabind->sa_family = sasend->sa_family; + sport = (getpid() & 0xffff) | 0x8000; /* source UDP port # */ + sock_set_port (sabind, salen, htons(sport)); + Bind (sendfd, sabind, salen); + + Signal (SIGALRM, sig_alrm); + + for (ttl = 1; ttl <= max_ttl; ttl++) { + done = send_probes (ttl); + if (done > 0) break; + } +} From 8ea9cebcd432ac185197790d7b61aaa7a9103d42 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:33:21 -0500 Subject: [PATCH 11/14] she finally compiles!!!!!!!!! --- exercises/ex04/trout/trout.h | 96 ++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 exercises/ex04/trout/trout.h diff --git a/exercises/ex04/trout/trout.h b/exercises/ex04/trout/trout.h new file mode 100644 index 00000000..e445646d --- /dev/null +++ b/exercises/ex04/trout/trout.h @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 1500 + +typedef struct rec { /* outgoing UDP data */ + u_short seq; /* sequence number */ +} Rec; + +typedef struct timeval Timeval; +typedef struct sockaddr Sockaddr; + +#define max(a,b) ((a) > (b) ? (a) : (b)) + +/* the following are prototypes for the Stevens utilities in util.c */ + +void Sendto(int fd, const void *ptr, size_t nbytes, int flags, + const struct sockaddr *sa, socklen_t salen); + +Sockaddr *sasend; /* socket addresses for various purposes */ +Sockaddr *sarecv; +Sockaddr *salast; +Sockaddr *sabind; + +socklen_t salen; /* length of a socket address */ + +/* other global variables */ + +int seq; + +char recvbuf[BUFSIZE]; +char sendbuf[BUFSIZE]; + +int sendfd, recvfd; +int pipefd[2]; /* the pipe for the alarm handler */ + +// Sockaddr *sasend; /* socket addresses for various purposes */ +// Sockaddr *sarecv; +// Sockaddr *salast; +// Sockaddr *sabind; + +// socklen_t salen; /* length of a socket address */ +int datalen; /* length of the data in a datagram */ +int max_ttl; + +u_short sport; /* source UDP port # */ + + /* 668 = the neighbor of the beast */ +Timeval sendtv[1]; +Timeval recvtv[1]; +Timeval difftv[1]; + +void err_sys (char *fmt, ...); +void err_quit (char *fmt, ...); +char *Sock_ntop_host(const struct sockaddr *sa, socklen_t salen); +int sock_cmp_addr(const struct sockaddr *sa1, + const struct sockaddr *sa2, socklen_t salen); +void sock_set_port(struct sockaddr *sa, socklen_t salen, int port); +void tv_sub (struct timeval *out, struct timeval *in); +char *icmpcode_v4(int code); +void *Calloc(size_t n, size_t size); +void Gettimeofday(struct timeval *tv, void *foo); +void Pipe(int *fds); +void Bind(int fd, const struct sockaddr *sa, socklen_t salen); +void Setsockopt(int fd, int level, int optname, const void *optval, + socklen_t optlen); +struct addrinfo *Host_serv(const char *host, const char *serv, + int family, int socktype); +ssize_t Read(int fd, void *ptr, size_t nbytes); +void Write(int fd, void *ptr, size_t nbytes); +ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags, + struct sockaddr *sa, socklen_t *salenptr); + +typedef void Sigfunc(int); +Sigfunc *Signal(int signo, Sigfunc *func); + +void loop_ttl (); From 90477edd6d3fb556f4b8b98864c4f86aca91a8ce Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:33:57 -0500 Subject: [PATCH 12/14] finally compiles --- exercises/ex04/trout/util.c | 284 ++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 exercises/ex04/trout/util.c diff --git a/exercises/ex04/trout/util.c b/exercises/ex04/trout/util.c new file mode 100644 index 00000000..ce9b0a40 --- /dev/null +++ b/exercises/ex04/trout/util.c @@ -0,0 +1,284 @@ +#include "util.h" + +void err_doit (int errnoflag, int level, char *fmt, va_list ap) +{ + int errno_save, n; + char buf[MAXLINE]; + + errno_save = errno; /* value caller might want printed */ + vsnprintf (buf, sizeof(buf), fmt, ap); + n = strnlen (buf, MAXLINE); + if (errnoflag) + snprintf (buf+n, sizeof(buf) - n, ": %s", strerror(errno_save)); + strcat (buf, "\n"); + + fflush (stdout); + fputs (buf, stderr); + fflush (stderr); +} + +void err_sys (char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + err_doit (1, LOG_ERR, fmt, ap); + va_end(ap); + exit(1); +} + +void err_quit (char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + err_doit (0, LOG_ERR, fmt, ap); + va_end(ap); + exit(1); +} + +char *sock_ntop_host(const struct sockaddr *sa, socklen_t salen) +{ + static char str[128]; + + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + + if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL) { + return NULL; + } else { + return str; + } + } + case AF_UNIX: { + struct sockaddr_un *unp = (struct sockaddr_un *) sa; + + /* OK to have no pathname bound to the socket: happens on + every connect() unless client calls bind() first. */ + if (unp->sun_path[0] == 0) + strcpy(str, "(no pathname bound)"); + else + snprintf(str, sizeof(str), "%s", unp->sun_path); + return str; + } + default: + snprintf(str, sizeof(str), "sock_ntop_host: unknown AF_xxx: %d, len %d", + sa->sa_family, salen); + return str; + } + return NULL; +} + +char *Sock_ntop_host(const struct sockaddr *sa, socklen_t salen) +{ + char *ptr; + + if ( (ptr = sock_ntop_host(sa, salen)) == NULL) + err_sys("sock_ntop_host error"); /* inet_ntop() sets errno */ + return(ptr); +} + +void sock_set_port(struct sockaddr *sa, socklen_t salen, int port) +{ + switch (sa->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *) sa; + + sin->sin_port = port; + return; + } + return; + } +} + +int sock_cmp_addr(const struct sockaddr *sa1, const struct sockaddr *sa2, + socklen_t salen) +{ + if (sa1->sa_family != sa2->sa_family) + return(-1); + + switch (sa1->sa_family) { + case AF_INET: { + return(memcmp( &((struct sockaddr_in *) sa1)->sin_addr, + &((struct sockaddr_in *) sa2)->sin_addr, + sizeof(struct in_addr))); + } + + case AF_UNIX: { + return(strcmp( ((struct sockaddr_un *) sa1)->sun_path, + ((struct sockaddr_un *) sa2)->sun_path)); + } + } + return -1; +} + +void tv_sub (struct timeval *out, struct timeval *in) +{ + if ( (out->tv_usec -= in->tv_usec) < 0) { /* out -= in */ + --out->tv_sec; + out->tv_usec += 1000000; + } + out->tv_sec -= in->tv_sec; +} + +char *icmpcode_v4(int code) +{ + switch (code) { + case 0: return("network unreachable"); + case 1: return("host unreachable"); + case 2: return("protocol unreachable"); + case 3: return("port unreachable"); + case 4: return("fragmentation required but DF bit set"); + case 5: return("source route failed"); + case 6: return("destination network unknown"); + case 7: return("destination host unknown"); + case 8: return("source host isolated (obsolete)"); + case 9: return("destination network administratively prohibited"); + case 10: return("destination host administratively prohibited"); + case 11: return("network unreachable for TOS"); + case 12: return("host unreachable for TOS"); + case 13: return("communication administratively prohibited by filtering"); + case 14: return("host recedence violation"); + case 15: return("precedence cutoff in effect"); + default: return("[unknown code]"); + } +} + +Sigfunc *signal(int signo, Sigfunc *func) +{ + struct sigaction act, oact; + + act.sa_handler = func; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + if (signo == SIGALRM) { + act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x (and Linux, apparently) */ + } + if (sigaction(signo, &act, &oact) < 0) + return(SIG_ERR); + return(oact.sa_handler); +} + +Sigfunc *Signal(int signo, Sigfunc *func) /* for our signal() function */ +{ + Sigfunc *sigfunc; + + if ( (sigfunc = signal(signo, func)) == SIG_ERR) + err_sys("signal error"); + return(sigfunc); +} + +void *Malloc(size_t size) +{ + void *ptr; + + if ( (ptr = malloc(size)) == NULL) + err_sys("malloc error"); + return(ptr); +} + +void *Calloc(size_t n, size_t size) +{ + void *ptr; + + if ( (ptr = calloc(n, size)) == NULL) + err_sys("calloc error"); + return(ptr); +} + +void Gettimeofday(struct timeval *tv, void *foo) +{ + if (gettimeofday(tv, foo) == -1) + err_sys("gettimeofday error"); + return; +} + +void Pipe(int *fds) +{ + if (pipe(fds) < 0) + err_sys("pipe error"); +} + +void Bind(int fd, const struct sockaddr *sa, socklen_t salen) +{ + if (bind(fd, sa, salen) < 0) + err_sys("bind error"); +} + +void Setsockopt(int fd, int level, int optname, const void *optval, + socklen_t optlen) +{ + if (setsockopt(fd, level, optname, optval, optlen) < 0) + err_sys("setsockopt error"); +} + +struct addrinfo * +host_serv (char *host, char *serv, int family, int socktype) +{ + int n; + struct addrinfo hints, *res; + + bzero (&hints, sizeof(struct addrinfo)); + hints.ai_flags = AI_CANONNAME; /* return canonical name */ + hints.ai_family = family; + hints.ai_socktype = socktype; + + n = getaddrinfo (host, serv, &hints, &res); + if (n != 0) { + return NULL; + } else { + return res; /* return pointer to first on linked list */ + } +} + +/* + * There is no easy way to pass back the integer return code from + * getaddrinfo() in the function above, short of adding another argument + * that is a pointer, so the easiest way to provide the wrapper function + * is just to duplicate the simple function as we do here. + */ + +struct addrinfo * +Host_serv(const char *host, const char *serv, int family, int socktype) +{ + int n; + struct addrinfo hints, *res; + + bzero(&hints, sizeof(struct addrinfo)); + hints.ai_flags = AI_CANONNAME; /* always return canonical name */ + hints.ai_family = family; /* 0, AF_INET, AF_INET6, etc. */ + hints.ai_socktype = socktype; /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */ + + if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0) + err_quit("host_serv error for %s, %s: %s", + (host == NULL) ? "(no hostname)" : host, + (serv == NULL) ? "(no service name)" : serv, + gai_strerror(n)); + + return(res); /* return pointer to first on linked list */ +} + +ssize_t Read(int fd, void *ptr, size_t nbytes) +{ + ssize_t n; + + if ( (n = read(fd, ptr, nbytes)) == -1) + err_sys("read error"); + return(n); +} + +void Write(int fd, void *ptr, size_t nbytes) +{ + if (write(fd, ptr, nbytes) != nbytes) + err_sys("write error"); +} + +ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags, + struct sockaddr *sa, socklen_t *salenptr) +{ + ssize_t n; + + n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr); + if (n < 0) + err_sys("recvfrom error"); + return(n); +} From a56751067e734801fad7459339220e494ea1d646 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:34:59 -0500 Subject: [PATCH 13/14] finally compiles --- exercises/ex04/trout/util.h | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 exercises/ex04/trout/util.h diff --git a/exercises/ex04/trout/util.h b/exercises/ex04/trout/util.h new file mode 100644 index 00000000..b04ff27b --- /dev/null +++ b/exercises/ex04/trout/util.h @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 + +/* the following are a few definitions from Stevens' unp.h */ +typedef void Sigfunc(int); /* for signal handlers */ + +void err_sys (char *fmt, ...); +void err_quit (char *fmt, ...); +char *Sock_ntop_host(const struct sockaddr *sa, socklen_t salen); +int sock_cmp_addr(const struct sockaddr *sa1, + const struct sockaddr *sa2, socklen_t salen); +void sock_set_port(struct sockaddr *sa, socklen_t salen, int port); +void tv_sub (struct timeval *out, struct timeval *in); +char *icmpcode_v4(int code); +Sigfunc *Signal(int signo, Sigfunc *func); +void *Calloc(size_t n, size_t size); +void Gettimeofday(struct timeval *tv, void *foo); +void Pipe(int *fds); +void Bind(int fd, const struct sockaddr *sa, socklen_t salen); +void Setsockopt(int fd, int level, int optname, const void *optval, + socklen_t optlen); +struct addrinfo *Host_serv(const char *host, const char *serv, + int family, int socktype); +ssize_t Read(int fd, void *ptr, size_t nbytes); +void Write(int fd, void *ptr, size_t nbytes); +ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags, + struct sockaddr *sa, socklen_t *salenptr); From 125b49bb39a3ca1281804a074673bd5633454597 Mon Sep 17 00:00:00 2001 From: Maalvika Bhat <42943695+maalvikabhat@users.noreply.github.com> Date: Thu, 27 Feb 2020 21:36:43 -0500 Subject: [PATCH 14/14] Update trout.c --- exercises/ex04/trout/trout.c | 46 +----------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/exercises/ex04/trout/trout.c b/exercises/ex04/trout/trout.c index a9bf21e4..0cf8f328 100644 --- a/exercises/ex04/trout/trout.c +++ b/exercises/ex04/trout/trout.c @@ -3,29 +3,12 @@ /* variables we might want to configure */ Rec *rec = (Rec *) sendbuf; -/* NOTES: system calls beginning with a capital letter are Stevens's - wrapper functions. Each one invokes the method and checks the - return value. If the call fails, it invokes err_sys, which prints - the error message and quits. - Types that begin with a capital letter are usually typedefs - that I added because (1) I hate seeing the word struct all over - the place, and (2) it lets me pretend I am writing Java. */ - -/* sig_alrm: alarm handler sends a message to the process through - a pipe, causing select to return */ - void sig_alrm (int signo) { Write (pipefd[1], "", 1); /* write 1 null byte to pipe */ return; } -/* process_ip: extracts all the info from an incoming ICMP packet - Just for kicks, I changed the BSD-style names of the ICMP - errors to Linux-style names, mostly so that they will be - consistent with the changes I made in the kernel and so my - head won't explode. */ - int process_ip (struct ip *ip, int len) { int hlen1, hlen2, icmplen; @@ -57,10 +40,6 @@ int process_ip (struct ip *ip, int len) if (udp->source != htons (sport)) return 0; if (udp->dest != htons (dport + seq)) return 0; - /* now we know it's an ICMP packet caused by a UDP - datagram sent by us and sent to the port we happen to - be sending to. It's probably one of ours. */ - if (icmp->icmp_type == ICMP_TIME_EXCEEDED) { if (icmp->icmp_code == ICMP_EXC_TTL) { return -2; @@ -79,30 +58,7 @@ int process_ip (struct ip *ip, int len) return 0; } -/* recv_dgram: reads all incoming datagrams and checks for - returning ICMP packets. - returns -3 on timeout, - -2 on ICMP time exceeded in transit (we reached a router) - -1 on ICMP port unreachable (we reached the destination) - 0 on ICMP that has nothing to do with us */ - - /* as Stevens points out in Section 18.5 of Unix Network Programming, - many programs with alarms have a race condition, which is that - the alarm might go off before we get to the recvfrom, in which - case it does nothing and the recvfrom might wait indefinitely. - In earlier versions of this code, this problem seemed to pop - up occasionally (although I am not positive about that). - The use of select here solves that problem. When the alarm - goes off, the alarm handler sends a message through the pipe, - which is one of the things select waits for. - When select returns, we know that we have received a datagram - OR the alarm has gone off OR both. We then use rset to find - out which, and deal with it. - According to the specification of select, it should not be possible - to get to the recvfrom unless there is a datagram waiting, and - therefore the recvfrom should never block. Nevertheless, it sometimes - does, which is why, when we opened it, we set the NONBLOCK flag - and why, if it fails (errno = EAGAIN) we just go on. */ + int recv_dgram () {