Errata for UNIX Network Programming, Volume 1

This file contains all typos found in the book UNIX Network Programming, Volume 1, Second Edition: Networking APIs: Sockets and XTI by W. Richard Stevens, Prentice Hall, 1998, ISBN 0-13-490012-X.


Page Description
306 The horizontal rules at the beginning and end of Figure 11.19 should say libgai/gai_hdr.h and not libgai/gai_hdr.c (990715).
Page Description
7 Indented paragraph near bottom of page: there is a space before the comma in "socket function ," that needs to be removed (990129).
59 8th line from bottom of page: replace "obsolescent" with "obsolete" (990330).
99 7th line from bottom of page: replace "pointed to by *addrlen" with "referenced by *addrlen" (990330).
107 3rd line above "Descriptor Reference Counts": replace "In this section" with "In that section" (990330).
113 Caption for Figure 5.2: append "(improved in Figure 5.12)" (981009).
117 2nd last line of Section 5.6: replace "and ttyin if the process" with "or ttyin or ttyout if the process" (990423).
122 Caption for Figure 5.7: append "(improved in Figure 5.11)" (981009).
125 Last sentence above "Difference between ..." heading: "This tells the kernel" should be "This option tells the kernel" and the last half of the sentence following the semicolon ("it blocks only if there are children still executing") should be removed (981125).
157 Caption for Figure 6.9: append "(improved in Figure 6.13)" (981009).
157 2nd sentence of Section 6.5: replace "First lets" with "First let's" (990330).
178 7th, 6th, and 5th lines above Section 7.3: replace "optval is an integer" with "*optval is an integer", "optval is zero" with "*optval is zero", and "a nonzero optval" with "a nonzero *optval" (990330).
193 Last line of first indented paragraph: replace "returns the maximum size" with "is the maximum size" (990330).
193 5th line beneath "SO_RCVLOWAT and SO_SNDLOWAT Functions": replace "for a TCP and UDP sockets" with "for TCP and UDP sockets" (990330).
197 There are some inconsistencies in the text formatting when describing the socket options. On pages 197-201 the following headings should have "Socket Option" following the option name: IP_HDRINCL, IP_RECVDSTADDR, IP_RECVIF, IP_TOS, IP_TTL, ICMP6_FILTER, IPV6_ADDRFORM, IPV6_CHECKSUM, IPV6_DSTOPTS, IPV6_HOPLIMIT, IPV6_HOPOPTS, IPV6_PKTINFO, IPV6_PKTOPTIONS, IPV6_RTHDR, IPV6_UNICAST_HOPS (981222). Note that IPV6_NEXTHOP is not in this list because it is not a socket option.
203 3rd line following Figure 7.13: "we have the six packets" should be "we have the eight packets" (981222).
222 3rd line from bottom of page: replace "destination IP addresses" with "destination IP address" (990330).
229 Line 8 of Figure 8.19: replace "MAXLINE" with "DGLEN" (990330).
229 4th line from bottom of page: replace "which was a slow 80386" with "a slow 80386" (990330).
246 3rd line following box defining gethostbyname2: "family argument" should be "family argument", that is, the font should be Italic (981231).
249 First line of item "3.": "family argument" should be "family argument", that is, the font should be Italic (981231).
268 5th line from top of page: "An IPv6 server could call this function" should be "An IPv6 server could call this macro" (981231).
290 Caption for Figure 11.9: append "(see also Figure 11.10)" (981009).
398 3rd line from bottom of page: "In this section we provide" should be "In this chapter we provide" (990109).
410 In the code snippet at the beginning of Section 15.4, "(SA)" should be "(SA *)" (981207).
451 With the addition of the new line of code to Figure 17.6 with the 4th printing, the line numbers for the code descriptions on page 451 should change: "26-28" should be "26-29" and "29-33" should be "30-34" (981208).
466 Comment on line 41 of Figure 17.20: "call can free()" should be "caller can free()" (990117).
514 Caption for Figure 19.19: change "SNTP packet" to "NTP packet" (990220).
524 Line 7 of Figure 19.27: size_t should be ssize_t (981009).
524 Last line of page: change "SNTP packet" to "NTP packet" (990220).
525 Last line of page: change "SNTP packet" to "NTP packet" (990220).
526 Caption for code line 59: change "SNTP packet" to "NTP packet" (990220).
528 The prompt should be "bsdi #" instead of "bsdi %" since the program must be run as superuser to bind the reserved port (123) (981009).
571 Caption for Figure 21.5: change "that uses select" to "that (incorrectly) uses select" (981009).
595 2nd to last line of description for lines 42-45: replace "the flag nqueue" with "the counter nqueue" (990423).
607 Caption for Figure 23.3: append "(see also Exercise 23.5)" (981009).
658 2nd line of 2nd bullet, near top of page: "Complete IPv6 packets" should be "Complete IPv6 packets (including extension headers)" (981019).
659 Last sentence on page, replace with: "For a raw IPv6 socket everything other than any extension headers are passed to the socket (e.g., Figures 25.11 and 25.21)." (981019).
660 2nd indented paragraph near top of page: "passed to a raw IPv6 socket" should be "received on a raw IPv6 socket" (981019).
686 Figure 25.26: the arrow between the application and UDP should be double-headed (as in the next figure) (981019).
691 Middle down page: "We expect ICMP host unreachables" should be "We assume icmpd is running and expect ICMP host unreachables" (981019).
705 10th line from bottom of page: "read only from BPF" should be "only read from BPF" (981106).
707 Halfway down page: "Specifying a protocol of ETH_P_ALL" should be "Specifying a protocol of ETH_P_xxx" (981106).
716 Line 71 of Figure 26.10: "ui->ui_sum" should be "ntohs(ui->ui_sum)" (981210).
732 The WebStone URL is now http://www.mindcraft.com/webstone/ (990307).
734 5th line from top of page: replace "We do this after the client completes" to "We type this key after the client completes," (990307).
737 9th line from bottom of page: "which we shown" should be "which we show" (981109).
751 5th line of description for lines 56-66: "will be close" should be "will be closed" (981109).
760 4th line of second bullet: "a monitoring" should be "monitoring" (981109).
773 5th line from bottom of page: replace t_tcv with t_rcv (990423).
785 2nd line above Section 29.3: replace "netconfig file" with "/etc/netconfig file" (990423).
807 Lines 24 and 28 of Figure 30.6: replace the word "socket" in the comments with "endpoint" (990423).
822 2nd line of description for lines 26-33: replace "releases the memory that it allocated" with "releases the memory that netdir_getbyname allocated" (990423).
855 Last paragraph of Section 33.4: replace two occurrences of "flagsp" with "flagsp" (that is, it should be italic, not a constant-width font) and replace one occurrence of "bandp" with "bandp" (that is, it should be italic, not a constant-width font) (990423).
881 4th line from end of Chapter: replace "S_xxx functions" with "S_xxx flags" (990423).
931 In the answer to exercise 6.6 "shutdown always sends" should be "shutdown with SHUT_WR or SHUT_RDWR always sends" (990214).
981 The entry "h_errno member" should be "h_errno variable" (981231).
983 Add pages "463, 466-467" to the index entry for "if_nameindex structure" (990423).
992 Delete the index entry for "pcap_pkthdr function" (990314).
998 Delete the index entries for "SETBLOCK constant", "SETBLOCKALL constant", "SETPASS constant", and "SETPASSALL constant" (990428).
1000 Change "so_timeo structure" to "so_timeo member" (990315).
1000 For the socket function, change "206-207" to just "207" (981229).
1004 Delete the index entry for "t_tcv function" (990423).
1008 Delete the reference to page 343 from the "wait function" entry (990423).
1009 Delete the index entry for "xti_serv_dev device" and add page 921 to the index entry for "xti_serv_dev variable" (990423).
Page Description
x In the Table of Contents, the Section title for 19.3: "A LAN" should be "a LAN" (980916).
xix 2nd line under "Source Code and Errata Availability": replace the ftp:// URL with "my home page, listed at the end of the Preface" (981007). (The source code is still available from that URL, but numerous readers have had problems with FTP, so HTTP is preferable.)
xx 13th line from top of page: "Justis Addis" should be "Justus Addiss" (981008).
12 2nd line of second indented paragraph: "p. 184" should be "p. 182" (of Kernighan and Pike) (980711).
80 Figure 3.17, line 25: "int n, rc" should be "ssize_t n, rc" (980713).
81 Box with prototype for isfdtype: first argument should be fd and not sockfd (since any type of descriptor argument is OK) (980713).
104 2nd line from bottom: "in the file table (pp. 58-59 of APUE)" should be "in the file table entry (pp. 57-60 of APUE)" (980422).
105 1st line beneath Figure 4.13: replace "file table" with "file table entry" (980422). Similarly in the next line, replace "file table" with "file table entry". Similarly in the 4th line beneath the figure, replace "file tables" with "file table entries".
105 Caption for Figure 4.14: "before call to accept" should be "before call to accept returns" (980714).
118 Last line of bullet "3": change "(Figure 2.5)" to "(Figures 2.4 and 2.5)" (980422).
124 In the code snippet in the middle of the page (SA) should be (SA *) (980715).
143 3rd line of Section 6.1: "read (by calling our readline function)," should be "fgets (on standard input)" (980718).
154 4th line of item 2c: "for the SO_ERROR" should be "with the SO_ERROR" (980718).
156 Caption for Figure 6.8: strcli should be str_cli (980713).
179 Description for TCP_KEEPALIVE should be changed to "idle time in seconds before probing" to be more accurate (980628).
193 Last line of 2nd paragraph of "SO_RCVLOWAT ..." section: "have a send buffer it" should be "have a send buffer; it" (980721).
194 2nd line of 2nd indented paragraph: "516 ot" should be "516 of" (980721).
197 5th line from bottom of page: "(noticeably" should be "(notably" (980721).
202 8th line of "TCP_MAXSEG Socket Option" section: "is in use because" should be "is in use, because" (980721).
215 6th line above Figure 8.5: "socket, before" should be "socket before" (980724).
226 2nd line beneath Figure 8.16: "the server" should be "the servers" (980724).
256 5th line of 3rd paragraph of Section 9.11: "Section 9.3" should be "Section 9.4" (980730).
266 Last line of 2nd bullet: "IPv4 clients" should be "IPv4 sockets" (980804).
268 3rd line beneath item "2.": "an exec" should be "a fork" (980804).
271 3rd line above Exercises: "the IN6_IS_ADDR_V4MAPPED can" should be "the IN6_IS_ADDR_V4MAPPED macro can" (980422).
279 Figure 11.3, EAI_FAIL: "nonrecoverable" should be "unrecoverable" (980807).
279 Figure 11.3, EAI_NONAME: "nor service provided" should be "or service not provided" (980807).
281 Figure 11.4: 4th box under "Result": "IPv6 as sockaddr_in6{}s" should be "IPv6 sockaddr_in6{}s" (980807).
287 Caption for Figure 11.7: getaddrinfo should be tcp_connect (980807).
290 Caption for Figure 11.9: getaddrinfo should be tcp_listen (980807).
292 Caption for Figure 11.10: getaddrinfo should be tcp_listen (980903).
293 Example at top of page "daytimetcpcli /tmp/rendezvous 0" should be "daytimetcpcli /local /tmp/rendezvous" (980807).
300 3rd line from top of page: "Similarly the" should be "Similarly" (980807).
312 3rd line of description for lines 101-106: "even of" should be "even if" (980807).
315 The last sentence in the description of lines 28-36 ("We keep a counter ...") should be moved to the end of the description for lines 12-27 as the first use of this counter is on line 18 (980807).
320 1st line on page: "we shown" should be "we show" (980807).
333 2nd line of 1st indented paragraph: "possible" should be "possibly" (980809).
335 3rd line of description for lines 10-11: "This automatically runs the process" should be "This automatically runs the child process" (980809).
337 6th line of description for lines 19-20: "anywhere in the filesystem" should be "in any filesystem" (980809).
339 1st line on page: "The date and time" should be "The date, time, and FQDN" (980809).
340 2nd line of item "4.": "a TCP socket" should be "a listening TCP socket" (980809).
350 1st line of "connect with a Timeout using SIGALRM" section: "a upper limit" should be "an upper limit" (980811).
350 Line 11 of Figure 13.1: the "(struct sockaddr *)" cast is not needed (980811).
351 The description for lines 11-16 should be for lines 11-15 (980811).
351 The description for lines 17-18 should be for lines 16-18 (980811).
353 Paragraph above "recvfrom with a Timeout ..." section: "We do not block in the call to recvfrom" should be "We do not call recvfrom" (980811).
365 Last line of paragraph following code: "no another" should be "not another" (980811).
372 4th line from top of page: "of normal sequence" should be "of the normal sequence" (980811).
374 1st line of 2nd indented paragraph: "dependence of" should be "dependence on" (980811).
378 6th line of item "8.": "Unix domain socket" should be "Unix domain datagram socket" (980811).
382 2nd line of 2nd paragraph of item "1." towards the bottom of the page: "parent;" should be "parent," (980811).
391 Line numbers "27-37" should be "26-36" (980811).
405 Example near top of page: tcpcli01 should be tcpcli02 (980903).
405 Example near middle of page: "sort diag" should be "sort diag -" (the hyphen means standard input) (980903).
411 Line 12: remove the unneeded cast "(struct sockaddr *)" (980903).
416 Description of lines 11-17: "structure is filled in" should be "structures are filled in" (980903).
427 Figure 16.1, descriptions for FIOSETOWN and FIOGETOWN: replace "socket" with "file" (980904).
437 4th line of description of lines 32-49: "Figure 16.3" should be "Figure 16.2" (980904).
437 Last line on page: append to the end of this sentence "and that ifi_next is initialized to a null pointer" (980904).
441 2nd line of description of lines 14-17: "returned by gethostbyname" should be "returned by my_addrs" (980904).
443 3rd line of Exercise 16.3: "Section 16.5" should be "Section 16.6" (980904).
450 Line 3 of Figure 17.6: "/* * sizeof(struct sockaddr_in6)" should be "/* sizeof(struct sockaddr_in6) * 8" (980904).
450 The getrt program fails to set the sin_len field of the socket address structure that is sent to the kernel. For most user socket functions this is not required (see the bottom of p. 58) but this is needed with routing sockets. The fix is to add the line
	sin->sin_len = sizeof(struct sockaddr_in);
	
between lines 26 and 27 (980610).
451 Description of lines 26-28: "All we set are the address family" should be "All we set are the address length, the address family," (980904).
453 Lines 10 and 14 of Figure 17.9: struct sockaddr should be SA (980904).
454 Line 3 of Figure 17.10: struct sockaddr should be SA (980904).
458 Line 8 of Figure 17.14: mib[5] should be mib[4] (980904).
466 2nd line of text: "interface names and addresses" should be "interface names and indexes" (980904).
473 7th line from top of page: the third byte of the Ethernet address of the host in the middle of Figures 18.3 and 18.4 should be 8c and not 9c (980905).
476 Line 28 of Figure 18.5: the final argument to Sock_ntop should be len and not servlen (980905).
477 1st word of 1st line of text: "strings" should be "a string" (980905).
477 1st line of text: delete "and port number" (980905).
477 1st/2nd lines of text: "These are" should be "This is" (980905).
477 Middle of page (3rd line below example): "definition of a broadcast datagram" should be "destination of a broadcast datagram" (980905).
479 Line 33 of Figure 18.6: the final argument to Sock_ntop should be len and not servlen (980905).
479 In the caption for Figure 18.6 append "(incorrect solution)" (980713).
481 Line 38 of Figure 18.7: the final argument to Sock_ntop should be len and not servlen (980905).
482 1st line of paragraph above Figure 18.8: "Posix.1g and none" should be "Posix.1g; none" (980905).
483 Line 26 of Figure 18.9: the final argument to Sock_ntop should be len and not servlen (980905).
484 2nd line of description for lines 45-50: "possible interrupting" should be "possibly interrupting" (980905).
485 Line 29 of Figure 18.10: "pselect error" should be "select error" (980905).
485 Line 36 of Figure 18.10: the final argument to Sock_ntop should be len and not servlen (980905).
490 Section title for 19.3: "A LAN" should be "a LAN" (980916).
493 2nd line of Section 19.4: "The benefit in" should be "The benefit of" (980916).
495 Last sentence on page: "All 10" should be "All five" and "but the four that join" should be "but the two that join" (980904).
501 Code description for lines "36-48" should be for lines "36-50" (980916).
502 Lines 39-46 of Figure 19.9: the final else on line 45 should be associated with the if on line 39, that is, the code should be
if (ifindex > 0) {
    mreq6.ipv6mr_interface = ifindex;
} else if (ifname != NULL) {
    if ( (mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) {
        errno = ENXIO;  /* i/f name not found */
        return(-1);
    }
} else
    mreq6.ipv6mr_interface = 0;
(980916).
506 2nd line of description for lines 15-23: "buffer and skip" should be "buffer, skip" (980916).
512 Lines 23-26 of Figure 19.18: the printf on lines 25-26 should be associated with the true portion of the if on line 23. that is, the code should be
if (ifi->ifi_flags & IFF_MULTICAST) {
    Mcast_join(sockfd, mcastsa, salen, ifi->ifi_name, 0);
    printf("joined %s on %s\n",
           Sock_ntop(mcastsa, salen), ifi->ifi_name);
}
(980916).
513 Code description for lines "23-24" should be for lines "23-27" and code description for lines "29-35" should be for lines "30-36" (980916).
517 Last sentence on page that spans to top of next page: "A value of 1 as the second argument ...". This sentence, along with the next sentence on page 518 ("We then pass the IFI_ALIAS ..."), should both appear at the end of the description for lines 15-17 (980916).
523 2nd line of text: CLIENT_MODE should be MODE_CLIENT (980916).
523 1st sentence of description for lines 4-19: "address is stored" should be "addresses are stored" and "size of the corresponding datagram" should be "sizes of the corresponding datagrams" (980916).
525 Lines 38, 42, 44, 47, 49, 51, 55: the argument aptr->addr_salen should be len (the value-result argument returned by recvfrom) (980916).
528 1st line of text (example): "sntp" should be "sntp 224.0.1.1" (the IP address is a required command-line argument on p. 518) (980916).
535 Figure 20.3: the sizes of the structure members are not shown correctly to scale: cmsg_len, cmsg_level, and cmsg_type are all integers (typically 4 bytes each, recall p. 363) and all the remaining members are 1-byte fields, except for the interface index, which is a 2-byte field (recall p. 446) (980922).
537 6th line of indented paragraph: "an unknown error" should be "an unknown option" (980922).
542 5th line from top: "over both UDP or TCP" should be "over both UDP and TCP" (980922).
543 Two-thirds of the way down the page: "the next RTT is 8 seconds" should be "the next RTO is 8 seconds" (980922).
546 2nd line of description of lines 1-5: rtt_into should be rtt_info (980922).
550 Description of lines 3-8 should be for lines 3-7 (980922).
552 1st line of description of lines 62-78: "The argument" should be "The second argument" (980922).
553 Second indented paragraph: "received interface" should be "receiving interface" (980922).
554 Code description for lines "25-41" should be for lines "25-42" (980922).
555 Between lines 35 and 36 add a new line containing Close(sockfd); (980922).
555 Code description for lines "42-46" should be for lines "43-47", code description for lines "49-61" should be for lines "50-62", and code description for line "62" should be for line "63" (980922).
556 Line 77 (after addition of new line of code): the final argument to Sendto should be len and not clilen (980922).
556 Code description for lines "64-65" should be for lines "65-66" and code description for lines "70-77" should be for lines "71-78" (980922).
566 9th line from bottom of page: "socket receive buffer" should be "socket send buffer" (980924).
584 2nd line from bottom of page: maxnprobes should be maxnalarms (980924).
595 1st/2nd line of 1st indented paragraph: "asynchronous I/O" should be "signal-driven I/O" (980927).
603 3rd line from bottom of page: "Figure 23.13" should be "Figure 23.14" (981008).
616 last line of 1st paragraph: "is free" should be "is freed" (981008).
620 line 10 of Figure 23.13: "int f_tid" should be "pthread_t f_tid" (981008).
633 1st line of Exercise 23.5: "Figure 23.4" should be "Figure 23.3" (981008).
640 3rd and 4th lines below indented paragraph: "right-shift the addresses ... after the header." should be "swap the first 4 bytes with the following 4 bytes and add 4 to the length field." (981007).
641 Line 44: "*hop1" should be "hop1" (981007).
641 Line 57: the comment should be "/* subtract dest IP addr */" (981007).
641 3rd line of description of lines 48-64: "3-byte header." should be "3-byte header, except the destination IP address." (981007).
646 4th line from bottom of page: "RFC 1883 [Hinden and Deering 1995]" should be "RFC 1883 [Deering and Hinden 1995]" (981007).
651 6th line from top of page: "The bit labeled 0 is for the first hop." should be "The bit labeled 0 is for the last hop." (981007).
651 7th line from top of page: "RFC 1883 [Hinden and Deering 1995]" should be "RFC 1883 [Deering and Hinden 1995]" (981007).
653 2nd line of indented paragraph: "RFC 1883 [Hinden and Deering 1995]" should be "RFC 1883 [Deering and Hinden 1995]" (981007).
750 Line 38: the first argument to select should be "maxfd + 1" (980723). Recall the indented paragraph at the top of p. 153!
886 1st line of 1st indented paragraph: "RFC 1883 [Hinden and Deering 1995]" should be "RFC 1883 [Deering and Hinden 1995]" (981007).
886 4th and 5th lines of 5th bullet: "IPV6_UNICAST_HOPS and IPV6_MULTICAST_HOPS socket options (Section 7.8)." should be "IPV6_UNICAST_HOPS and IPV6_MULTICAST_HOPS (Sections 7.8 and 19.5) socket options." (980730).
896 2nd line of parenthetical comment in Figure A.14: "ICMP or ICMPv6" should be "ICMPv4 or ICMPv6" (980711).
911 3rd line of Section C.4: "test small test" should be "small test" (980903).
924 The strcat on line 78 can write one byte beyond the end of the buffer (980514). One solution is to change line 68 to "char buf[MAXLINE + 1];" and then change the two sizeof(buf) (lines 71 and 77) to MAXLINE. This guarantees that the buffer is always terminated by a newline followed by a null byte.
926 Solution to 2.1: http://www.internic.net should now be http://www.ietf.org. Also, ftp://ds.internic.net/rfc should now be ftp://ftp.isi.edu/in-notes. Finally, rfc-index should now be rfc-index.txt. "Go backward from these obsolete RFCs" should be "Go forward from these obsolete RFCs" (the RFC indexes are now in increasing order, they used to be in decreasing order).
927 In the solution to 4.2, the second argument to Sock_ntop should be len and not sizeof(cliaddr), since len is the value-result that might be modified by Getsockname (980714).
930 Next to last line of solution to Exercise 5.10: "two 32-bit values" should be "one 32-bit value" (980715). On the last line of this solution, "two 64-bit values" should be "one 64-bit value".
945 7th line of solution to 12.2: "each service generates a single datagram" should be "each generates at most a single datagram" (980809).
945 Last line of solution to 12.3: "a organization's" should be "an organization's" (980809).
946 First line of solution to 13.4: "the falling" should be "falling" (980811).
948 Line 52: the test in the for loop should be "k <= j" not "k < j" (the descriptor that failed the connect must also be closed) (980811).
949 Line 69: Close(pipefd[1]) should be Close(pfd) (980811). (It is the same descriptor, but this is more consistent, given the #define at the beginning of the program.)
954 Between lines 41 and 42 add a new line containing Close(sockfd); (980922).
955 Line 83 (after addition of previous fix): the final argument to Sendto should be len and not salen (980922).
957 4th line of solution to Exercise 23.2: "in the state" should be "in this state" (981008). Also add the sentence "The server will also run out of descriptors (eventually)." to the end of this solution.
963 See the entry above for p. 926 regarding the location of RFC repositories. http://www.ietf.org should be the starting point for locating Internet Drafts.
972 Change "Addis, J." to "Addiss, J." (981008).
974 Delete entry for CLIENT_MODE (980916).
979 Change "file table, 383" to "file table entry, 104-105, 383" (980422).
980 Delete page "441" from the entry for gethostbyname (980904).
984 Delete page "83" from the entry for inet_ntoa (980422).
989 Add page "523" to the entry for MODE_CLIENT (980416).
996 Delete entry for rtt_into structure (980922).
1001 In the entry for str_cli, change "155, 157" to "155-157" (980713).
  Inside back cover ("Structure definitions"): add "ifi_info 431" and "ntpdata 511" (980916).
Page Description
5 Line above Figure 1.4: "with the both LANs" should be "with both LANs" (971215).
10 End of first paragraph of text: "using the getaddrinfo function" should be "using the getaddrinfo function (which is called by tcp_connect)" (980102).
15 Last line of page: "Section 12.5" should be "Section "12.4" (980227).
35 4th line below "TCP Options": add an end-of-sentence period between "connection" and "We" (980403).
57 2nd to last line: "these structure begins" should be "these structures begin" (971217).
75 3rd line from bottom: "INETADDRSTRLEN plus 5 bytes for IPv4 (16 + 5 = 21)" should be "INETADDRSTRLEN plus 6 bytes for IPv4 (16 + 6 = 22)" (980326). The value 6 is for the decimal-point separator between the IP address and the port, plus up to 5 digits for the port.

Similarly the next line should be "plus 6 bytes for IPv6 (46 + 6 = 52)".

83 First line of Exercise 3.3: "The inet_ntoa" should be "The inet_aton" (980416).
95 Second indented paragraph: "lost in history" should be "lost to history" (9800416).
118 Last line of bullet "3": FIN_WAIT_1 should be FIN_WAIT_2 (980416).
124 3rd line from top: "functions falls" should be "functions fall" (971217).
124 3rd line above Section 5.10: "When connect is interrupted by a caught signal that is not automatically restarted" should be "When connect is interrupted by a caught signal and is not automatically restarted (p. 466 of TCPv2)" (980416).
153 2nd line of first indented paragraph: "descriptors sets" should be "descriptor sets" (980220).
188 Second line of indented paragraph near top of page: "one-hundreds" should be "one-hundredths" (980121).
188 Last line of indented paragraph near top of page: "32.767 seconds" should be "327.67 seconds" (971201).
214 The filename on the horizontal rules for Figure 8.3 should be udpserv01.c, not ucpserv01.c (971201).
218 5th line from top: "It the client's request" should be "If the client's request" (971217).
228 Figure 8.18: the font for the figure caption is wrong (980109).
268 16th line from top: "requires an LPORT command" should be "requires an LPRT command" (971202).
359 Line above Figure 13.7: "because we mentioned that it is not used" should be "because, as we mentioned, it is not used" (971209). (This is not a typo, just improved wording.)
365 Last sentence of Section 13.6: "allocating space the" should be "allocating space for the" (971222).
371 1st line of Section 13.10: "three way" should be "three ways" (971209).
371 1st bullet of Section 13.10: "SIGALRM function" should be "SIGALRM signal" (971209).
386 3rd line under "fork and exec": "We call snprintf are because" should be "We call snprintf because" (971203).
390 1st line of 2nd indented paragraph: "even thought" should be "even though" (971203).
401 2nd line of description for lines 36-40: "(tooptr equals to)" should be "(tooptr equals toiptr)" (971217).
402 Code line 39 should be: if (tooptr == toiptr) (971217).
416 4th line from top of page: "of the server the file from" should be "of the server to read the file from" (971222).
427 Figure 16.1, FIOASYNC entry: "i/o" should be "I/O" (980105).
449 5th line from bottom of page: rmt_addrs should be rtm_addrs (971203).
450 4th line from top of page: "which if" should be "which of" (971203).
452 5th line from top of page: "four socket address structure" should be "four socket address structures" (971227).
459 Figure 17.15: there is a memory leak: if the second sysctl on line 17 fails, the memory allocated on line 15 is not freed. The fix is to add a call to free between lines 17 and 18, with the appropriate { and } also (980323).
459 With the above correction, change the line numbers "15-19" below the figure to "15-21" (980323).
473 4th line from bottom of page: add the sentence "(We assume the IP address bound is INADDR_ANY, as is typical.) to the end of the paragraph ending with "the socket." (971204). This is not a typo but is being added for clarification.
475 4th line from bottom of page: "and a signal handler is installed for SIGCHLD" should be "and a signal handler is installed for SIGALRM" (971203).
495 Top line of page: "steps takes" should be "steps taken" (971203).
497 1st line of 1st indented paragraph: "per socket This" should have a period after "socket" (971209).
498 6th line from top of page: "should be use" should be "should be used" (971203).
499 In the function prototypes for mcast_join and mcast_leave, the second argument should be named sa and not addr to be consistent with the descriptions that follow (980120).
514 Line 23 of Figure 19.19: htonl should be ntohl (980302).
542 Item "2." about halfway down the page: "the the" should be "the" (980201).
548 Description of code lines 45-47: Delete the entire sentence "The variable alrm_flag ... by the signal handler." (980209).
594 Code line 46 of Figure 22.4: SIGGIO should be SIGIO (971203).
607 There is a coding error in Figures 23.3 and 23.4: the first argument to Pthread_create is a NULL pointer, which is not allowed by pthreads (980209). Even if you don't need the thread ID for the newly created thread, you must still allocate a variable of type pthread_t and pass the pointer to that variable as the first argument.
608 Second sentence of text: "The first argument is a null pointer ..." must be removed (see entry above for p. 607) (980209).
608 With the correction above for p. 607 the line numbers in the margin should now be "17-21" and "23-30" (980209).
609 In the function doit at the top of the page the calls to str_echo and Close can be expressed more simply as (971203):
	str_echo(connfd);
	Close(connfd);
	
609 With the correction below for p. 610 the line numbers in the margin should now be "17-22" and "28-29" (980209).
610 Figure 23.4: See entry above for p. 607 (980209).
611 Figure 23.5: getc_unblocked should be getc_unlocked (980223).
611 Last line of page: change "Figures 23.4 and" to "Figures 23.3 and" for consistency with previous paragraph (971204).
621 Figure 23.14: Move line 49 before line 47. There is a chance (albeit slight) that the thread could terminate before pthread_create returns, in which case setting the F_CONNECTING flag would wipe out the F_DONE flag (980306).
631 Code at bottom of page: move the line "fptr->f_flags = F_DONE" down, between the calls to Pthread_mutex_lock and ndone++; Else there is a potential deadlock if two threads terminate at about the same time, both set F_DONE, but only one increments ndone and terminates (980309).
632 Figure: 23.19: same fix as listed above for Figure 23.14 on p. 621 (980404).
636 Last sentence of indented paragraph near bottom of page: "allow the user" reads better as "allow the application". "IP_OPTIONS socket options" should be "IP_OPTIONS socket option" (971204).
638 5th line from top: change "datagram." to "datagram when it leaves the source host." (971204). This is not a typo but is being added for clarity.
646 2nd/3rd line of text: "two high-order bits specifies" should be "two high-order bits specify" (971205).
646 Description when the two high-order bits are "11": "the error is sent only of" should be "the error is sent only if" (971205).
647 Last line of second paragraph beneath Figure 24.9: "(Figure 24.7)" should be "(Figure 24.8)" (980306).
649 4th line above Section 24.6: "value if -1" should be "value is -1" (980206).
654 2nd line of Exercise 24.3: "What would be do" should be "What would we do" (980309).
661 Line below Figure 25.1: "Figures A.15 and A.16 shows": both "shows" on this line should be "show" (971205).
662 Figure 25.3: bottom ellipse beneath sig_alrm labeled proc_v6 should be labeled send_v6 (971205).
673 2nd line of 2nd paragraph: "building its own IPv4 header" should be "building their own IPv4 header" (971208).
676 Line 50 of Figure 25.17: "cannot ping" should be "cannot traceroute" (971208).
677 1st/2nd lines of description for code lines 12-15: "low-order 15 bits" should be "low-order 16 bits" (971208).
691 Last line of indented paragraph at top of page: EAGAIN should be EINVAL (971208).
725 3rd line from top: "(Figure 26.7)" should be "(Figure 26.8)" (980316).
740 6th line beneath "Effect of Too Many Children": "remaining three columns" should be "remaining four columns" (980319).
822 Figure 31.2: the small box containing the pointer to the t_unitdata{} should be labeled tudptr: (980403).
872 Last line of page: "The second argument" should be "The iov argument" (980408).
892 2nd line beneath Figure A.7: "a aggregatable" should be "an aggregatable" (980413).
900 3rd and 5th lines of Bullet "4.": "HR2" should be "MR2" (971214).
917 Line 107: "AF_LOCAL and AF_LOCAL" should be "AF_LOCAL and PF_LOCAL" (980311).
927 In the solution to 4.2, Sock_ntop should have two arguments, not three: remove the final NULL argument (980326).
938 3rd line following Figure E.9: "it's call" should be "its call" (971203).
977 Delete page number 691 from the index entry for EAGAIN (971208).
979 Move page number "118" from the entry for FIN_WAIT_1 to the entry for FIN_WAIT_2 (980416).
980 getc_unblocked should be getc_unlocked (980223).
996 Delete the index entry for rmt_addrs and change "448, 450" in the entry for rtm_addrs to be "448-450" (971203).
998 Change "476" in the index entry for SIGALRM to be "475-476" (971203).
998 Delete page number 475 from the index entry for SIGCHLD (971203).
Page Description
  inside front cover: Add bold page number 325 for freeaddrinfo, 307 for getaddrinfo, and 326 for getnameinfo (970920).
xv 3rd/2nd lines from bottom of page: "of the my" should be "of my" (970925).
19 7th line from top of page: "our of order" should be "out of order" (971113).
19 9th line from top of page: "the lower three layers" should be "the lower four layers" (971105).
39 Last line of page: "less that 1460" should be "less than 1460" (971113).
44 Figures 2.8, 2.9, and 2.10 are "backwards" in that all other figures have the client on the left and the server on the right (971118). For consistency Figure 2.7 should have its arrow going to the right. In the first printing there is no typo to fix, but the left-right orientation will be corrected in the second printing.
47 2nd bullet, 3rd line: "A router that receives an IPv4 datagram with the DF bit set generates" should be "A router that receives an IPv4 datagram with the DF bit set whose size exceeds the outgoing link's MTU generates" (971107).
52 Final paragraph of Section 2.11: "The next three are UDP-based" should be "The next five are UDP-based" (971114).
72 2nd sentence after box describing inet_pton and inet_ntop: "If family is not supported, both functions return -1 with errno": replace "-1" with "an error" (971107).
81 Line above box describing isfdtype: fdistype should be isfdtype (971107).
83 5th line of Exercise 3.3: "three numbers separated by four decimal points" should be "four numbers separated by three decimal points (971107).
105 Figures 4.14, 4.15, 4.16, and 4.17 are "backwards" in that all other figures have the client on the left and the server on the right (971118). In the first printing there is no typo to fix, but the left-right orientation will be corrected in the second printing.
116 First example: "bsdi % tcpserv &" should be "bsdi % tcpserv01 &" (971118).
116 Third example: "bsdi % tcpcli 127.0.0.1" should be "bsdi % tcpcli01 127.0.0.1" (971118).
117 ps -l output: Both occurrences of tcpserv should be tcpserv01. Also, tcpcli should be tcpcli01 (971118).
117 Middle of page: "The PID and PPID columns shows": "shows" should be "show" (971114).
117 Middle of page, line following previous typo: Both occurrences of tcpserv should be tcpserv01 (971118).
117 Example at bottom of page: tcpcli should be tcpcli01 (971118).
118 ps output at bottom of page: ./tcpserv should be tcpserv01 and (tcpserv) should be (tcpserv01) (971118).
125 Figure 5.9 should be labeled as 5.8, and Figure 5.8 on p. 126 should be labeled as 5.9. The two text references to these figures at the bottom of p. 125 must then be swapped (971114).

In the first printing, all is OK (other than the two figures appearing out of order, which is aesthetically incorrect) and there is nothing to fix, but the ordering will be corrected in the second printing.

127 In the example at the top of the page tcpcli03 should be tcpcli04 (971118).
127 ps output: ./tcpserv03 should be tcpserv03 (971118).
141 Exercise 5.1, 3rd line: "Terminate the server" should be "Terminate the client" (971124).
141 Exercise 5.6, 5th line: "write a few more bytes to the pipe" should be "write a few more bytes to the socket" (971124).
147 2nd line following "Signal Driven I/O Model": "shown a summary" should be "show a summary" (971124).
147 2nd line from bottom of page: "the data is read to" should be "the data is ready to" (971124).
195 2nd line from top: "would be to call" should be "would call" (971119).
280 4th line of 3rd bullet: "returned sockaddr_in6 structures" should be "returned as sockaddr_in6 structures" (971013).
280 Last line of final bullet: "type of socket address structure returned" should be "type of socket address structure is returned" (971013).
288 Description of code lines 25-26: socked should be socket (971013).
359 Figure 13.7 should be centered on the page (971101). In the first printing, all is OK and there is nothing to fix, but the centering will be corrected in the second printing.
398 2nd line from the top: "error or EWOULDBLOCK" should be "error of EWOULDBLOCK" (971120).
407 Figure 15.10 should be labeled as 15.9, and Figure 15.9 on p. 408 should be labeled as 15.10. The two text references to these figures on p. 407 must then be swapped (971124).

In the first printing, all is OK (other than the two figures appearing out of order, which is aesthetically incorrect) and there is nothing to fix, but the ordering and the resulting references will be corrected in the second printing.

408 Half-way down page, "In Figure 15.9": "Figure 15.9" should be "Figure 15.10" (971124, see note with typo on p. 407).
409 "8.7 sec, fork (Figure 15.9)": "Figure 15.9" should be "Figure 15.10" (971124, see note with typo on p. 407).
422 4th line of Section 15.6: "connection ready" should be "connection is ready" (971120).
424 Exercises 15.1-15.3: "Figure 15.9" should be "Figure 15.10" (971124, see note with typo on p. 407).
605 First line of Section 23.3: "Figure 15.9" should be "Figure 15.10" (971124, see note with typo on p. 407).
730 Section 27.2, list item "4.": "Figure 15.9" should be "Figure 15.10" (971124, see note with typo on p. 407).
892 2nd line after Figure A.7: "are 010" should be "are 001" (971114).
892 2nd line following "Aggregatable Global Unicast Addresses" heading: "3-bit prefix of 010" should be "3-bit prefix of 001" (971114).
893 1st bullet at top of page: "format prefix (010)" should be "format prefix (001)" (971114).
979 Delete the entry for fdistype (971107).
988 Index entry for "Lucchnia" should be "Lucchina" (971103).
990 Add pages 209 and 357 to the entry for "Nagle algorithm" (971103).
992 Delete the index entry for "Pasxon" and add page 47 to the entry for "Paxson" (971103).
Page Comment
27 The C9X proposed revision to ANSI C (p. 15) would add a new row to this table: the datatype long long with a size of 64 bits in both the ILP32 and LP64 models. Also, http://www.lysator.liu.se/c/ contains lots of information on ANSI C.
126 In Figure 5.9, notice that lines 11-14 can be taken out of the for loop. My coding style is not to do this, unless the code is part of a loop that greatly affects the program's execution speed, which is not the case here. Ditto for line 12 on p. 157.
155 The declarations shown for FD_SETSIZE have traditionally been found in the <sys/types.h> header (4.4BSD and 4.4BSD-Lite2) but newer BSD-derived kernels and SVR4-derived kernels have these declarations in <sys/select.h>.
155 It is worth noting that some applications (typically event-driven servers that want to multiplex lots of descriptors, more than 1024) are starting to use poll instead of select, to avoid problems with a limit on the number of descriptors. It is also worth noting that typical implementations of select can have scaling problems when the number of descriptors gets large, as described in:

Banga, G., and Mogul, J. C. 1998. " Scalable Kernel Performance for Internet Servers under Realistic Loads," Proceedings of the 1998 USENIX Annual Technical Conference, pp. 1-12, New Orleans, LA.

162 There is another type of failure with the client-server that can be seen when using the str_cli function from Figure 6.13 along with the faster version of readline from Figure 3.17 and extending the server to return multiple lines for a given input from the client: the socket can be marked readable by select, the client calls readline, my_read reads multiple lines into its buffer, readline returns the first of these lines to the client, and then select (p. 162) no longer indicates that the socket is readable because all the input has already been read by my_read and is sitting in its buffer. The client is then hung.

I see two ways around this, when one line of input from the client can generate any amount of output from the server. First is to split the client into two processes (Figure 15.9) or two threads (Figure 23.1). Then each direction of data flow is totally independent of the other. The second is to change Figure 6.13 so that when the socket is readable, don't just read one line, but read everything that is in the socket's input buffer, and output that to standard output.

If you really wanted a lock-step approach, so that the client is not allowed to enter another request until all the server output has been received for the current request, then you need some way for the server to tell the client that its reply is complete. HTTP 1.0 essentially does this by using a separate TCP connection for each client request, and having the server close the connection to signify the end of each response.

165 One reader has pointed out that keeping the client array contiguous simplifies the code. The suggestion is as follows:

Delete lines 21-22. Replace lines 31-37 with:

	if (++maxi == FD_SETSIZE)
		err_quit("too many clients");
	client[maxi] = connfd;
Delete lines 41-42. Replace lines 47-48 with:
	sockfd = client[i];
Replace line 54 with:
	client[i--] = client[maxi--];
219 Although the source code is not shown for udpcliserv/udpcli02.c, this program should set the length field of the socket address structure on systems that support this field. One way is to write
	#ifdef	HAVE_SOCKADDR_SA_LEN
		servaddr.sin_len = sizeof(servaddr);
	#endif
when filling in the socket address structure. If this is not done, the call to memcmp in Figure 8.9 will fail on systems that set this value in the socket address structure returned by recvfrom.
220 Indented paragraph: Under Solaris 2.5.1 it appears that the source IP address of the server's reply is the last configured IP address for the outgoing interface.
334 Be aware that most implementations of openlog just save a pointer to the ident string; they do not make a copy of this string. That means that this string should not be allocated on the stack, because if the corresponding stack frame is gone when syslog is called at some later time, the saved pointer will not point to the ident string.
367 There is an interesting problem with the code in Figure 13.14. The function does not fclose the two standard I/O streams, counting instead on on the exit(0) in the main function to close all open standard I/O streams. But since both standard I/O streams use the same underlying descriptor, the first fclose will succeed, closing the underlying descriptor, but the second fclose will fail with an error of EBADF. You can see this error by inserting Fclose(fpout); Fclose(fpin); between lines 10 and 11. The easiest fix is to replace line 8 with fpout = Fdopen(Dup(sockfd), "w");, which also requires that you define the (trivial) wrapper function Dup. This does use one additional descriptor but avoids the fclose error.
382 Item "2." at the top of the page: just to reiterate: exec does not create a new process: a new program is executed in the context of the calling process.
411 There is a descriptor leak in the connect_nonb function, in that the error returns on lines 27 and 40 close the descriptor, but the error returns on lines 14 and 32 do not close the descriptor. I think the two calls to close on lines 25 and 38 should be removed. My reasoning is that when connect fails, the application must close the descriptor to avoid a leakage, so the application should do the same if connect_nonb fails.

In this same function, the call to Fcntl on line 36 should really be moved between lines 41 and 42, to avoid the call in the case of an error.

483 There are two potential timing problems with Figure 18.9. First consider what happens if the signal is delivered between the time that recvfrom returns and the storing of its return value in n. The datagram is considered lost (even though it was received) but a UDP application should be able to handle lost datagrams. But if this same technique is used with a TCP application, the data is lost forever (since TCP acknowledged the data and delivered it to the application).

The dg_cli function on page 485 that uses IPC has a similar problem: the signal can be delivered between recvfrom returning OK and storing the return value in n. This can be solved by turning off the alarm after select returns. Another exercise for the reader with Figure 18.10 is to not use alarm but use select's timer instead.

Second, there is no guarantee that the time between the call to alarm and the first call to sigsetjmp is less than the alarm time (5 seconds). One way around this is to set another flag after calling sigsetjmp and test this flag in the signal handler: if the flag is not yet set, do not call siglongjmp and just reset the alarm.

The bottom line here is that for robustness in these possible scenarios, avoid siglongjmp and use either pselect or the IPC method.

525 In Figure 19.28 you can simplify lines 36-50 by factoring out the first printf that is common to all three cases.
539 In the middle of the page there could be a 4th scenario: Return MSG_TRUNC but return the excess bytes to the application in subsequent read operations. One reader reports that Solaris 2.3 does this. I no longer have access to Solaris 2.3, and if it really does this, is clearly a bug.
548 There is a nonfatal race condition with Figure 20.9: if SIGALRM is delivered between lines 59 and 60 after a successful recvmsg, this will cause an unnecessary retransmission.
548 One reader has suggested replacing lines 57-60 with
do {
    do {
        n = Recvmsg(fd, &msgrecv, 0);
    } while (n < sizeof recvhdr);

        /* calculate & store new RTT estimator values */
    rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts);
} while (recvhdr.seq != sendhdr.seq);

alarm(0);       /* stop SIGALRM timer */
581 One reader provides the following comments on the heartbeat functions described in Section 21.5, and the possibility of the urgent data leaking into the normal band of data. (These comments reiterate a basic belief of mine, that out-of-band is a bad thing, and if you really need a second channel for some reason, create a second TCP connection.)

Later, I was thinking what a really nice solution it is because it comes almost for free (in terms of bandwidth). That lead me to think about what would happen if heartbeats backed up on the sender (because of a closed send window, say). Specifically, I wondered whether some of the early urgent bytes could leak into to the main-band data.

I checked my kernel, and there didn't seem to be any protection on the send side--i.e., when a user sends urgent data, tcp_usr_send (in tcp_usrreq.c) just sets snd_up without worrying about any previous _unsent_ urgent bytes. There is a remark in tcp_input (see TCPv2, page 984, lines 1075-1078) that urgent bytes could indeed get into the user data if there were multiple urgent bytes pending.

I then changed one of the programs from unpv12e/oob to send 8192 bytes of '1' as normal data, an OOB byte ('2'), 1024 more bytes of '1' as normal data, and another OOB byte ('3'). I then changed tcprecv05.c to sleep 5 seconds and then read and print all the data it receives.

When I ran the two programs, sig_urg printed the value of 3, and the 2 was in the user data. All of this is a long winded way of saying that the heartbeat functions might lead to data corruption. It's pretty unlikely because two or more unsent urgent bytes have to back up on the send side, but it clearly can happen.

I can't think of a transparent way (i.e., without having to check the user data for a special byte etc.) to fix this other than having only one urgent byte in flight at a time. That is, rather than declaring a connection dead if 5 consecutive 3 second heartbeats are missed, send a heartbeat every 15 seconds and declare the connection dead if you don't get it back before the 15 second timer fires again.

696 Lines 38-42 of Figure 25.37 are redundant, since the same operations were done in lines 18-22 of Figure 25.35, and we would not be in readable_conn had readable_listen not been called previously.
721 Lines 13 and 30 of Figure 26.14 could be removed since only one pass is made around the loop each time the function is called. But in the general case, you might want to handle an unknown datalink type without terminating, in which case the loop is needed.
914 In the description of lsof I say that "the size or offset of the file (not meaningful for a socket)". The author of this program offers the following insight:

A socket's offset can be very useful. In most UNIX dialects the offset comes from the file structure's f_offset. That structure member is incremented each time bytes are transferred to or from the file. So a changing offset value for a socket can mean that data transfers are taking place.

I use this feature to watch incoming ftp transfers with a custom Perl script that uses lsof field output and the lsof repeat feature. Usually I run it with the lsof repeat time set to 30 seconds, but here is some sample output for a test transfer from vic.cc to vic.cc and a 1 second repeat time:

=====
 3822    9r        0x600    1129991    28942
              /usr/ftp/pub/tools/unix/lsof/lsof_4.34_W.tar.Z
        10u   0x10169de8     901120      TCP
              vic.cc.purdue.edu:ftp-data->vic.cc.purdue.edu:listen
                                (ESTABLISHED QR=0 QS=4096)
=====
 3822    9r        0x600    1129991    28942
              /usr/ftp/pub/tools/unix/lsof/lsof_4.34_W.tar.Z
        10u   0x10169de8    1024000      TCP
              vic.cc.purdue.edu:ftp-data->vic.cc.purdue.edu:listen
                                (ESTABLISHED QR=0 QS=0)
=====

The fourth column is SIZE/OFF and you'll notice it increments as the ftp server pumps data to the ftp client.

968 A newer version of [Paxson 1996] is available:

Paxson, V. 1997. "End-to-End Routing Behavior in the Internet," IEEE/ACM Transactions of Networking, vol. 5, no. 5, pp. 601-615 (Oct.). ftp://ftp.ee.lbl.gov/papers/vp-routing-TON.ps.Z