100% found this document useful (13 votes)
111 views194 pages

TCP IP Lean Web Servers For Embedded Systems 2nd Edition Jeremy Bentham Full

The document provides information on the 'TCP/IP Lean Web Servers for Embedded Systems 2nd Edition' by Jeremy Bentham, available for download in various formats including PDF. It includes details about the book's content, structure, and educational resources related to TCP/IP and embedded systems. The book is published by CMP Books and is highly rated by users.

Uploaded by

tzijccjc2910
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (13 votes)
111 views194 pages

TCP IP Lean Web Servers For Embedded Systems 2nd Edition Jeremy Bentham Full

The document provides information on the 'TCP/IP Lean Web Servers for Embedded Systems 2nd Edition' by Jeremy Bentham, available for download in various formats including PDF. It includes details about the book's content, structure, and educational resources related to TCP/IP and embedded systems. The book is published by CMP Books and is highly rated by users.

Uploaded by

tzijccjc2910
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 194

TCP IP Lean Web Servers for Embedded Systems 2nd

Edition Jeremy Bentham pdf download

https://ebookgate.com/product/tcp-ip-lean-web-servers-for-embedded-systems-2nd-edition-jeremy-
bentham/

★★★★★ 4.7/5.0 (49 reviews) ✓ 116 downloads ■ TOP RATED


"Fantastic PDF quality, very satisfied with download!" - Emma W.

DOWNLOAD EBOOK
TCP IP Lean Web Servers for Embedded Systems 2nd Edition
Jeremy Bentham pdf download

TEXTBOOK EBOOK EBOOK GATE

Available Formats

■ PDF eBook Study Guide TextBook

EXCLUSIVE 2025 EDUCATIONAL COLLECTION - LIMITED TIME

INSTANT DOWNLOAD VIEW LIBRARY


Instant digital products (PDF, ePub, MOBI) available
Download now and explore formats that suit you...

Web Technologies TCP IP Web Java Programming and Cloud


Computing 3rd Edition Achyut S. Godbole

https://ebookgate.com/product/web-technologies-tcp-ip-web-java-
programming-and-cloud-computing-3rd-edition-achyut-s-godbole/

ebookgate.com

The ABCs of TCP IP 2nd Edition Gilbert Held

https://ebookgate.com/product/the-abcs-of-tcp-ip-2nd-edition-gilbert-
held/

ebookgate.com

TCP IP Clearly Explained Pete Loshin

https://ebookgate.com/product/tcp-ip-clearly-explained-pete-loshin/

ebookgate.com

The Correspondence Of Jeremy Bentham Volume 1 1752 To 1776


1st Edition Jeremy Bentham

https://ebookgate.com/product/the-correspondence-of-jeremy-bentham-
volume-1-1752-to-1776-1st-edition-jeremy-bentham/

ebookgate.com
The Correspondence of Jeremy Bentham Volume 2 1777 To 1780
1st Edition Jeremy Bentham

https://ebookgate.com/product/the-correspondence-of-jeremy-bentham-
volume-2-1777-to-1780-1st-edition-jeremy-bentham/

ebookgate.com

The Correspondence Of Jeremy Bentham Volume 5 January 1794


To December 1797 1st Edition Jeremy Bentham

https://ebookgate.com/product/the-correspondence-of-jeremy-bentham-
volume-5-january-1794-to-december-1797-1st-edition-jeremy-bentham/

ebookgate.com

TCP IP Network Administration 3rd Edition Craig Hunt

https://ebookgate.com/product/tcp-ip-network-administration-3rd-
edition-craig-hunt/

ebookgate.com

Special Edition Using TCP IP Niit (Usa) Inc.

https://ebookgate.com/product/special-edition-using-tcp-ip-niit-usa-
inc/

ebookgate.com

Jeremy Bentham s Economic Writings Critical Edition Based


on His Printed Works and Unprinted Manuscripts Jeremy
Bentham
https://ebookgate.com/product/jeremy-bentham-s-economic-writings-
critical-edition-based-on-his-printed-works-and-unprinted-manuscripts-
jeremy-bentham/
ebookgate.com
TCP/IP Lean
Web Servers for Embedded Systems
Second Edition

Jeremy Bentham

CMP Books
Lawrence, Kansas 66046
CMP Books
CMP Media LLC
1601 West 23rd Street, Suite 200
Lawrence, Kansas 66046
USA
www.cmpbooks.com

Designations used by companies to distinguish their products are often claimed as trademarks. In
all instances where CMP Books is aware of a trademark claim, the product name appears in initial
capital letters, in all capital letters, or in accordance with the vendor’s capitalization preference.
Readers should contact the appropriate companies for more complete information on trademarks
and trademark registrations. All trademarks and registered trademarks in this book are the prop-
erty of their respective holders.

Copyright © 2002 by Jeremy Bentham, except where noted otherwise. Published by CMP Books,
CMP Media LLC. All rights reserved. Printed in the United States of America. No part of this pub-
lication may be reproduced or distributed in any form or by any means, or stored in a database or
retrieval system, without the prior written permission of the publisher; with the exception that the
program listings may be entered, stored, and executed in a computer system, but they may not be
reproduced for publication.

The programs in this book are presented for instructional value. The programs have been carefully
tested, but are not guaranteed for any particular purpose. The publisher does not offer any war-
ranties and does not guarantee the accuracy, adequacy, or completeness of any information herein
and is not responsible for any errors or omissions. The publisher assumes no liability for damages
resulting from the use of the information in this book or for any infringement of the intellectual
property rights of third parties that would result from the use of this information.

Acquisitions Editor: Robert Ward


Managing Editor: Michelle O’Neal
Editor: Rita Sooby
Layout production: Kris Peaslee
Cover art: Robert Ward
Cover design: Damien Castaneda

Distributed in the U.S. and Canada by:


Publishers Group West
1700 Fourth Street
Berkeley, California 94710
1-800-788-3123
www.pgw.com

ISBN: 1-57820-108-X
To Fred, Ilse, and Jane
Table of Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
The Lean Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Embedded Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xii
The Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
The Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
The Operating System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv
The Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv
The Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv

Chapter 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . 1
The Lean Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2
Software Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5
Network Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5
Device Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8
Configuration File Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
Process Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
State Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17
Buffering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21
Coding Conventions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29

v
vi Table of Contents

Chapter 2 Introduction to Protocols: SCRATCHP . . . . . .31


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
SCRATCHP Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Logical Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Packet Format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Protocol Identification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Reception and Transmission . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Implementation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

Chapter 3 Network Addressing and Debugging . . . . . . .71


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Internetworks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
IP Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Address Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
ARP Scanner. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Using ARPSCAN for Network Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Ethernet 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
IEEE 802.3 Networks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

Chapter 4 The Network Interface: IP and ICMP . . . . . . .95


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
TCP/IP Stack. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Internet Control Message Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Ping Implementation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Router Implementation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

Chapter 5 User Datagram Protocol: UDP . . . . . . . . . . .135


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Ports and Sockets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Datagram Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
UDP Checksum. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
UDP Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Table of Contents vii

Chapter 6 Transmission Control Protocol: TCP . . . . . 155


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .155
TCP Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .156
TCP Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .169
TCP Application — Telnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .188
Telnet Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .190
Using Telnet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .199
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .203

Chapter 7 Hypertext Transfer Protocol: HTTP . . . . . . 207


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207
HTTP GET Method. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207
Simple Web Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .211
Introducing HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .217
State Machine Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .226
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .235

Chapter 8 Embedded Gateway Interface: EGI. . . . . . . 237


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .237
Interactive Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .237
Standard CGI interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .244
EGI Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .249
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .267

Chapter 9 Miniature Web Server Design . . . . . . . . . . 269


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .269
Microcontroller Software Development . . . . . . . . . . . . . . . . . . . . . . . . . . . .270
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .270
Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .274
Software Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .275
Web Server Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .278
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .290

Chapter 10 TCP/IP on a PICmicro® Microcontroller. . 291


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .291
Peripherals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .291
Block Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .294
Circuit Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .294
Low-Level Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .296
viii Table of Contents

SLIP and IP Drivers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303


ICMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329

Chapter 11 PWEB: Miniature Web Server for the


PICmicro® . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Web Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
ROM File System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Using the PWEB Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
Dynamic Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Dynamic Web Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367

Chapter 12 ChipWeb — Miniature Ethernet Web


Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .369
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Ethernet Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
LCD Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Other Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Protocols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Protocol Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409

Chapter 13 Point-to-Point Protocol: PPP . . . . . . . . . . .411


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Design of PPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Protocol Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Sample PPP Negotiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
PPP Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Table of Contents ix

Chapter 14 UDP Clients, Servers, and Fast Data


Transfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .435
Client–Server Networking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .435
Peer-to-Peer Networking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .437
Beyond the Web Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .438
Buffer Enhancements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .438
IP and ICMP Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .445
UDP Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .448
UDP Time Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .451
High-Speed Data Transfer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .457
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .458
Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .461
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .467

Chapter 15 Dynamic Host Configuration Protocol:


DHCP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .471
DHCP Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .472
Sample Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .477
DHCP Implementation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .481
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .487

Chapter 16 TCP Clients, SMTP, and POP3 Email . . . . 489


Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .489
TCP Client Techniques. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .490
TCP Client Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .494
SMTP Email Client. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .502
POP3 Email Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .509
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .515

Appendix A Configuration Notes . . . . . . . . . . . . . . . . 517


Network Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .517
Addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .519
Testing the Network. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .519
Windows SLIP Configuration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .520
x Table of Contents

Appendix B Resources . . . . . . . . . . . . . . . . . . . . . . . . .523


Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524

Appendix C Software on the CD-ROM . . . . . . . . . . . .527


ARPSCAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
DATAGRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
NETMON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
PICmicro® Software. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
PING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
ROUTER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
SCRATCHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
TELNET. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
WEBROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
WEBSERVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
WEB_EGI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533

Appendix D PICmicro®-Specific Issues . . . . . . . . . . . .535


Compiler Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535

Function Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .541

Stucture Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .545

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .547

What’s on the CD-ROM? . . . . . . . . . . . . . . . . . . . . . . . . . . .576


Preface
The Lean Plan
This is a hands-on book about TCP/IP (transmission control protocol/Internet protocol) net-
working. You can browse it to get an overview of the subject or study a particular section in
detail, but to get maximum benefit, I suggest you set up your own network and try out the
software for real.
Not so long ago, I would have given you a detailed description of a computer network
called the Internet and how it allowed academics to pass information between their comput-
ers using the TCP/IP protocol family. Now the Internet encroaches all aspects of our lives, so
an introduction to it seems totally unnecessary. Yet a hands-on introduction to TCP/IP seems
highly necessary, because the very size of the Internet presents a massive barrier to those wish-
ing to understand its inner workings.
My first attempt at implementing TCP was not a great success. I’d waded through the spec-
ifications and thought, “this isn’t too bad,” and waded through the few public domain sources
I could find and thought, “this is horrendously complicated,” then wrote my own implementa-
tion. When I came to test it, the problems started in earnest. I couldn’t find a sensible set of
software tools for testing; whenever I found a problem, I wasn’t sure whether the fault lay
with the test software, the software under test, or my understanding of the specification.
What I needed was
• an implementation I could understand — not a heavyweight implementation for a
large multiuser operating system, but a lightweight one that clearly showed the underlying
principles — and
• software tools I could use; that is, test utilities that allowed me to check my understand-
ing and implementation of the protocols.

xi
xii Preface

As time went by and my TCP/IP software matured, the Web became increasingly impor-
tant. My industrial customers would browse the Web at home or work and could see the
advantages of using a Web browser for remote control and to monitor their industrial equip-
ment. TCP became just a vehicle for conveying Web pages. The focus shifted from “I want
TCP/IP on my system” to “I want my system to produce Web pages,” and these pages always
included dynamic real-time data.
History was repeating itself; the software to produce these dynamic Web pages was
designed for large multiuser systems, and I couldn’t find small-scale implementations that
were usable on simple, low-cost embedded systems hardware. I needed:
• a description of the techniques to insert live data into Web pages and
• some simple platform-independent code that I could adapt for specific projects.
Having implemented many small-scale Web servers of my own (generally an 80188 pro-
cessor with 64Kb of ROM), I was delighted to hear of a 256-byte implementation on a
microcontroller, although I was disappointed to discover that it could only produce fixed
pages from its ROM, with no dynamic data. I wanted to know:
• what compromises were associated with implementing TCP and a Web server on a
microcontroller and
• what techniques I could use to insert dynamic data into its Web pages.
Almost by chance, the first edition of this book included a miniature Web server running
on a PICmicro®1. I wasn’t the first to create such a server, but I was the first to publish a full
description of the techniques used, including full source code. The success of the initial
offering prompted me to update this book to broaden the range of networks and protocols
supported on the PICmicro. Despite the “Web servers” in the title of this book, there are many
ways to transfer data across a network, and I wanted to provide working examples of their
use.
Hopefully, you’ll find the answers you want in this book.

Embedded Systems
The term “embedded system” may be new to some of you and require some explanation,
even though you use embedded systems every day of your life. Microwave ovens, TVs, cars,
elevators, and aircraft are all controlled by computers, which don’t necessarily have a screen,
keyboard, and hard disk. A computer could be controlling your car without your knowledge:
an engine management system takes an input signal from the accelerator and provides out-
puts that control the engine.
These computers are embedded in a system, of which they may be only a small compo-
nent. The embedded system designer may have to work within tight constraints of size,
weight, power consumption, vibration, humidity, electrical interference, and above all, cost
and reliability. The PC architecture has been adapted for embedded systems operation, and
rugged single-board computers (SBCs) are available from a wide variety of suppliers, together
with the necessary add-on cards to process real-world signals. The ultimate in miniaturization

1. PICmicro® is the registered trademark of Microchip Technology Inc.


The Hardware xiii
is the microcontroller, which is a complete computer on a single chip, including all the neces-
sary I/O interfaces.
Regardless of the user interface, most embedded systems have an external interface for
status monitoring and system diagnosis. Traditionally this has been in the form of a serial ter-
minal, but industry is starting to see the advantages of remote diagnosis: because Web
browser usage is so widespread, it seems the logical choice for a user interface. The browser is
technically a Web client, which implies that the embedded system must be a Web server;
hence, the title of this book.
Whether you are an embedded systems developer or not, I trust you will find plenty of
interest in this book. I’ll look at
• what software components are needed,
• how these components work,
• clear, simple implementation, and
• effective test strategies.
The qualities of simplicity and clarity have much to recommend them. Modern program-
ming toolkits are very useful because they can simplify a complex programming task so it
becomes a join-the-dots exercise, but the resulting bloated code may require much more com-
plex hardware than the slim-line code of your competitor; hence, the Lean Plan.

The Hardware
At the time of writing, the PC hardware platform, although distinctly showing its age, cannot
be ignored. The second-hand market is awash with perfectly serviceable PCs that don’t con-
tain the latest and fastest technology but are more than adequate for your purposes. There are
low-cost industrial SBCs that have a PC core, standard network interface, and the ability to
accept interface cards for a wide variety of real-world signals.
My software will run on all these PC compatibles, and even on PC incompatibles (such as
the 80188 CPU) with a very small amount of modification, because I have clearly isolated all
hardware and operating-system dependencies.
In addition to the PC code, I have included a miniature TCP/IP stack and Web server for a
Microchip PICmicro® microcontroller, using the Custom Computer Services PCM C com-
piler. A standard PICmicro evaluation board can be hand-modified to include the appropriate
peripherals (a circuit diagram is given), or a complete off-the-shelf board can be purchased
instead. I won’t pretend that it would be easy to adapt this software to another processor, but
there is an in-depth analysis of the difficulties associated with microcontroller implementa-
tions, which would give you a very significant head-start if working with a different CPU.

The Network
Base-level Ethernet (10Mbit) is still widely available; complete kits, including interface cards
and cabling, are available at low cost from computer retailers. My software directly supports
two of the most popular Ethernet cards — Novell NE2000 compatibles and 3COM 3C509
— and can potentially (if using the Borland Compiler) support other cards through the packet
driver interface, though the direct hardware interface approach is preferable because it makes
experimentation and debugging much easier.
xiv Preface

When developing network software, you are very strongly advised to use a separate scratch
network, completely isolated from all other networks in the building. Not only does debug-
ging become much easier, but you also avoid the possibility of disrupting other network traffic.
It is remarkable how a minor change to the software can result in a massive increase in the net-
work traffic and a significant disruption to other network users. You have been warned!
The software also supports serial links through SLIP (serial line Internet protocol), and a
crossover serial cable between two PCs can, to a certain extent, be used as a substitute for a
real network.

The Operating System


You may be surprised by the extent to which I ignore the operating system. In the embedded
systems market, there is always pressure to simplify the hardware and reduce the costs, and
one way of achieving this is to use the simplest possible operating system, or none at all.
For those of you wedded to complex operating systems, and even more complex software
development environments, this will initially be an uncomfortable experience because you are
exposed to the harsh reality of real bare-metal programming. However, I hope that you will
soon come to appreciate the power, flexibility, and pure simplicity of this approach and grad-
ually come to the realization that for many common or garden-variety applications, an oper-
ating system (even a free operating system) is an expensive luxury. Luxury or not, I want to
use my desktop PC for development, so the software is compatible with Windows 95 and 98,
either in DOS, extended DOS, or Win32 console application mode.
My primary development system is a Windows 95 machine equipped with two network
cards — only one of which is installed in the operating system. This is extremely useful
because a single machine can simultaneously act as both network client (using a standard
Web browser) and server (using my Web server), making experimentation much easier.
The final target machine can be a relatively humble SBC running DOS or a microcontrol-
ler compatible with PC code without an operating system, although the latter would entail
some minor changes to the software provided.

The Development Environment


The following four PC compilers are supported.

Borland C++ v3.1. An excellent DOS-hosted compiler with an integrated development


environment.
Borland (Inprise) C++ v4.52. Windows-hosted compiler, which seems to be the latest ver-
sion that can generate executable files for DOS.
Microsoft Visual C++ v6. Windows-hosted compiler that can generate Win32 console
applications.
DJGPP v2.02 with RHIDE v1.4. Part of the GNU project, this is a remarkably good clone
of the Borland 3.1 development environment, which runs in a 32-bit extended DOS environ-
ment and can be downloaded free of charge.

The Borland compilers, though ostensibly obsolete, may be found on the CD-ROM of
some C programming tutorial books or may be bundled with their 32-bit cousins. The
The Software xv
high-level software can be compiled using all of these environments, but I have not been so
fortunate with the low-level network interface code.
• The Borland compilers are the easiest to use because they allow the use of interrupts
without the need for machine code inserts and so can support the full range of network
interfaces.
• With the Microsoft compiler, the network card and SLIP interfaces are supported, but the
packet driver interface is not.
• Only the direct network card interface is supported when using the DJGPP compiler.
Because the direct network card interface is the easiest to debug, and hence more suitable
for experimentation, this restriction isn’t as onerous as it might appear.
If your favorite compiler isn’t on the list, I apologize for the omission, but I am very
unlikely to add it. Each compiler represents a very significant amount of testing, and my pref-
erence is to reduce, rather than increase, the number of compilers supported. If your compiler
is similar to the above (for example, an earlier version), then you should have little or no
adaptation work to perform, though I can’t comment on any compiler I haven’t tried.

PICmicro Compilers. The early software used the Custom Computer Services (CCS) PCM
v2.693, but later developments are broadly compatible with the CCS and Hitech compilers
for the PIC16xxx and PIC18xxx series microcontrollers. A detailed discussion of compatibil-
ity issues is beyond the scope of this chapter. See Appendix D and the software release notes
on the CD-ROM for more information.

The Software
The enclosed CD-ROM contains complete source code to everything in this book so that you,
as purchaser of the book, can experiment. However, the author retains full copyright to the
software, and it may only be distributed in conjunction with the book; for example, you may
not post any of the source code on the Internet or misrepresent its authorship by extracting
fragments or altering the copyright notices.
If you want to sell anything that contains this software, a license is required for the
“incorporation” of the software into each commercial product. This normally takes the form
of a one-off payment that allows unlimited incorporation of any executable code derived
from this source. There are no additional development fees (apart from purchase of the
book), and license fees are kept low to encourage commercial usage. Full details and software
updates are on the Iosoft Ltd. Web site at www.iosoft.co.uk.

Acknowledgments
The author owes a profound debt of gratitude to Berney Williams of CMP Books for being so
keen on this project, Anthony Winter for his proofreading skills and advice, Glen Middleton
of Arcom Control Systems Ltd. and Adrian Nicol of Io Ltd. for their help with the hardware,
and, above all, to Jane McSweeney (now Jane Bentham) for her continued enthusiasm, sup-
port, and wonderful cakes.
xvi Preface
1
Chapter 1

Introduction
The Lean Plan
This is a software book, so it contains a lot of code, most of which has been specially written
(or specially adapted) for the book. The software isn’t a museum piece, to be studied in a
glass case, but rather a construction kit, to promote understanding through experimentation.
The text is interspersed with source code fragments that illustrate the points being discussed
and provide working examples of theoretical concepts. All the source code in the book, and
complete project configurations for various compilers, are on the enclosed CD-ROM.
When I started writing this book, I intended to concentrate on the protocol aspects of
embedded Web servers, but I came to realize that the techniques of providing dynamic con-
tent (on-the-fly Web page generation) and client/server data transfers were equally important,
yet relatively unexplored. Here are some reasons for studying this book.

TCP/IP. You want to understand the inner workings of TCP/IP and need some tools and
utilities to experiment with.

Dynamic Web Content. You have an embedded TCP/IP stack and need to insert dynamic
data into the Web pages.

1
2 Chapter 1: Introduction

Miniaturization. You are interested in incorporating a miniature Web server in your sys-
tem but need to understand what resources are required and what compromises will have to
be made.

Prototyping. You want a prebuilt Web server that you can customize to evaluate the con-
cept in a proposed application.

Data transfer. You need to transfer data across a network using standard protocols.

Client/server programming. You have to interface to standard TCP/IP applications, such


as email servers.

Of course, these areas are not mutually exclusive, but I do understand that you may not
want to read this book in a strict linear order. As far as possible, each chapter stands on its own
and provides a stand-alone utility that allows you to experiment with the concepts discussed.
I won’t assume any prior experience with network protocols, just a working knowledge of
the C programming language. In the Preface, I detailed the hardware and software you would
need to take full advantage of the source code in the book. You don’t have to treat this book
as a hands-on software development exercise, but it would help your understanding if you
did.

Getting Started
On the CD-ROM, you’ll find the directory tcplean with several subdirectories.

BC31 compiler-specific files for Borland C++ v3.1


BC45 compiler-specific files for Borland C++ v4.52
DJGPP compiler-specific files for (GNU) DJGPP and RHIDE
PCM the PICmicro®-specific1 files for Chapters 9–11
ROMDOCS sample documents for the PICmicro Web server
SOURCE all source code for PC systems
VC6 compiler-specific files for Microsoft Visual C++ v6
WEBDOCS sample documents for the PC Web server

You’ll also find the directory chipweb with a two subdirectories containing the files for
Chapters 12–16.

ARCHIVE zip files containing older versions of the ChipWeb source code
P16WEB latest ChipWeb source code
Executable copies of all the utilities, sample configuration files, and a README file with any
late-breaking update information are in tcplean. Preferably, the complete directory tree d:\
tcplean (where d: is the CD-ROM drive) should be copied to c:\tcplean on your hard disk,

1. PICmicro® is the registered trademark of Microchip Technology Inc.; PICDEM.net™ is the trade-
mark of Microchip Technology Inc.
Getting Started 3
and d:\chipweb to c:\chipweb. If a different directory path is used, it will be necessary to edit
the compiler project files.
The utilities read a configuration file to identify the network parameters and hardware
configuration; the default is tcplean.cfg, read from the current working directory. It is
unlikely that this will contain the correct hardware configuration for your system, so it is
important that you change the configuration file before running any of the utilities. See
Appendix A for details. If you attempt to use my default configuration without checking its
suitability, it may conflict with your current operating system settings and cause a lockup.
It is possible to browse the source files on the CD-ROM and execute the utilities on it
without loading them onto your hard disk, though you still need a to adapt the configuration
file and store it in the current working directory.
c:\>cd tcplean
c:\tcplean>d:\tcplean\ping 10.1.1.1
This would execute the utility on the CD-ROM using the configuration file.
c:\tcplean\tcplean.cfg
The default configuration file may be overridden using the -c command-line option.
c:\tcplean>ping -c slip 172.16.1.1
This uses the alternative configuration file slip.cfg, which makes it possible to experiment
with multiple network configurations without having to rebuild the software each time.
If you are in any doubt about the command-line arguments for a utility, use the -? option.
c:\>cd tcplean
c:\tcplean>ping -?
Some of the utilities have the same name as their DOS counterparts (because they do the same
job), so it is important to change to tcplean before attempting to run them.
A final word of warning: I strongly recommend that you create a new “scratch” network
for your experimentation that is completely isolated from all other networks in the building.
It is a very bad idea to experiment on a “live” network.

Network Configuration
The DOS software in this book supports the following network hardware.

Direct-drive network card Novell NE2000-compatible or 3COM 3C509 Ethernet cards


can be direct-driven by the software. This is the preferred option because of the ease of con-
figuration and debugging.
Serial link A serial line Internet protocol (SLIP) link between two PCs or a PC and the PIC-
micro miniature Web server.
Packet driver An otherwise unsupported network card may be used via a Crynwr packet
driver supplied by the card manufacturer.

Some combinations of network hardware and compiler are not supported. Consult Appendix
A and the README file for full information on the network configuration options.
4 Chapter 1: Introduction

Compiler Configuration
Executable versions of all the DOS projects are included within the tcplean directory, so ini-
tial experimentation can take place without a compiler. The project files for each compiler
reside in a separate directory, as described earlier, and all the compiler configuration informa-
tion resides within the project files. All the source code files reside in a single shared directory.
There are a few instances where compiler-specific code (generally Win32-specific code) must
be generated, in which case automatic conditional compilation is used.
Load specific projects for the following compilers:

Borland C++ v3.1 In a DOS box, change to the BC31 directory and run BC using the
project filename.

c:\>cd \tcplean\bc31
c:\tcplean\bc31>bc ping.prj

Borland C++ v4.52 Launch the Integrated Development Environment (IDE) and select
Project–Open Project and the desired IDE file in the BC45 directory.
DJGPP and RHIDE Launch the RHIDE IDE and select Project–Open Project and the
desired GPR file in the DJGPP directory.
Visual C++ v6 Launch the IDE and select File–Open Workspace and the desired DSW file
in the VC6 directory.
Custom Computer Services PCM The PICmicro cross-compiler uses a completely differ-
ent set of source code that resides in the PCM directory. Open a DOS box and change direc-
tory to \tcplean\pcm. Copy the necessary system files (16C76.h and ctype.h) into this
directory from the standard PCM distribution. Run the PCM compiler, specifying PWEB.C on
the command line.

c:\>cd \tcplean\pcm
c:\tcplean\pcm>copy \picc\examples\16c76.h
c:\tcplean\pcm>copy \picc\examples\ctype.h
c:\tcplean\pcm>\picc\pcm pweb.c
I run the PCM compiler from within the IDE of an emulator; see the emulator documenta-
tion for details on how to do this. When first using such a setup, make a minor but readily
observable change, rebuild, and check that the new executable really has been downloaded
into the emulator. It is all too easy to omit a vital step in the rebuild chain, such that the old
file is still being executed.

Other PICmicro® Compilers


The software in Chapters 12–16 is broadly compatible with the later versions of the CCS and
Hitech PICmicro compilers, for both the PIC16xxx and PIC18xxx series of devices. There are
compatibility issues with some versions of these compilers; see Appendix D for guidance on
compiler-specific issues, and always refer to the release notes (in file readme.txt) before using
a specific ChipWeb release.
Software Introduction 5

Software Introduction
For the rest of this chapter, I’ll look at the low-level hardware and software functions needed
to support software development.
• network hardware characteristics
• network device drivers
• process timing
• state machines
• buffering
• coding conventions
Even if you’re keen to get on with the protocols, I suggest you at least skim this material,
since it forms the groundwork for the later chapters.

Network Hardware
To help in setting up a serial or network link, I’ve included some sample configurations in
Appendix A, together with the relevant software installations. Assuming one or both are
installed, I will examine their characteristics with a view to producing the low-level hardware
device drivers.

Figure 1.1 Serial link and network topologies.


Serial link

Network - bus topology

Network - star topology


6 Chapter 1: Introduction

Figure 1.1 shows two types of networks (two “topologies”): the older style bus network,
where the computers are connected to a single common cable, and the newer star network,
where the computers are individually connected to a common box (a hub), which electrically
copies the network signals from one computer to all others. Fortunately, the operation of an
Ethernet hub is completely transparent to the software, so you can still treat the network as if
the computers were sharing a common cable.

Serial Hardware Characteristics


The simplest communication link between two PCs (A and B) consists of three wires: a ground
connection, a wire from the A transmit to the B receive, and a wire from the B transmit to the
A receive. A commercial serial crossover cable (often called a null modem or “Laplink” cable)
generally has more wires connected so that the handshake signals are transferred, but you’ll
concentrate on the two data lines, which have the following characteristics.

Both computers have equal access to the serial link. The hardware simply acts as a
“data pipe” between the two computers and does not prioritize one computer above another.

There are only two computers (nodes) on the network. Throughout this book, I’ll use
“node” as shorthand for “a computer on the network.” Insofar as the simple serial link con-
stitutes a network, it is clear that if one node transmits a message, it can only be received by
the other node and no others.

A node can transmit data at any time. This is technically known as a full duplex system;
both computers can transmit and receive simultaneously without any clash of data signals.

Message delivery is reliable. The assumption is that the two nodes are close to each
other, with a short connecting cable, so there will be no corruption of data in transit. The pre-
dominant failure mode is a catastrophic link failure, such as a disconnection of the cable or a
node powering down.

The serial data is a free-format stream of bytes, with little or no integrity checking.
The serial hardware is only designed for short-distance interconnects, so it has a very simple
error-checking scheme (parity bit), which is often disabled. To guarantee message integrity,
error checking must be provided in software.

There is no limit on message size. Because the serial data is simply a stream of bytes
with no predefined start or end, there is no physical restriction on its length.

There is no need for addressing Because there is only one possible recipient for each
message, there is no need to include an address identifying that recipient.

Network Hardware Characteristics


Whatever the actual topology, a base-level Ethernet network appears logically to be two or
more computers transmitting and receiving on a single shared medium (cable).
Network Hardware 7
All computers on the network have equal access to the network. This is called peer-
to-peer networking, in which all nodes are equal. The alternative (master–slave networking)
assumes that one or more special nodes control and regulate all network traffic; they are the
masters, and their slaves only speak when spoken to. Master–slave operation is very useful
for industrial data acquisition, where all data and control is to be funneled through a few
large computer systems but prohibits the kind of ad hoc communication that is required in an
office or on the Internet.

All nodes have a 48-bit address that is unique on the network. Just as a postal address
uniquely identifies a specific location in the world, so a node address (generally known as a
media access and control, or MAC, address) must uniquely identify a node on the network. In
fact, the standardization of Ethernet guarantees each node address to be also unique in the
world; you can mix and match Ethernet adaptors from different manufacturers, secure in the
knowledge that no two will have the same 48-bit address.

Any node may transmit on the network when it is idle. If a node is to communicate
with another, it must wait for all others to be silent before it can transmit. Because all nodes
are equal, they need not ask permission before transmitting on the network; they simply wait
for a suitable gap in the network traffic.

Message delivery is unreliable. “Unreliable? Why don’t you fix it?” Networks are, by
their very nature, an unreliable way of sending data. The failure modes range from the cata-
strophic (the recipient’s computer is powered down or physically disconnected from the net-
work) to the intermittent (a packet has been corrupted by collision or electrical interference).
The network hardware has the ability to detect and compensate for some intermittent faults
(e.g., a retry in the event of a packet collision), but eventually an error will occur that has to
be handled in software, so the software must assume the network is unreliable.

All data on the network is in blocks (frames) with a defined beginning and end and
an integrity check. Nodes that are going to transmit when they want need a defined for-
mat for their transmissions so that others know when they are starting or finishing, assuming
each transmission is a block with start and end markers and some form of checking (usually a
CRC, or cyclic redundancy check) to ensure it hasn’t been damaged in transit. The name
given to this block differs according to the network used; Ethernet blocks are called frames.

The network can send a maximum of 1,500 bytes of data per frame. All networks
have an upper limit on the size of data they can carry in one frame. This is called the maxi-
mum transfer unit, or MTU. Ethernet frames can contain up to 1.5Kb, but TCP/IP software
will work satisfactorily with a lot smaller MTU.

All messages are equipped with a source and destination address. Frames are usu-
ally intended for a single recipient; this is known as unicast transmission. Occasionally, it may
be necessary to send a frame to all nodes on the network, which is a broadcast transmission.
8 Chapter 1: Introduction

Device Drivers
It would be helpful if the driver software presented a common interface to the higher-level
code, but it is clear from the preceding analysis that there are significant differences; these are
summarized in Table 1.1.

Serial Driver Requirements


TCP/IP assumes the network data is sent in blocks, with a defined beginning and end, so the
serial drivers must convert the free-format serial byte stream into well-defined blocks.
Table 1.1 RS232 serial versus Ethernet.

RS232 Serial Ethernet


Access Equal Equal
Address range None 48-bit
Transmit Any time When network is idle
Delivery Reliable Unreliable
Format None (data stream) Frame
Data length Unlimited 1.5Kb per frame
Addressing None Source, destination, broadcast

SLIP
Fortunately, one of the TCP/IP families of standards, SLIP, provides exactly this functionality. It
uses simple escape codes inserted in the serial data stream to signal block boundaries as follows.
• The end of each block is signaled by a special End byte, with a value of C0h.
• If a data byte equals C0h, two bytes with the values DB, DC are sent instead.
• If a data byte equals DBh, two bytes with the values DB, DD are sent instead.
Additionally, most implementations send the End byte at the beginning of each block to
clear out garbage characters prior to starting the new message (Figure 1.2).

Figure 1.2 SLIP frame.

END Data END


C0h 1-1006 bytes C0h

There is effectively no limit to the size of the data block, but you have to decide on some
value in order to dimension the data buffers. With old slow serial links, a maximum size of
256 bytes was generally used, but you’ll be using faster links, and a larger size is better for
minimizing protocol overhead. By convention, 1,006 bytes is often used.
The encoding method can best be illustrated by an example (Figure 1.3). Assume a six-
byte block of data with the hex values BF C0 C1 DB DC is sent; it is expanded to C0 BF DB DC C1
DB DD DC C0.
Device Drivers 9
Figure 1.3 SLIP example.

BFh C0h C1h DBh DCh

END END
BFh DBh DCh C1h DBh DDh DCh
C0h C0h

The original data has nearly doubled in size, due to my deliberately awkward choice of
data values. In normal data streams, the overhead is much lower.

Modem Emulation
An additional problem with serial networking is that most PCs are configured to use a
modem (Figure 1.4) to an Internet Service Provider (ISP).

Figure 1.4 Modem communication.

Web browser Web server

Serial Telephone Serial

PC system Modem Modem Service Provider

I’ll create a Web server, but instead of two modems, I’ll use a serial (null modem) cable to
link it to the browser. The problem is that my Web server will then receive the browser’s com-
mands to its modem. If these go unanswered, the browser will assume its modem is faulty and
report this to the user.
The easiest solution is to include a simple modem emulator in your serial driver so that the
browser is fooled into thinking it is talking to a modem. Because modem commands are text
based, you can easily distinguish between them and the SLIP message blocks prefixed by the
delimiter character (C0h); when the latter appears, disengage the modem emulation.
Modem commands begin with the uppercase letters AT, followed by zero or more alpha-
betic command letters, with alphabetic or numeric arguments, terminated by an ASCII car-
riage return (<CR>) character. The usual reply are the uppercase letters OK, followed by a
carriage return and line feed (<CR><LF>). Table 1.2 shows a few typical command–response
10 Chapter 1: Introduction

sequences for a simple modem. This emulation would respond OK to all commands; this is
normally sufficient.
Table 1.2 Modem command–response sequences.

Browser Modem Response


AT<CR> OK<CR><LF> Check modem present
ATZ<CR> OK<CR><LF> Reset modem
OK<CR><LF>
ATDT12345 CONNECT 38400<CR><LF> Dial phone number

Ethernet Driver Requirements


The Ethernet message (frame) is necessarily more complicated than the serial message (Figure
1.5). It contains the
• destination address,
• source address,
• type/length field,
• data, and
• cyclic redundancy check (CRC).

Figure 1.5 Ethernet frame.

Dest Srce Type Data CRC


6 bytes 6 bytes 2 bytes 46-1500 bytes 4 bytes

Ethernet frame 64 - 1518 bytes


It is traditional to include the CRC when quoting the Ethernet frame size (e.g. a maximum
frame size of 1518 bytes), even though it is ignored by the software, and is usually removed
by the lower-level driver code.

#define MACLEN 6 /* Ethernet (MAC) address length */

/* Ehernet hardware Rx frame length includes the trailing CRC */


#define MAXFRAMEC 1518 /* Maximum frame size (incl CRC) */
#define MINFRAMEC 64 /* Minimum frame size (incl CRC) */

/* Higher-level drivers exclude the CRC from the frame length */


#define MAXFRAME 1514 /* Maximum frame size (excl CRC) */
#define MINFRAME 60 /* Minimum frame size (excl CRC) */
Device Drivers 11

/* Ethernet (DIX) header */


typedef struct {
BYTE dest[MACLEN]; /* Destination MAC address */
BYTE srce[MACLEN]; /* Source MAC address */
WORD ptype; /* Protocol type or length */
} ETHERHDR;

/* Ethernet (DIX) frame; data size is frame size minus header & CRC */
#define ETHERMTU (MAXFRAME-sizeof(ETHERHDR))
typedef struct {
ETHERHDR h; /* Header */
BYTE data[ETHERMTU]; /* Data */
LWORD crc; /* CRC */
} ETHERFRAME;
This is the basic Ethernet frame, also known as Ethernet 2 (Ethernet 1 is obsolete), or DIX
Ethernet (after its creators, DEC, Intel, and Xerox).

Destination and Source Addresses


These six-byte values identify the recipient and sender of the frame and are generally known
as media access and control (MAC) addresses. They are standardized by the IEEE; the first
three bytes identify the network hardware vendor, and the next three are used by that vendor
to guarantee the address is unique, so they are different for every network adaptor that the
manufacturer has ever produced.
Each adaptor has its six-byte address burned into a memory device at manufacture, but it
is normally the responsibility of the networking software to copy this value into the appropri-
ate field of the network packet. A destination address of all ones indicates a broadcast address.

Type/Length Field
Unfortunately, there are several Ethernet standards, and they make different use of this two-
byte field. One standard uses it as a length, giving the total count of bytes in the data field.
Others use it as a protocol type, indicating the protocol that is being used in the data field.
Mercifully there are simple ways of detecting and handling these standards, which are dis-
cussed in Chapter 3.

Data
This area contains user data in any format; the only restrictions are that its minimum size is
46 bytes and its maximum is 1,500 bytes. The minimum is necessary to ensure that the over-
all frame is at least 64 bytes. If it were smaller, there would be a danger that frame collisions
wouldn’t be detected on large networks.
12 Chapter 1: Introduction

Cyclic Redundancy Check


This is a check value that allows the network controller to discard corrupted frames. It is
automatically appended by the Ethernet controller on transmit and checked on receive. The
bit-by-bit algorithm is particularly suited to hardware implementation. The following code
fragment is equivalent but operates on byte values.
#define ETHERPOLY 0xedb88320L

/* Update CRC for next input byte */


unsigned long crc32(unsigned long crc, unsigned char b)
{
int i;

for (i=0; i<8; i++)


{
if ((crc ^ b) & 1)
crc = (crc >> 1) ^ ETHERPOLY;
else
crc >>= 1;
b >>= 1;
}
return(crc);
}

A starting CRC value of FFFFFFFFh is sent to this function, together with the first byte
value. A new CRC value is returned, which is sent to this function together with the next byte
value, and so on. When all bytes have been processed, the final CRC value is inverted (one’s
complement) to produce the four-byte Ethernet CRC, which would be transmitted least sig-
nificant byte first.

Generic Driver Functions


You need some generic network driver functions that are usable for a variety of network
types and hardware configurations. This node-specific information will be in a configuration
file and read from disk at boot time. The following code fragments show what a line in this
file might look like.
net ether ne 0x280

This specifies an Ethernet interface using an NE2000-compatible card at I/O address 280h.
See Appendix A for details on the cards and networks supported.
This string passed to a network initialization function, to open the required interface.
WORD open_net(char *cfgstr);
Device Drivers 13
This function opens up the network driver, given a string specifying the type of driver and
configuration parameters, and returns a driver type, which must be used in all subsequent
accesses, or a 0 on error (e.g., when the hardware is in use by other software).
void close_net(WORD dtype);

This function shuts down the network driver. The returned value for the driver type serves
two purposes: it provides a unique handle for the interface, and its flags inform you of the
type of interface in use. This allows you to create software that can handle multiple network
interfaces, each with different hardware characteristics.
You need a generic frame that can accommodate any one of the different frame types. Its
header includes the driver type.
/* General-purpose frame header, and frame including header */
typedef struct {
WORD len; /* Length of data in genframe buffer */
WORD dtype; /* Driver type */
WORD fragoff; /* Offset of fragment within buffer */
} GENHDR;

typedef struct {
GENHDR g; /* General-pupose frame header */
BYTE buff[MAXGEN]; /* Frame itself (2 frames if fragmented) */
} GENFRAME;

The header also has a length word to assist in low-level buffering (e.g., polygonal buffer-
ing, described later) and support for fragmentation. This is where a frame that exceeds the
MTU size is broken up, sent as two smaller frames, and reassembled at the far end. This will
be discussed further in Chapter 3; for now, you need to be aware that the maximum frame
size (MAXGEN in the above definitions) need not be constrained to the maximum Ethernet frame
size. You’ll use a MAXGEN of just over 3Kb, so two complete Ethernet frames can be stored in
the one GENFRAME.
Having standardized on a generic frame, you can create the driver functions to read and
write these frames.

WORD get_net(GENFRAME *gfp); Checks for an incoming frame. If present, it copies it into
the given buffer and returns the data length. If there is no frame, it returns 0.

WORD put_net(GENFRAME *gfp, WORD len); Sends a frame, given its length, and returns the
total transmitted length or 0 if error.

You don’t need to specify which network interface is used because the function can exam-
ine the driver-type field to determine this. Sample device drivers have been included on the
CD-ROM, but they will not be discussed here because they are highly specific to the hard-
ware (and operating system).
14 Chapter 1: Introduction

Configuration File Format


As part of the experimentation in this book, you’ll frequently need to change the software
parameters at run time. Because it is tedious to type these in every time the program runs,
they’ll be incorporated into a configuration file called tcplean.cfg. By default, utilities will
read this file from the default file path, although an alternative configuration filename can be
specified on the command line.
The file consists of ASCII text lines, each line referring to one configuration item.
# TCP/IP Lean configuration file

net ether ne 0x280


id node1
ip 10.1.1.1
gate 10.1.1.111

# EOF
Blank lines, or lines beginning with #, are treated as comments. At the start of each line is
a single lowercase configuration parameter name delimited by white space and followed by a
string giving the required parameter value(s).
The content of the file is specific to the software being run; if any configuration parameter
is unrecognized, it is ignored. In the above example, the net entry defines the network driver
to be used and its base I/O address. The node name is identified as node1, with IP address
10.1.1.1 and gateway address 10.1.1.111 given. Appendix A gives guidance on how to cus-
tomize the configuration file for the network hardware you are using.

Process Timer
When implementing a protocol, an event for a future time is often scheduled. Whenever you
send a packet on the network, you must assume that it, or the response to it, might go astray.
After a suitable time has elapsed, you may want to attempt a retry or alert the user.
Most modern operating systems have a built-in provision for scheduling such events, but I
am very keen to keep the code Operating System (OS) independent and to be able to run it on
the bare metal of small embedded systems. To this end, my software includes a minimal event
scheduler of its own, which requires a minimum of OS support and can be adapted to use the
specific features of your favorite OS.
The simplest scheduling algorithm is to delay between one event and another.
putpacket(...); /* Packet Tx */
delay(2000); /* Wait 2 seconds */
if (getpacket(...)) /* Check for packet Rx */
{
/* Handle response packet */
}
else
{
/* Handle error condition */
}
Process Timer 15
The dead time between transmission and reception is highly inefficient. If the response arrives
within 100 milliseconds (ms), the system would wait a further 900ms before processing it.
With a multitasking OS, you could use sleep instead of delay, which would wake up on
time-out or when the packet arrived (a method called blocking, since it blocks execution until
an event occurs). An alternative pseudo-multitasking method is to use timer interrupts to
keep track of elapsed time and to initiate corrective action as necessary, but this approach
would be highly specific to the OS.
A simple compromise, not entirely unfamiliar to old-style Windows programmers, is to
have the software check for its own events and handle them appropriately.
putpacket(...); /* Packet Tx */
timeout(&txtimer, 0); /* Start timer */
while (1)
{
/* Check for packet Rx */
if (getpacket(...))
{
/* Handle response packet */
}
/* Check for timeout on response */
else if (timeout(&txtimer, 2))
{
/* Handle error condition */
}
/* Check for other events */
else if ...

The timeout() function takes two arguments: the first is a pointer to a variable that will
hold the starting time (tick count), and the second is the required time-out in seconds. When
the time-out is exceeded, the function triggers an event by reloading the starting time with the
current time and returning a non-zero value. For example, the following code fragment prints
a seconds count every second.
WORD sectimer, secs=0;

timeout(&sectimer, 0);
while (1)
{
if (timeout(&sectimer, 1))
printf("%u sec\n", ++secs);
}
16 Chapter 1: Introduction

Before a timer is used, a timeout() call must be made using time value 0. This forces an
immediate time-out, which loads the current (starting) time into the timer variable. The tim-
eout() function is easy to implement, providing you take care with the data types.

/* Check for timeout on a given tick counter, return non-zero if true */


int timeout(WORD *timep, int sec)
{

WORD tim, diff;


int tout=0;

tim = (WORD)time(0);
diff = tim - *timep;
if (sec==0 || diff>=sec)
{
*timep = tim;
tout = 1;
}
return(tout);
}

If the use of unsigned arithmetic appears counterintuitive, consider the following code.
WORD a, b, diff;
a = <any starting value>;
b = a + 10;
diff = b - a;

What is the value of diff? It must be 10, whatever the starting value.
There is a hidden trap that is due to timer granularity. The if statement in the code
timeout(&sectimer, 0);
if (timeout(&sectimer, 1))

will sometimes return TRUE, even though much less than a second has elapsed. This is because
the two statements happen to bracket a timer tick, so it appears that one second has elapsed
when it has not.
A cure for this problem is to change the unit of measurement to milliseconds, although the
nonstandard millisecond timer, mstime(), must be coded for each operating system.
/* Check for timeout on a given msec counter, return non-zero if true */
int mstimeout(LWORD *timep, int msec)
{
State Machines 17

LWORD tim;
long diff;
int tout=0;

tim = mstime();
diff = tim - *timep;
if (msec==0 || diff>=msec)
{
*timep = tim;
tout = 1;
}
return(tout);
}
Alternatively, you can just document this feature by saying that there is a tolerance of –1/+0
seconds on the time measurement. Given this timing tolerance, you might be surprised that my
trivial example of printing seconds works as suggested.
WORD sectimer, secs=0;

timeout(&sectimer, 0);
while (1)
{
if (timeout(&sectimer, 1))
printf("%u sec\n", ++secs);
}

It works because the state changes in the main loop are locked to the timer tick changes.
The whole operation has become synchronous with the timer, so after a random delay of up
to one second, the one-second ticks are displayed correctly.
When working with protocols, you will frequently see software processes synchronizing
with external events, such as the arrival of data frames, to form a pseudo-synchronous sys-
tem. When testing your software, you must be sure that this rhythm is regularly disrupted
(e.g., by interleaving accesses to another system) to ensure adequate test coverage.

State Machines
When learning to program, I always avoided state machines and skipped the examples (which
always seemed to be based on traffic lights) because I couldn’t see the point. Why go to all the
effort of drawing those awkward diagrams when a simple bit of procedural code would do
the job very effectively?
Tackling network protocols finally convinced me of the error of my ways. You may think a
network transaction is a tightly specified sequence of events that can be handled by simple
procedural code, but that is to deny the unpredictability (or unreliability, as I discussed earlier)
18 Chapter 1: Introduction

of any network. In the middle of an orderly transaction, your software might see some
strangely inconsistent data, perhaps caused by a bug in the someone else’s software or your
own. Either way, your software must make a sensible response to this situation, and it can’t do
that if you didn’t plan for this possibility. True, you can’t foresee every problem that may
occur, but with proper analysis you can foresee every type of problem and write in a strategy
to handle it.
Only the simplest of network transactions are stateless; that is, neither side needs to keep
any state information about the other. Usually, each side keeps track of the other and uses the
network to
• signal a change of state,
• signal the other machine to change its state, or
• check whether the other machine has signaled a change of state.
The key word is signal. Signals are sent and received over the network to ensure that two
machines remain in sync; that is, they track each other’s state changes. The signals may be
explicit (an indicator variable set to a specific value) or implicit (a quantity exceeding a given
threshold). Either way, the signals must be detected and tracked by the recipient.
Any error in this tracking will usually lead to a rapid breakdown in communications.
When such problems occur, inexperienced network programmers tend to concentrate on the
data, rather than the states. If a file transfer fails, they might seek deep meaning in the actual
number of bytes transferred, whereas an older hand would try to establish whether a state
change had occurred and what caused it at the moment of failure. This process is made much
easier if the protocol software has specifically defined states and has the ability to display or
log the state information while it is running.
At the risk of creating a chapter that you will skip, I’d like to present a simple, worked
example of state machine design, showing the relationship between state diagram, state table,
and software for a simple communications device, the telephone.

Telephone State Machine


If you ignore outgoing calls, what states can a telephone be in?

Idle on-hook, unused


Ringing on-hook, bell ringing
Connected off-hook, connected to another phone
Sending sending speech to other phone
Receiving receiving speech from other phone

The last two states are debatable, since a telephone can send and receive simultaneously.
However, most human beings possess a half-duplex audio system (they seemingly can’t speak
and listen at the same time), so the separation into transmission and reception is logical.
A telephone changes state by a combination of electrical messages down the phone cable
and by user actions. From the point of view of a hypothetical microcontroller in the tele-
phone, these might all be considered signals.
State Machines 19
Line ring ring signal from another phone
Line idle no signal on phone line
Pick up user picks up handset
Mic. speech user speaks into microphone
Line speech speech signal from other phone
Hang up user replaces handset

It is now necessary to define which signals cause transitions between states; for example,
to change state from idle to ringing, a ring signal is required.
It is traditional to document these state changes using a state diagram such as Figure 1.6,
which is a form of flowchart with special symbols. Each circle represents a defined state, and
the arrows between circles are the state transitions, labeled with the signal that causes the
transition. So line speech causes a transition from the connected state to the receiving state,
and line idle causes the transition back to connected.
Because of the inherent limitations of the drawing method, these diagrams tend to over-
simplify the state transitions; for example, Figure 1.6 doesn’t show a state change if the user
hangs up while receiving.
A more rigorous approach is to list all the states as rows of a table and all the signals as col-
umns (Table 1.3). The table entries give a new state or are blank if there is no change of state.

Figure 1.6 Telephone state diagram.

IDLE

Line ring

Line idle

Hang up Ringing

Pick up

Connected
Mic idle
Line speech

Mic speech
Line idle

Sending Receiving
20 Chapter 1: Introduction

Table 1.3 Telephone state table.

Line speech
Mic. speech
Line Ring

Line idle

Hang up
Mic. idle
Pick up
Idle Ringing
Ringing Idle Connected Idle
Connected Sending Receiving Idle
Sending Connected Idle
Receiving Connected Idle
Once the table has been created, it isn’t difficult to generate the corresponding code. You
could use a two-dimensional lookup table, although a series of conditional statements are
generally more appropriate.
switch(state)
{
case STATE_IDLE:
if (signal == SIG_LINE_RING)
newstate(STATE_RINGING);
break;
case STATE_RINGING:
if (signal == SIG_PICKUP)
newstate(STATE_CONNECTED);
else if (signal == SIG_LINE_IDLE)
newstate(STATE_IDLE);
break;

case STATE_CONNECTED:
// ..and so on
}
Buffering 21
I have created an explicit state machine where the states, signals, and relationship between
them are clearly and explicitly identified. Contrast this with an implicit state machine, where
the current state is buried in function calls.
void idle(void)
{
while (1)
{
if (signal == SIG_LINE_RING)
ringing();
}
}
void ringing(void)
{
while (signal != SIG_HANGUP)
{
if (signal == SIG_PICKUP)
connected();
}
}
void connected(void)
{
// ... and so on

Here, the current state is indicated implicitly by the current position in the code, and it is
far harder to keep control of all the possible state transitions, particularly under error condi-
tions. The stack-based call return mechanism imposes a hierarchical structure that is ill suited
to the arbitrary state transitions required. It is important that the state machine is explicitly
created, rather than being an accidental by-product of the way the software has been struc-
tured. The requirements of the state machine must dictate the software structure, not (as is
often the case) the other way around.

Buffering
To support the protocols, three special buffer types will be used. The first is a modified ver-
sion of the standard first in, first out (FIFO) to accommodate an extra trial pointer; the sec-
ond is a fixed-data-length variant of this, and the third is a FIFO specifically designed for bit-
wide, rather than byte-wide, transfers.

FITO Buffer
The FITO (first in, trial out) is a variant of the standard FIFO, or circular buffer (Figure 1.7).
A normal FIFO has one input and one output pointer; data is added to the buffer using the
input pointer and removed using the output pointer. For example, assume that a 10-character
FIFO has the letters “ABCDEFG” added, then “ABCDE” removed, then “HIJKL” added.
22 Chapter 1: Introduction

Figure 1.7 FIFO example.

in

Start

out
in
'ABCDEFG'
A B C D E F G
added
out
in
'ABCDE'
A B C D E F G
removed
out
in
'HIJKL'
K L C D E F G H I J
added
out

The circularity of the buffer is demonstrated in Figure 1.7 by the second addition; instead
of running off the end, the input pointer wraps around to the start, providing there is suffi-
cient space (i.e., the pointers do not collide). Note that after removal, the characters
“ABCDE” are shown as still present in the buffer; only the output pointer has changed posi-
tion. This reflects standard practice, in that there is little point in clearing out unused loca-
tions, so the old characters remain until overwritten.
Now imagine this FIFO is being used in a Web server; the input text is a Web page stored
on disk, and the output is being transmitted on the network. Due to network unreliability,
you don’t actually know whether the transmitted data has been received or has been lost in
transit. If the latter, then the data will have to be retransmitted, but it is no longer in the
FIFO, so it must be refetched from disk.
It would be better if the FIFO had the ability to retain transmitted data until an acknowl-
edgment was received; that is, it keeps a marker for output data that may still be needed,
which I will call trial data, in contrast to untried data, which is data in the buffer that hasn’t
been transmitted yet; hence, the FITO buffer has one input and two output pointers, as
shown in Figure 1.8.
Having loaded “ABCDEFG” in the buffer, data fragments “ABC” and “DE” are sent out
on the network, and the trial pointer is moved up to mark the end of the trail data. “ABC” is
then acknowledged, so the output pointer can be moved up, but the rest of the data is not, so
the unacknowledged data between the output and trial pointers is retransmitted on the net-
work, followed by the remaining untried data. Finally that is all acknowledged, so the output
pointer can be moved up to join the input pointer.
Buffering 23
Figure 1.8 FITO example.

in

Start

trial
out in
'ABCDEFG'
A B C D E F G
added
trial
out
in
Trial data Untried data
'ABC'
A B C D E F G
sent
out trial
in
'DE'
A B C D E F G
sent
out trial
in
'ABC'
A B C D E F G
acknowledged
out trial
in

Timeout A B C D E F G

trial
out in
'DE'
A B C D E F G
resent
out trial
in
'FG'
A B C D E F G
sent
out trial
in
'DEFG'
A B C D E F G
acknowledged
trial
out
24 Chapter 1: Introduction

A structure stores the data and its pointers (as index values into the data array). The first
word indicates the buffer length, which allows for a variety of buffer sizes. For speed, the
buffer size is constrained to be a power of two.
#ifndef _CBUFFLEN_
#define _CBUFFLEN_ 0x800
#endif
/* Circular buffer structure */
typedef struct
{
WORD len; /* Length of data (must be first) */
LWORD in; /* Incoming data */
LWORD out; /* Outgoing data */
LWORD trial; /* Outgoing data 'on trial' */
BYTE data[_CBUFFLEN_]; /* Buffer */
} CBUFF;

A default buffer size of 2Kb is provided, which may be overridden if required. This permits a
buffer to be declared as a simple static structure.
#include "netutil.h"
CBUFF rxpkts = {_CBUFFLEN_};

Or, consider the code when using dynamically allocated memory.


#define BUFFLEN 0x2000
CBUFF *rxp;
if ((rxp = (CBUFF *)malloc(BUFFLEN+16))!=0)
{
rxp.len = BUFFLEN;
...
}

In both cases, the length value is set when the buffer is created; this is very important if
strange bugs are to be avoided.
The use of LWORD (unsigned 32-bit) buffer pointers with WORD (unsigned 16-bit) data
length may seem strange. The former is part of a Cunning Plan to map the TCP 32-bit
sequencing values directly onto these pointers, whereas the latter permits the code to be com-
piled into a 16-bit memory space (e.g., small model), if necessary. All should become clear in
subsequent chapters.
Buffering 25
In creating the buffer-handling software, it is important to retain a clear idea of what is
meant by untried data (not yet sent), and trial data (sent but not acknowledged).
/* Return total length of data in buffer */
WORD buff_dlen(CBUFF *bp)
{
return((WORD)((bp->in - bp->out) & (bp->len - 1)));
}
/* Return length of untried (i.e. unsent) data in buffer */
WORD buff_untriedlen(CBUFF *bp)
{
return((WORD)((bp->in - bp->trial) & (bp->len - 1)));
}
/* Return length of trial data in buffer (i.e. data sent but unacked) */
WORD buff_trylen(CBUFF *bp)
{
return((WORD)((bp->trial - bp->out) & (bp->len - 1)));
}
/* Return length of free space in buffer */
WORD buff_freelen(CBUFF *bp)
{
return(bp->len ? bp->len - 1 - buff_dlen(bp) : 0);
}

/* Set all the buffer pointers to a starting value */


void buff_setall(CBUFF *bp, LWORD start)
{
bp->out = bp->in = bp->trial = start;
}

When loading data into the buffer, the simple but slow method is to copy it byte-by-byte.
Instead, I’ll use either one or two calls to a fast block-copy function, depending on whether
the new data wraps around the end of the buffer. If the data is too big for the buffer, it is trun-
cated, because I’m assuming the programmer has checked the free space before calling this
function. The free space is always reported as one byte less than the actual space, so there is
no danger of the input pointer catching up with the output pointer.
/* Load data into buffer, return num of bytes that could be accepted
** If data pointer is null, adjust pointers but don't transfer data */
WORD buff_in(CBUFF *bp, BYTE *data, WORD len)
{
WORD in, n, n1, n2;
26 Chapter 1: Introduction

in = (WORD)bp->in & (bp->len-1); /* Mask I/P ptr to buffer area */


n = minw(len, buff_freelen(bp)); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - in)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1 && data) /* If anything to copy.. */
memcpy(&bp->data[in], data, n1); /* ..copy up to end of buffer.. */
if (n2 && data) /* ..and maybe also.. */
memcpy(bp->data, &data[n1], n2); /* ..copy into start of buffer */
bp->in += n; /* Bump I/P pointer */
return(n);
}

/* Load string into buffer, return num of chars that could be accepted */
WORD buff_instr(CBUFF *bp, char *str)
{
return(buff_in(bp, (BYTE *)str, (WORD)strlen(str)));
}
Removal of untried data from the buffer, so that it becomes trial data, is essentially the
inverse of the above.

/* Remove waiting data from buffer, return number of bytes */


** If data pointer is null, adjust pointers but don't transfer data */
WORD buff_try(CBUFF *bp, BYTE *data, WORD maxlen)
{
WORD trial, n, n1, n2;

trial = (WORD)bp->trial & (bp->len-1); /* Mask trial ptr to buffer area */


n = minw(maxlen, buff_untriedlen(bp)); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - trial)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1 && data) /* If anything to copy.. */
memcpy(data, &bp->data[trial], n1); /* ..copy up to end of buffer.. */
if (n2 && data) /* ..and maybe also.. */
memcpy(&data[n1], bp->data, n2); /* ..copy from start of buffer */
bp->trial += n; /* Bump trial pointer */
return(n);
}
Buffering 27
Functions to remove data from the buffer are required to complete the set and to wind back
the trial pointer so that the data is waiting for retransmission.
/* Remove data from buffer, return number of bytes
** If data pointer is null, adjust pointers but don't transfer data */
WORD buff_out(CBUFF *bp, BYTE *data, WORD maxlen)
{
WORD out, n, n1, n2;
out = (WORD)bp->out & (bp->len-1); /* Mask O/P ptr to buffer area */
n = minw(maxlen, buff_dlen(bp)); /* Get max allowable length */
n1 = minw(n, (WORD)(bp->len - out)); /* Length up to end of buff */
n2 = n - n1; /* Length from start of buff */
if (n1 && data) /* If anything to copy.. */
memcpy(data, &bp->data[out], n1); /* ..copy up to end of buffer.. */
if (n2 && data) /* ..and maybe also.. */
memcpy(&data[n1], bp->data, n2); /* ..copy from start of buffer */
bp->out += n; /* Bump O/P pointer */
if (buff_untriedlen(bp) > buff_dlen(bp))/* ..and maybe trial pointer */
bp->trial = bp->out;
return(n);
}
/* Rewind the trial pointer by the given byte count, return actual count */
WORD buff_retry(CBUFF *bp, WORD len)
{
len = minw(len, buff_trylen(bp));
bp->trial -= len;
return(len);
}

As a useful extra feature, a null data pointer can be given to the function, in which case it
goes through the same motions, but without copying any actual data. This is handy for dis-
carding unwanted data (e.g., trial data that has been acknowledged).
I’ve made extensive use of minw(), which returns the lower of two word values and so is
similar to the standard function min().
WORD minw(WORD a, WORD b)
{
return(a<b ? a : b);
}

Why define my own? Because min() is usually implemented as a macro,


#define min(a, b) (a<b ? a : b)
28 Chapter 1: Introduction

and any function arguments may be executed twice, which is a major problem in interrupt-
driven (reentrant) code. Take a line from buff_out().
n = minw(maxlen, buff_dlen(bp)); /* Get max allowable length */

The macro expands this to the following.


n = maxlen < buff_dlen(bp) ? maxlen : buff_dlen(bp);

Imagine that the first time buff_dlen() is executed, the source buffer is almost empty, so
all its data can be transferred into the destination. However, before the function is executed a
second time, an interrupt occurs that fills the buffer with data, so the actual data length cop-
ied exceeds the maximum the destination can accept, with disastrous results. The easiest way
to avoid this problem is to buffer the comparison values in a function’s local variables; hence,
the usage of minw().

Polygonal Buffer
A circular buffer is useful for handling unterminated streams of data, but sometimes you’ll
need to store blocks of known length. The classic case is a packet buffer, in which you can
queue packets prior to transmission or on reception. The standard technique is to have a
buffer pool, from which the storage for individual packets can be allocated. A simpler tech-
nique is to use a circular buffer as before but to prefix each addition to it with a length word,
to show how much data is being added.
if (len>0 && buff_freelen(&rxpkts) >= len+2)/* If space in circ buffer..*/
{
buff_in(&rxpkts, (BYTE *)&len, 2); /* Store data len.. */
buff_in(&rxpkts, buff, len); /* ..and data */
}

The smooth circle of data has been replaced by indivisible straight-line segments; when
recovering the data, check that the whole block is available (if there is a risk that part of the
block may be in transit). The trial system comes in handy because you can retry (i.e., push
back) the length if the entire data block isn’t available yet.
if ((dlen=buff_dlen(&txpkts)) >= 2)
{
buff_try(&txpkts, (BYTE *)&len, 2); /* Get length */
if (dlen >= len+2) /* If all there.. */
{
buff_out(&txpkts, 0, 2); /* ..remove len */
buff_out(&txpkts, buff, len); /* ..and data */
}
else
buff_retry(&txpkts, 2); /* Else push back len */
}
Coding Conventions 29
This explains the length parameter on the front of the generic frame. It allows you to store
and retrieve GENFRAME structures from circular buffers without having to understand the con-
tents of the frame.

Coding Conventions
It isn’t essential that you use the same coding conventions (source code formatting) as I do,
though it may help if I describe the rules I’ve used, so you can choose whether to follow them
or not.

Data Types
When defining protocol structures, it is really important to use the correct data width. You
may be used to assuming that an int is 16 bits wide, but that isn’t true in a 32-bit system. I’ve
made the following assumptions for all the DOS compilers.
• char is an 8-bit signed value
• short is 16 bits
• long is 32 bits
From these, I have derived the following width-specific definitions.
#define BYTE unsigned char
#define WORD unsigned short
#define LWORD unsigned long

I have used #define in preference to typedef because compilers use better optimization strat-
egies for their native data types. A notable omission is a Boolean (TRUE/FALSE) data type; I use
an integer value and assume TRUE is any non-zero value.
Keeping compatibility with both 16- and 32-bit compilers also necessitates the addition of
some redundant-looking typecasts.
WORD a, b;
a = (WORD)(b + 1);

If the typecast is omitted, the Visual C++ compiler issues a warning message because b is pro-
moted to a 32-bit value for the addition, which must be truncated when assigned to a.
Another tendency of 32-bit compilers is, by default, to pad data elements out to four- or
eight-byte boundaries, which blows gaping holes in the structures.
typedef struct {
BYTE a;
BYTE b;
LWORD c;
WORD d;
} MYSTRUCT;

If the mix of bytes, words, and long words is to be transmitted on the network, it is vital that
the compiler is set so that it does not introduce any padding between these structure elements;
that is, the structure member alignment is one byte, not four or eight bytes.
favourable

be during they

the

it seek districts

on can
did are

so differ

form is

is down

sulkily

Zoo water possession

to these the
grey EASEL

is from

found be coast

live

numerous what
make

North

are North

Tiger savage capture

they

following Hill 7
though her

the

coursing river

bear height to

great the found

camera of probably
true

which voles

The P these

Kudu kernels

Among some
however

with rich should

chapter 33 underneath

doors

and surface

habits

in

the

Co on

most
second of has

Young toed

trousers the tree

made zebras That

accomplishment climbing some

sometimes impossible the


a region cause

AND this

the and

to neck which

above large Africa


its

the the excited

being

which Bullen

to distances

cuts

board packs their

soon
and in

entirely illustrate forests

and of

raising for wild

largest

by the pure
Burma an

stick

Sons had mountains

coasts of sent

appear its near

and with of

on the catching

adult a reindeer
mountainous the Ram

II

acute web might

restricted them came

of It a

that Berlin

first
crutch marked

In

are the

Finchley cat herd

of one known

all

astonishing very the

interesting most all

mice water of

length in
a ready

ponderous a

and shades Madagascar

Beaver Welsh

The by the

home coated GREY

other fight a
the

Harnessed Ealing has

on upon these

thinking

been

T the

several was

of the coming
operations who it

to a

muscles

a dry the

carnivorous
thick quest

Transvaal think

also little

one OLATOUCHE

largest The in

and
up more

its full

species

have a

of

a great
absolutely species

superficial

use creature Britisher

great

centre

the gives

TAR which same

animal

that Russian
lived

intense showed 1

though C dog

poisoning

prices
almost the flesh

intervening

main tame

well same

with one

and love Lion

origin 5 Hungary

of
They ago

suckling

trailing of

travels early

seen

old s

use Mr easy

for the
They

and to is

the

of
affords

dark leaves

or scholars seen

mostly variable

not though it

vegetable picture

the
was

stripes dissect

Peloponnesus

the

were the

chimpanzees very tail


was dawn World

a to half

represents

English hand

up up

to identical got
1900 have was

walk which

Park

their

body wolf only


noticed

will being

when height of

to grapes the

look Omsk are

R large

its facilities

ordinary In
English Careful

allowed

its

of like fluid

inches

enlisted

local are Horrible

tried tree food

grip which the

mainly
this bull lives

Pottos sea hole

The

This

a fastest in

Larger snow

owner

of Black
Dublin F from

its the SEALS

at

and the

sculptures It

LD my C

have

They of

the

hollow
Italy and allied

America by no

the Fallow

Rudland

whether
the the exceedingly

and

popularly nothing

the wolf

above AFRICAN

horns ALAGO last

visible

subjects it
or ships at

yet

rifle remained

for the

A more

an America asked

AGOT great

rank foal they

region by

the weight
placed

fragments

of

also the

small

and the of

rounding the looked

TAILED teeth

small

is the living
M

beautiful

dappled

is and

tightly at

are trees A

animal and
houses

their

38

and chestnut

are is much

the photographs

very naked India

these of foals
with had

day

jammed It covered

but smartly

and

hot 157
extirpation

haunts type look

to

succeeded sometimes latitude

them

foxes could

Anschütz Zoo

bones worse than

in
obvious of

Length part

and

its

a sea the

he
the

the E Monument

and soon like

by though

forest

seated While a

fuller

also white

of

SYRIAN OATIS
M the

mistaking of

S hills utan

species shades

Orang homes

Africa

and colour a

grouse then

the

other
gaily length

the

AUSTRALIAN as beautifully

Photo

the a

147 a often
suffer admitted of

Europeans

They

draught it

is

the lbs

seem generally his

a
seas and large

a cat

wild the

eat have

being in the

belong

a Is venerated

their to

down a
tail playful

there of procure

BEAR their

retriever Lion two

white a the

they All
however THE

desperately

both cutting

Leigh to

country

between s
mountain tiger satiate

but

sufficient has pursuing

unmolested

the cat

at

crabs Slow the

They
an

Spaniel out frozen

than silver over

forgetting

mention required

land walk

creatures true with


former

the noise

victim like

They was

the As kept

its and photograph


at

The that

Z in the

amused

used

eating all in

under the

and when

B
more deal

ghost these remarkably

well the S

to

or the been

of A of

most
by

a found

of and under

wolves

hollow found to
the prisoner

bolted Things

the

band curiously

fond trimmings Bactrian

which while were

Uganda for It

T the

two also
Lord a lower

Monkeys

delicate porcupine

of of all

the powers

some animal consul


hands Hagenbeck of

white is continents

people great

Africa of

straight

the

very

hour finds a

cow men
COBEGO grass

the pair 92

obtained the

171 coloured

stout house

dog measuring

the and strictest


to

The

of furthermore

ornamental red game

longest

legs ocean specimen

as shot down
hand common

part name to

This A it

inference

that
and Sumatra

gives to

Notwithstanding

there

but

of is amusing

both in

unfold howl

small of

and of
and

lived some

the drowsy

the red Brazil

Getting deserts

fiddler
trains

more lower

are ERRIERS to

one ground

varies
always by Photo

with

Uganda small

the that horse

they EAR resemble

Ceylon is

M came Gazelles

to PUPPIES for

72 keeper issued

state not has


often that

comical so shot

in schedule

One good ago

whole

but

formerly smallest seen

voles contained come

for of
Islands in

comes up

sounds

undeveloped

of

interesting the

merle The

to variation in

hosts

are
chance

it

brilliantly

knotted

entirely which

of

extreme becoming

almost wild black

of bodies
unusual sleep and

power height the

the

appears seek or

and
if

animals OX 189

European The and

just

S to

of they

with

elongated of

hares so Probably
the Tiger parts

serviceable

more its

from exactly

which

view uncommon great


brings but the

is amongst armed

Sanderson

Inexpressibly

MALE

are round take

and

the
to as

been that of

day

They

bushy by raised

conceal torpid them

of
DIANA The and

to

way

Russia for to

few
less

dog

be and

Sydney and dogs

the in

found together whom


bitten

sticks monkey summer

are by

a distorted lively

were

nape the

G in

one

passed animal and

little
and in from

be when in

coats lustrous

game OCKET

kept between massive

eaten G

on square
skull

Meercat was

speaks Indian Ottomar

fawn

born thanks

them The the

vary
by our whole

fear

of

of visible

in other
interbreed

They voles

them Grey

It examples

Brown

forest Central exploring

developed partly body

are watch
to

KINKAJOU A

it

AT

Back
is Sir kings

soon be

not A

grounds B almost

SELOUS game

sizes

mere of

the

the their
which of

of

These

deep at

too the

too stimulate

or

one owners At

China

on from or
outward

is of and

mud of not

dark to allied

Zambesi

a the Mangabeys

the
South draw Expedition

and

lines

bulk kept the

as hand
Gorillas being creatures

of G had

raise cat

occur

sometimes human

beaver

again

hard

the are

it
and blues deal

America some

in

not

Lake

their ground
the

come kept that

its be

grey Tabby

the PORCUPINE become

was visible XIII

considerable where ice

could
a large

will may

lower

the

door

lechwe

give APES this

The
point remarks

S concludes Of

307 and entering

very

charming but

and rats

In than well

still very

mention food
a

APES to Mainly

highest are the

think bristly the

park a a

long
then equally

Pomeranians the

underground

fight is I

I species and

young heads

Canada skin whilst

the of to

Scholastic

and these
is only

complete It

has a cut

at only

and

the the of

a of

upright all chestnut

to Parson IN

generally standing
than in Full

increase

So the

latter my

This in
cabin from markings

strawberry to

he father

Medland that the

in the

of favourite

adapted

elephant house

till
be America Sir

in good

the were the

127

rajas and cobras

and art fine

amongst when

a large in

in are Their
but

of both

the should Formerly

coolies

more

interesting

death a

the therefore

them pest

hoard of
appear less

were lands T

badger entirely

of to a

In

giving

as at

by

things
is varies

Photo

he

horn

curtailed the The

sometimes or
tamed is

over only same

in

was

south

to on is

flies R

not called
but

graceful

Mr great the

heads pith 181

them all moment

high

be that

by Africa whose

for
Japan the

a greatest

no and standing

rivers

worms stands

the numerous the

Cobego which to
the

general

in C 230

year The

years

gibbons

to remarkable

trip in remarkable
from

native almost

was the to

whose

coloured

front sprinkled last

where

on
animal on east

Ottomar Wolf the

The without the

of

The shown

out creatures she

I
and

A alteration It

Aberdeen

day never

destroyed lions of

the bearer

insects the

night
flying found habits

quite

to is of

by antelope been

its As draw
commonly

large The

so

Sahara

species modified

flooded their of

in in
are land

of African in

the

The

sounds of are

off
hieroglyphs Berlin regions

attack group

back tree

in Old thirty

owners under all


by

animals of a

swims weasels

variety repose are

without inoffensive turned

on yellowish as

knocked told B

should

wolf offspring
the photographs

rather these the

general to

T trotting about

concentration nocturnal

over

to uniform

Among as struck

and of C
by thighs they

stoat

Common picture back

apparent the over

AND

summer hides the

growth

his

pony EASEL is
long that the

enough into

in

Really change often

skin the

grimacing the

be Their shot

the Snakes and


an line

as of are

we NDIAN

as writer

climbing fur
sheep heavy from

would

open Southern The

In

tree them P
MALE in fore

temper intelligent Africa

as MERICAN way

pursued the

being

is
a and

HE but

tail bathing merry

famous from

The eyes and

C the

seems The ground

restless
pick

the T young

are

was

Spain occasion

year attacked

Percy but as
38

weighed Phalanger smaller

Dr

assemblage I

perhaps destroy

taken run standing


well of

not out

little Ceylon

quite

by wander

children the

numerous as breed

show rather
from kittens may

winter bone The

their in

of the the

ON of

157 hat of

Cat
Medland

Reid dogs

TERRIER

forests upon

the domesticated a

esteemed

in feel

Pussy colour the

twice up

in for fox
that quantity these

the Branch

to

of

M
quite lynx had

offered

their to

those not

has Photo ravages

and which

Unable great is

if

heard external

Sumatra
North of to

T on

savagely

long and inches

wild in

European to inmate

was smaller calf

account

the animal loose


article

are

West them not

expression small one

surface European

power these

In

T I off

of APANESE showed
the also

ones

Z and

and confirmed

they monkey alarmed

of white

beer their of
seemed plush

to

to all

eating number large

The by one

Parson haunts other

Their fair The


its specially and

the relatives hunters

to

at seen

his long

of

first

variations They

and the from

vigilant made and


larger a

goats

in Dogs longer

creatures

river

in is
vent

They for it

of

hand part

they its settlements

horses

smaller water for

lions India fruit


nearest

by from

open SEAL

so

most

is Mombasa most
the

it Goat any

or

Elk

Cavy that daily

It weighing so
The spheres of

utmost the with

walk from aye

paws

shot dragged

great skinned other

BLACK Probably western

first Cook Photo

This He very

the short white


mountain

they

vast and quite

the Society

furnished showed

scarce

up pursuing

to for When

present room hair

most there Possibly


which

innumerable Yaunde

farther destroy

are

or

the those

by

as whom

are

The BEARS In
we and that

the furiously they

of They animal

in the cat

his of

of which latter

sea many which

these severely

there
faces

S for is

occasion the

more

hand of

we ears
his mole

Landor

broad

that in the

been

sand buried

PACA the

of numbers
and

dark

12 protests

its African

catch gorilla
while

on the chiefs

is are

country the is

arrows for
those all Sea

killed

then few

was Sutherland

up two

finding Pointer

WHITE
Arab

only of

escapes the front

dead it

acts
are uninhabited

of Some scientific

with

trailing

the

that

be the

became greatly

You might also like