



                        AmiTCP/IP



                     System  Manual


                             Revision: 2.4



                          amitcp-group@hut.fi



Tomi Ollila      Pekka Pessi      Markus Peuhkuri      Jarno  Rajahalme



                           August 13, 1993







Foreword



What  Is  AmiTCP/IP


The Programming Project is a software engineering course here at Helsinki
University of Technology.  A group of 3---4 students designs, implements
and tests a complete working software system during this course.
   Our purpose was to provide a free TCP/IP implementation for all Amiga
users.  Lack of a standard networking interface was anirritating
shortcoming of the Amiga systems.
   AmiTCP/IPis a protocol stack implementing basic Internet protocols on
top of any SANA-II network device driver(for Ethernet, SLIP, etc.).  The
protocol stack offers the standard Berkeley Socket application program
interface (API) to the TCP/IP protocolsimplemented as an Amiga shared
library.
   Using AmiTCP/IP and appropriate client program you can connect to any
services available on your TCP/IP network.



How  Is  This  Achieved


At first we planned to write the whole protocol stack from scratch.
After examining standards about TCP/IP and bibliography about its
implementations we become aware of the possibility of using the BSD NET/2
code as a base of our work.  We discussed about the idea and found good
reasons why the BSD code should be used.  Eventually wedecided to take
that path with the project.
   AmiTCP/IPis built around BSD NET/2 networking code.  Because the
networking part of the BSD UNIX kernel is rather isolated, only a few
kernel routines had to be rewritten to suit the architecture of the
AmiTCP/IP.
   SANA-II and shared library interfaces were added to the bottom and top
of the modified NET/2 code, respectively.



Why Is the BSD Code Used


Here are some of the pros of the decision:


   fflWe don't need to reimplement the most complex part (and all the bugs)
    of the system.



                                       i





   fflWe noticed that the BSD kernel support for the networking part is
    easy enough to implement using powerful Amiga features.

   fflWhen improvements are done to the NET/2 code, we can improve
    AmiTCP/IP by simply replacing the old code with the changed one.

   fflWe are offering the socket application interface.  It is the most
    used interface in networking programs with TCP/IP. Using the NET/2
    code makes it easy to implement the BSD socket related function call
    interface as our API.

   fflWe can easily port crucial network utilities from the BSD.



About SANA-II

Bottom level interface to the SANA-II device drivers was an obvious
choice.  SANA-II is the Amiga standard interface for network devices, and
most manufacturers are shipping SANA-IIcompatible device drivers for
their hardware.  There are also some freely distributable SANA-II drivers
e.g.  for the standard serial interface.
   Althoughthere may be few problems with different network types the
AmiTCP/IP should be able to use all SANA-II device drivers which support
IP.



Release 2.0

This release of AmiTCP/IP includes onlythe protocol stack (AmiTCP),
test programs, basic network utilities and example client and servers.
The distribution still lacks most basicclient and server programs.
   The second release of the AmiTCP/IP contains some improvements and bug
fixes over the first release.  It is incompatible withprevious version
in binary level, however.  Old applications and the newlibrary DO NOT
work together.  If you have an application compiled with previous version
of AmiTCP/IP, it MUST be recompiled.  We hope that thisis the only
downward incompatible release.
   The AmiTCP/IP Group requests all users of the AmiTCP/IP to return any
new applications or improved versions tothe AmiTCP/IP Group,
<amitcp-group@hut.fi>, and grant it theright to redistribute them.



                                      ii





Acknowledgments


We would like to thank

   fflComputer Systems Research Group from University of California,
    Berkeley, for developing BSD Unix system.

   fflCarnegie Mellon University for Mach bsdss port of BSD Net/2.

   fflAntti Louko <alo@hut.fi>, our project supervisor, from the Computing
    Centre of the Helsinki University of Technology.

   fflJukka Partanen <jtp@cs.hut.fi> for providing the GNU CC
    cross-compiling environment for the Amiga in the HP 9000/700
    workstations.

   fflTimo Rossi <trossi@jyu.fi> for providing the SANA-II drivers for
    Western Digital Ethernet cards used in testing.

   Further on, Jarno and Markus would like to thank their wives Maarit and
Katri for forgiving those late nights (or early mornings) that we spent
with this project.



                                      iii





   AmiTCP/IPcontains material derived from BSD net/2 release.  The
following acknowledgement should be included in all AmiTCP/IP
distributions:


   Copyright cfl1982, 1986, 1988, 1990 Regents of the University of
California.  All rights reserved.
   Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:


 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

 3. All advertising materials mentioning features or use of this software
    must display the following acknowledgment:  This product includes
    software developed by the University of California, Berkeley and its
    contributors.

 4. Neither the name of the University nor the names of its contributors
    may be used to endorse or promote products derived from this software
    without specific prior written permission.


   THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.



                                      iv





   Some codeof the AmiTCP/IP originates from the BSDSS 4 by CMU, which
is hereby acknowledged:


Mach Operating System.
Copyright cfl1992 Carnegie Mellon University.
All Rights Reserved.


Permission to use, copy, modify and distribute this software and its
documentation is hereby granted, provided that both the copyright notice
and this permission notice appear in allcopies of the software,
derivative works or modified versions, and any portions thereof, and that
both notices appear in supporting documentation.


CARNEGIE MELLON ALLOWS FREE USE OF THISSOFTWARE IN ITS "AS IS"
CONDITION. CARNEGIE MELLON DISCLAIMS ANYLIABILITY OF ANY KIND FOR ANY
DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.


Carnegie Mellon requests users of this software to return to


Software Distribution Coordinator
School of Computer Science
Carnegie Mellon University
Pittsburgh PA 15213-3890


or Software.Distribution@CS.CMU.EDU


any improvements or extensions that theymake and grant Carnegie Mellon
the rights to redistribute these changes.



                                       v





vi





About  This  Manual


How This Manual Is Organized

We have tried to organize this manual sothat you are not forced to read
material that you are not interested in.  In order to achieve this we
have divided the text into following chapters:


 1. User's Manual gives you basic information about using the AmiTCP/IP
    system.  Descriptions about our debugging tools qwriter and
    agnet.device is also included here.


 2. Interfaces describes briefly all external interfaces of the
    AmiTCP/IP.


 3. Programmer's Manual gives you the needed information to use
    AmiTCP/IP to make your own network-aware programs.


 4. Internal Description gives you information about the internal
    structure of the AmiTCP/IP-system.  This is meant for all of you who
    are interested in the internal design of the AmiTCP/IP.


 5. Implementation Notes is written for those of you who are going to
    maintain AmiTCP/IP or plan to develop it further.


   There arealso two appendices, the user and programmer reference
guides.  These appendices are in the AutoDoc format andthey are also
available in machine readable form.
   If you have trouble understanding the jargon1  or TLAs1  refer to the
glossary at the end of this manual.



Typographical Conventions

To help you to understand the text in this manual, following typefaces
and punctuation are used:


     Roman   is the basic typeface used throughout the text.


   Slanted   is used in text which we want youto take special attention
             on.


   Italics   is used to introduce new terms and concepts which will be
             explained shortly.  Italics is also used to refer to the
             names of the publications and tothe sections of this manual.


Typed Text   is used for literal program codeand items specific to the
             implementation, such as functionnames, identifiers and C
             language keywords.


      Bold   text is used to refer to specificfiles and command names
             used by AmiTCP/IP.
________________________________
   1See glossary.



                                      vii





Syntax Conventions

There are few syntactic conventions usedin this manual:


       [:::] Square brackets are used for bibliographical references, list
             of which can be found from the end of this manual.

 hargumenti  User supplied required argumentsare printed between angle
             brackets.

[argument]   User supplied optional argumentsare printed between square
             brackets.

function()   C function names are followed bya pair of parenthesis.  The
             preprocessor macros---as opposedto the genuine
             functions---are in upper case.



                                     viii





GNU  GENERAL  PUBLIC  LICENSE


                             Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.  675 Mass Ave,
Cambridge, MA 02139, USA

   Everyoneis permitted to copy and distribute verbatim copies of this
license document, but changing it is notallowed.



Preamble


The licenses for most software are designed to take away your freedom to
share and change it.  By contrast, the GNU General Public License is
intended to guarantee your freedom to share and change free software---to
make sure the software is free for all its users.   This General Public
License applies to most of the Free Software Foundation's software and to
any other program whose authors commit to using it.   (Some other Free
Software Foundation software is coveredby the GNU Library General Public
License instead.)  You can apply it to your programs, too.

   When we speak of free software, we are referring to freedom, not price.
Our General Public Licenses are designedto make sure that you have the
freedom to distribute copies of free software (and charge for this
service if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.

   To protect your rights, we need to make restrictions that forbid anyone
to deny you these rights or to ask you to surrender the rights.  These
restrictions translate to certain responsibilities for you if you
distribute copies of the software, or ifyou modify it.

   For example, if you distribute copies of such a program, whether gratis
or for a fee, you must give the recipients all the rights that you have.
You must make sure that they, too, receive or can get the source code.
And you must show them these terms so they know their rights.

   We protect your rights with two steps:  (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

   Also, foreach author's protection and ours, we want to make certain
that everyone understands that there isno warranty for this free
software.  If the software is modified by someone elseand passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

   Finally,any free program is threatened constantly by software patents.
We wish to avoid the danger that redistributors of a free program will
individually obtain patent licenses, ineffect making the program
proprietary.  To prevent this, we have made it clear that any patent must
be licensed for everyone's free use or not licensed at all.

   The precise terms and conditions for copying, distribution and
modification follow.



                                      ix





TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

 1. This License applies to any program or other work which contains a
    notice placed by the copyright holder saying it may be distributed
    under the terms of this General Public License.  The ``Program'',
    below, refers to any such program or work, and a ``work based on the
    Program'' means either the Program or any derivative work under
    copyright law:  that is to say, a work containing the Program or a
    portion of it, either verbatim or with modifications and/or
    translated into another language.  (Hereinafter, translation is
    included without limitation in the term ``modification''.)  Each
    licensee is addressed as ``you''.

    Activities other than copying, distribution and modification are not
    covered by this License; they are outside its scope.  The act of
    running the Program is not restricted, and the output from the
    Program is covered only if its contents constitute a work based on
    the Program (independent of having been made by running the Program).
    Whether that is true depends on what the Program does.

 2. You may copy and distribute verbatim copies of the Program's source
    code as you receive it, in any medium, provided that you
    conspicuously and appropriately publish on each copy an appropriate
    copyright notice and disclaimer of warranty; keep intact all the
    notices that refer to this License and to the absence of any
    warranty; and give any other recipients of the Program a copy of this
    License along with the Program.

    You may charge a fee for the physical act of transferring a copy, and
    you may at your option offer warranty protection in exchange for a
    fee.

 3. You may modify your copy or copies of the Program or any portion of
    it, thus forming a work based on the Program, and copy and distribute
    such modifications or work under the terms of Section 1 above,
    provided that you also meet all of these conditions:

    (a) You must cause the modified files to carry prominent notices
        stating that you changed the files and the date of anychange.

    (b) You must cause any work that you distribute or publish,that in
        whole or in part contains or is derived from the Program or any
        part thereof, to be licensed as a whole at no charge toall third
        parties under the terms of this License.

    (c) if the modified program normally reads commands interactively
        when run, you must cause it, when started running for such
        interactive use in the most ordinary way, to print or display an
        announcement including an appropriate copyright noticeand a
        notice that there is no warranty (or else, saying thatyou
        provide a warranty) and that users may redistribute theprogram
        under these conditions, and telling the user how to view a copy
        of this License.  (Exception:  if the Program itself is
        interactive but does not normally print such an announcement,
        your work based on the Program is not required to printan
        announcement.)



                                       x





   These requirements apply to the modified work as a whole.  If
   identifiable sections of that work are not derived from the Program,
   and can be reasonably considered independent and separate works in
   themselves, then this License, and its terms, do not apply to those
   sections when you distribute them as separate works.  But when you
   distribute the same sections as part of a whole which is a work based
   on the Program, the distribution of the whole must be on the terms of
   this License, whose permissions for other licensees extend to the
   entire whole, and thus to each and every part regardless of who wrote
   it.

   Thus, it is not the intent of this section to claim rights or contest
   your rights to work written entirely by you; rather, the intent is to
   exercise the right to control the distribution of derivative or
   collective works based on the Program.

   In addition, mere aggregation of another work not based on the
   Program with the Program (or with a work based on the Program) on a
   volume of a storage or distribution medium does not bring the other
   work under the scope of this License.


4. You may copy and distribute the Program (or a work based on it, under
   Section 2) in object code or executable form under the terms of
   Sections 1 and 2 above provided that you also do one of the
   following:


   (a) Accompany it with the complete corresponding machine-readable
       source code, which must be distributed under the termsof
       Sections 1 and 2 above on a medium customarily used forsoftware
       interchange; or,

   (b) Accompany it with a written offer, valid for at least three
       years, to give any third party, for a charge no more than your
       cost of physically performing source distribution, a complete
       machine-readable copy of the corresponding source code,to be
       distributed under the terms of Sections 1 and 2 above on a medium
       customarily used for software interchange; or,

   (c) Accompany it with the information you received as to the offer to
       distribute corresponding source code.  (This alternative is
       allowed only for noncommercial distribution and only ifyou
       received the program in object code or executable formwith such
       an offer, in accord with Subsection b above.)


   The source code for a work means the preferred form of the work for
   making modifications to it.  For an executable work, complete source
   code means all the source code for all modules it contains, plus any
   associated interface definition files, plus the scripts used to
   control compilation and installation of the executable.  However, as
   a special exception, the source code distributed need not include
   anything that is normally distributed (in either source or binary
   form) with the major components (compiler, kernel, and so on) of the
   operating system on which the executable runs, unless that component
   itself accompanies the executable.



                                     xi





   If distribution of executable or object code is made by offering
   access to copy from a designated place, then offering equivalent
   access to copy the source code from the same place counts as
   distribution of the source code, even though third parties are not
   compelled to copy the source along with the object code.

5. You may not copy, modify, sublicense, or distribute the Program
   except as expressly provided under this License.  Any attempt
   otherwise to copy, modify, sublicense or distribute the Program is
   void, and will automatically terminate your rights under this
   License.  However, parties who have received copies, or rights, from
   you under this License will not have their licenses terminated so
   long as such parties remain in full compliance.

6. You are not required to accept this License, since you have not
   signed it.  However, nothing else grants you permission to modify or
   distribute the Program or its derivative works.  These actions are
   prohibited by law if you do not accept this License.  Therefore, by
   modifying or distributing the Program (or any work based on the
   Program), you indicate your acceptance of this License to do so, and
   all its terms and conditions for copying, distributing or modifying
   the Program or works based on it.

7. Each time you redistribute the Program (or any work based on the
   Program), the recipient automatically receives a license from the
   original licensor to copy, distribute or modify the Program subject
   to these terms and conditions.  You may not impose any further
   restrictions on the recipients' exercise of the rights granted
   herein.  You are not responsible for enforcing compliance by third
   parties to this License.

8. If, as a consequence of a court judgment or allegation of patent
   infringement or for any other reason (not limited to patent issues),
   conditions are imposed on you (whether by court order, agreement or
   otherwise) that contradict the conditions of this License, they do
   not excuse you from the conditions of this License.  If you cannot
   distribute so as to satisfy simultaneously your obligations under
   this License and any other pertinent obligations, then as a
   consequence you may not distribute the Program at all.  For example,
   if a patent license would not permit royalty-free redistribution of
   the Program by all those who receive copies directly or indirectly
   through you, then the only way you could satisfy both it and this License
   would be to refrain entirely from distribution of the Program.

   If any portion of this section is held invalid or unenforceable under
   any particular circumstance, the balance of the section is intended
   to apply and the section as a whole is intended to apply in other
   circumstances.

   It is not the purpose of this section to induce you to infringe any
   patents or other property right claims or to contest validity of any
   such claims; this section has the sole purpose of protecting the
   integrity of the free software distribution system, which is
   implemented by public license practices.  Many people have made



                                     xii





    generous contributions to the wide range of software distributed
    through that system in reliance on consistent application of that
    system; it is up to the author/donor to decide if he or she is
    willing to distribute software through any other system and a
    licensee cannot impose that choice.

    This section is intended to make thoroughly clear what is believed to
    be a consequence of the rest of this License.

 9. If the distribution and/or use of the Program is restricted in
    certain countries either by patents or by copyrighted interfaces, the
    original copyright holder who places the Program under this License
    may add an explicit geographical distribution limitation excluding
    those countries, so that distribution is permitted only in or among
    countries not thus excluded.  In such case, this License incorporates
    the limitation as if written in the body of this License.

10. The Free Software Foundation may publish revised and/or new versions
    of the General Public License from time to time.  Such new versions
    will be similar in spirit to the present version, but may differ in
    detail to address new problems or concerns.

    Each version is given a distinguishing version number.  If the
    Program specifies a version number of this License which applies to
    it and ``any later version'', you have the option of following the
    terms and conditions either of that version or of any later version
    published by the Free Software Foundation.  If the Program does not
    specify a version number of this License, you may choose any version
    ever published by the Free Software Foundation.

11. If you wish to incorporate parts of the Program into other free
    programs whose distribution conditions are different, write to the
    author to ask for permission.  For software which is copyrighted by
    the Free Software Foundation, write to the Free Software Foundation;
    we sometimes make exceptions for this.  Our decision will be guided
    by the two goals of preserving the free status of all derivatives of
    our free software and of promoting the sharing and reuse of software
    generally.



                               NO  WARRANTY

12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
    FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
    WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
    PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND,
    EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
    PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
    THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
    REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR



                                     xiii





    DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
    DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
    (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
    INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE
    OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
    HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
    DAMAGES.



END OF TERMS AND CONDITIONS



                                      xiv





Contents



1  User's Manual                                                             1
   1.1  Installation : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : :   1
        1.1.1  Using the SLIP Drivers: : : : : : : : : : : : : : : : : : : : : *
 *: : : :   2
               Common Problems with the SLIP Driver And AmiTCP/IP : : : :   2
   1.2  Configuration : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : :    3
        1.2.1  Options : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : :   4
        1.2.2  Network Database : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : :   4
   1.3  Internet Addressing : : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :   4
        1.3.1  Internet Dot Notation : : : : : : : : : : : : : : : : : : : : : *
 *: : : :   5
        1.3.2  Nets and Routing : : : : : : : : : : : : : : : : : : : : : : : :*
 * : :: : :    5
        1.3.3  Subnets : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : :   6
        1.3.4  Broadcast Addresses : : : : : : : : : : : : : :: : : : : : : : :*
 * : : : :   6
   1.4  Utilities : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : :   7
        1.4.1  arp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : :   7
        1.4.2  ifconfig : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : :   7
        1.4.3  letnet: : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : :   8
        1.4.4  netstat : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : :   8
        1.4.5  NapsaTerm  : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :   8
        1.4.6  offline : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : :   9
        1.4.7  online: : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : :   9
        1.4.8  route  : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : :   9
   1.5  Errors and Logging  : : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :   9
   1.6  Troubleshooting : : : :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  10
   1.7  Testing Utilities : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : :  10
        1.7.1  Agnet  : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : :  10
               ARexx Port for agnet.device : : : : : : : :: : : : : : : : : : :*
 * : :  11
        1.7.2  Qwriter : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : :  13
               Command Line Options : : : : : : : : : : : : : : : : : : : : : :*
 * : :: :  13


2  Interfaces                                                               15
   2.1  AmiTCP/IP Processes : : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  15
   2.2  Application Interface : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : :  16
   2.3  SANA-II Interface : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : :  16
        2.3.1  Interface ioctls : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : :  17
   2.4  Configuration Files : : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  17
   2.5  ARexx Interface : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  17
        2.5.1  Commands : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : :  18
        2.5.2  Variables  : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  19
               Boolean variables  : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : :  23



                                      xv





               CONNECTIONS output format : : : : : : : : : : : : : : : : : : : *
 *: : :  24
               ICMPHIST output format: : : : : : : : : : : : : : : : : : : : : *
 *: : : :  24


3  Programmer's Manual                                                     27
   3.1  Socket Concepts : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  27
        3.1.1  Socket Types : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : ::  27
        3.1.2  Using The Socket Library : : : : : : : : : : : : : : : : : : : :*
 * : : :  28
        3.1.3  Compiling and Linking The Applications: : : : : : : : : : : : : *
 * 30
               The NETINCLUDE Header Files : : : : : : : :: : : : : : : : : : :*
 * : :  30
               Linking With net.lib : : : : : : : : : : : : : : : : : : : : : :*
 * : :: :  32
        3.1.4  Socket Creation : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : :  32
        3.1.5  Binding Local Names : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : :  33
        3.1.6  Connection Establishment : : : : : : : : : : : : : : : : : : : :*
 * : : :  34
        3.1.7  Data Transfer  : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  36
        3.1.8  Discarding Sockets: : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : :  36
        3.1.9  Connectionless Sockets: : : : : : : : : : : : : : : : : : : : : *
 *: : : :  37
        3.1.10 Input/Output Multiplexing  :: : : : : : : : : : : : : : : : : : *
 *: : :  38
   3.2  Network Library Routines : : : : : : : : : : : : : : :: : : : : : : : :*
 * : : : :  40
        3.2.1  Host Names : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  40
        3.2.2  Network Names  : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  41
        3.2.3  Protocol Names :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  41
        3.2.4  Service Names  : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  42
        3.2.5  Miscellaneous  :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  42
               Remote Login Client Code : : : : : : : : : : : : : : : : : : : :*
 * : : :  42
   3.3  Client/Server Model : : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  44
        3.3.1  Servers : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : :  45
        3.3.2  Clients : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : :  47
        3.3.3  Connectionless Servers: : : : : : : : : : : : : : : : : : : : : *
 *: : : :  48
               Ruptime Output :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  48
   3.4  Advanced Topics : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  51
        3.4.1  Out Of Band Data : : : : : : : : : : : : : : : : : : : : : : : :*
 * : :: : :  51
        3.4.2  Non-Blocking Sockets : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :  53
        3.4.3  Signal Driven Socket I/O : : : : : : : : : : : : : : : : : : : :*
 * : : :  54
        3.4.4  Selecting Specific Protocols : : : : : : : : : : : : : : : : : :*
 * : :  55
        3.4.5  Address Binding : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : :  55
        3.4.6  Broadcasting And Determining Network Configuration : : : :  58
               AmiTCP/IP specific extensions : : : : : : : : : : : : : : : : : *
 *: :  60
               Extensions to interface ioctls: : : : : : : : : : : : : : : : : *
 *: :  60
        3.4.7  Socket Options :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  61
        3.4.8  Inetd  : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : :  62
   3.5  Deviation From Berkeley Sockets: : : : : : : : : : : : : : : : : : : : *
 *: : :  63
        3.5.1  Opening and Closing the Shared Library: : : : : : : : : : : : : *
 * 63
        3.5.2  Naming Conventions of the API Functions : : :: : : : : : : : :  *
 *63
        3.5.3  errno  : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : :  64
        3.5.4  New Field in the sockaddr Structures : : : : : : : : : : : : : :*
 *  64
        3.5.5  Linger Time : : : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : : :  64
        3.5.6  Transferring Sockets from a Task to Another : :: : : : : : :  64
        3.5.7  Ioctl Differences  : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : :  65
        3.5.8  Signal Handling : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : :  65
        3.5.9  Asynchronous I/O : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : :  66
        3.5.10 Constructing an Event Loop: : : : : : : : : : : : : : : : : : : *
 *: : :  66



                                      xvi





        3.5.11 ''Killing'' the Processes : : : : : : : : : : : : : : : : : : : *
 *: : :  67
        3.5.12 WaitSelect() : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * :: : : : :  67


4  Internal Description                                                    69
   4.1  Source File Structure : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : :  69
        4.1.1  System Include Files : : : : : : : : : : : : : : : : : : : : : :*
 * : :: :  69
        4.1.2  Protocol Independent Network Routines : : : : : : : : : : : : : *
 * 70
        4.1.3  Internet Protocol Modules : : : : : : : : : : : : : : : : : : : *
 *: : :  71
        4.1.4  BSD Kernel Service Modules: : : : : : : : : : : : : : : : : : : *
 *: : :  72
        4.1.5  BSD Socket API: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  73
        4.1.6  Miscellaneous Files : : : : : : : : : : : : : :: : : : : : : : :*
 * : : : :  75
   4.2  AmiTCP/IP Initialization : : : : : : : : : : : : : : : : : : :: : : : :*
 * : : : :  75
        4.2.1  init_all() : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  76
        4.2.2  deinit_all() : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : ::  77
   4.3  The Main Module : : : :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  77
   4.4  Protocol Entities : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : :  78
   4.5  Memory Management : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : :  79
        4.5.1  Mbuf Functions :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  79
   4.6  Concurrency Control : : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  82
   4.7  Network Device Drivers  : : : : :: : : : : : : : : : : : : : : : : : : *
 *: : : : :  83
        4.7.1  SANA-II Soft Network Interface: : : : : : : : : : : : : : : : : *
 *: :  84
        4.7.2  ARP : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : :  87
   4.8  Logging : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : :  88
   4.9  ARexx Interface : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : :  89
   4.10 Application Interface Concepts  : :: : : : : : : : : : : : : : : : : : *
 *: : :  90
        4.10.1 SocketBase -- an Extension of the Task Structure  : : : : :  90
        4.10.2 The System Call Semaphore and Task Priorities : : : : : : :  90
   4.11 Configuration Variables : : : : :: : : : : : : : : : : : : : : : : : : *
 *: : : : :  91
   4.12 Network Database : : : : : : : : : : : : : : : : : : : : :: : : : : : :*
 * : : : : : :  92


5  Implementation Notes                                                    93
   5.1  Time outs : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : ::   93
   5.2  Memory Management : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : :  95
        5.2.1  Mbufs  : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : :  95
        5.2.2  malloc() & free() : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : :  95
   5.3  Concurrency Control : : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : :  96
        5.3.1  Processor Priority Levels : : : : : : : : : : : : : : : : : : : *
 *: : :  96
        5.3.2  Sleeping Facilities : : : : : : : : : : : : : :: : : : : : : : :*
 * : : : :  97
   5.4  Socket Library Creation Procedure : : : : : : : : : : : : : : : : : : :*
 * : :  99
        5.4.1  Master Library Base : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : :  99
        5.4.2  Application Library Bases : : : : : : : : : : : : : : : : : : : *
 *: : :  99
   5.5  The SocketBase Structure : : : : : : : : : : : : : : :: : : : : : : : :*
 * : : : : 100
   5.6  The Application Program Interface : : : : : : : : : : : : : : : : : : :*
 * : : 102
        5.6.1  How API Functions Are Ported : : : : : : : : : : : : : : : : : :*
 * : :102
        5.6.2  API Functions Which Needed More Modifications : : : : : : : 103
   5.7  Changes in Functions Below API Level : : : : : : : : : : :: : : : : : :*
 * : 103
        5.7.1  Other Changes  : : : : :: : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 103
   5.8  Agnet.device : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : 104
        5.8.1  IO Commands : : : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : : : 104
        5.8.2  Initialization Procedure : : : : : : : : : : : : : : : : : : : :*
 * : : : 106
        5.8.3  The Device Interface Functions: : : : : : : : : : : : : : : : : *
 *: : 107



                                     xvii





               Opening an Unit : : : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : : : 107
               Closing an Unit : : : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : : : 107
               Initiating an IO Request : : : : : : : : : : : : : : : : : : : :*
 * : : :108
               Aborting an IO Request: : : : : : : : : : : : : : : : : : : : : *
 *: : : : 108
               Expunging the Device : : : : : : : : : : : : : : : : : : : : : :*
 * : :: : 108
        5.8.4  Packet Delivery : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : : 109
        5.8.5  Arexx Interface : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : : 109


A  Autodocs for Network Applications and Utilities                      111
   A.1  Network Utilities : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : 112
        A.1.1  arp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : : 112
        A.1.2  ifconfig : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 114
        A.1.3  inetd  : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 117
        A.1.4  letnet: : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 119
        A.1.5  offline : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : 120
        A.1.6  online: : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 121
        A.1.7  ping : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : : 122
        A.1.8  route  : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 126


B  API Function Reference                                                 128
   B.1  Standard BSD Style Socket Functions: : : : : : : : : : : : : : : : : : *
 *: : 130
        B.1.1  accept() : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 130
        B.1.2  bind(): : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 132
        B.1.3  CloseSocket()  :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 133
        B.1.4  connect()  : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : 134
        B.1.5  Dup2Socket() : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * :: : : : : 136
        B.1.6  getpeername()  :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 137
        B.1.7  getsockname()  :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 138
        B.1.8  getsockopt() : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * :: : : : : 139
        B.1.9  IoctlSocket()  :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 142
        B.1.10 listen() : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 144
        B.1.11 recv(): : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 145
        B.1.12 select() : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 147
        B.1.13 send(): : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 150
        B.1.14 shutdown(): : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : 152
        B.1.15 socket() : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 153
   B.2  Other BSD Functions Related to Sockets : : : : : : : : : : : : : : : : *
 *: 156
        B.2.1  getdtablesize() : : : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : : : 156
        B.2.2  Syslog() : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 157
   B.3  Network Data and Address Manipulation : : : : : : : : : : : : : : : : :*
 * : 159
        B.3.1  inet_addr() : : : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : : : 159
   B.4  Network, Protocol and Service Queries : : : : : : : : : : : : : : : : :*
 * : 162
        B.4.1  gethostbyname() : : : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : : : 162
        B.4.2  getnetbyname(): : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 164
        B.4.3  getprotobyname() : : : : : : : : : : : : : : : : : : : : : : : :*
 * : :: : : 166
        B.4.4  getservbyname() : : : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : : : 167
   B.5  AmiTCP/IP Specific Extensions : : : : : : : : : : : : : : : : : : : : :*
 * : : : 169
        B.5.1  Errno() : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : 169
        B.5.2  ObtainSocket(): : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 170
        B.5.3  ReleaseCopyOfSocket() : : : : : : : : : : : : : : : : : : : : : *
 *: : : : 171
        B.5.4  ReleaseSocket() : : : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : : : 172



                                     xviii





        B.5.5  SetDTableSize() : : : : : : : : : : : :: : : : : : : : : : : : :*
 * : : : : : 173
        B.5.6  SetErrnoPtr()  :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 174
        B.5.7  SetSocketSignals(): : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : 175


C  AmiTCP/IP Network Link Library                                        176
   C.1  net.lib Functions : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : 177
        C.1.1  autoinit : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 177
        C.1.2  autoinitd  : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : 178
        C.1.3  charRead : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 179
        C.1.4  gethostname : : : : : : : : : : : : :: : : : : : : : : : : : : :*
 * : : : : : : 181
        C.1.5  lineRead : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : 182


D  Protocols and Network Interfaces                                      185
   D.1  Protocols and Network Interfaces : : : : : : : : : : : :: : : : : : : :*
 * : : 186
        D.1.1  arp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : : 186
        D.1.2  icmp : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : : 189
        D.1.3  if : :: : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : :190
        D.1.4  inet : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *: : : : : : : : 193
        D.1.5  ip : :: : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : :196
        D.1.6  lo : :: : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : :198
        D.1.7  routing : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : 199
        D.1.8  tcp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : : 201
        D.1.9  udp : : : : : : : : : : : : : : : :: : : : : : : : : : : : : : :*
 * : : : : : : : : 203


Glossary                                                                   205


Bibliography                                                               209



                                      xix





xx





Chapter 1



User's  Manual



1.1     Installation


AmiTCP/IP installation is made by standard Commodore Amiga Installer
which provides an easy installation.  Before you can proceed, you should
acquire some information, list of whichfollows.
   Your should ask your local network administrator for few things to be
able to connect your Amiga to a network.  Take this page or copy of it
with you to make sure that you don't forget anything:


 1. Internet protocol address allocated for your computer.  This is a
    series of four decimal numbers separated by dots.  For example,
    ``130.233.161.40'' is a legal internet address.

 2. Destination IP address of a point--to--point link.  This applies only
    if you use a point--to--point medium, such as a serial line.


 3. Netmask for your network1 This determines which part of your internet
    address is used to specify the network.  Netmask is like
    ``255.255.255.0''.  If you do not supply this value, a default
    computed from the IP address is used.

 4. Name of your host.  This is a mnemonic name which can usually be used
    instead of the internet address to refer to your computer.  This is
    like ``Amiga1''.

 5. Domain name of your site.  For example, ``hut.fi'' is the domain name
    for the Helsinki University of Technology in Finland.

 6. Address(es) of the Domain Name Server(s) which will be used to
    translate host names to corresponding internet addresses.  A local
    host database must be used instead if there is no name server on your
    domain.

 7. Address of the default gateway via which to send packets to the hosts
    not on your local network.  There may be more than one of them.
________________________________
   1Netmask is usually needed onlyif you are connected to several

networks or a network capable to broadcasts.



                                       1


2    Section 1.1                  AmiTCP/IP                    System Manual



 8. The network interface to use.  This may be Ethernet, SLIP or
    something else.  We assume that you have proper hardware installed
    and the appropriate Sana-II compatible device driver installed in
    directory Devs:networks.  AmiTCP/IP needs the name of the device
    driver in order to use it.  The unit number for the device in
    question is also needed (usually this is 0).

   Installation starts by double-clicking the Install_AmiTCP-2.0-icon of
the distribution disc.  You can select the level whichspecifies how many
choices are left to you by the installation script.   After a successful
installation your computer is ready to communicate with the network.  See
the file README.FIRST for more information about the installation
procedure.
   If you plan to compile applications which use AmiTCP/IP, you should
add two AmigaDOS assigns for the compiler to find appropriate files.
Assign the name NETINCLUDE: to the netinclude directory of the AmiTCP/IP
and the name NETLIB: to the directory netlib.



1.1.1   Using the SLIP Drivers

Some Commodore-Amiga Networking Group supplied SANA-II drivers are
distributed with the AmiTCP/IP. The SLIPdrivers included are taken from
Olaf Seibert's distribution and has somebug fixes over the version 37.3.
See the file doc/slip.doc for installinginstructions for these drivers.
   The version number of the included slip.device is 37.4.  You can use
this or newer SLIP driver with AmiTCP/IPwith certain precautions.  The
included CSLIP device is similar to theSLIP device, it only uses the Van
Jacobson header compression (see [Jacobson 1990 ] fordescription of this
compression method).  If your network connection supports CSLIP, you can
use cslip.device instead of slip.devicein all examples given in this
section.
   Used serial interface, baud rate and other parameters for the unit 0 of
the SLIP device are specified in the configuration file
ENV:Sana2/slip0.config.  You must edit this file according your system
setup before you can use the slip device.   Copy the edited file to both
ENVARC:Sana2 and ENV:Sana2 directories.
   The AmiTCP/IP opens the slip device driver when given a following

ifconfig2 command:

ifconfig slip.device/0 local-address remote-address

The local-address is the IP address (orname) given to your host, the
remote-address is the IP address (or name) of the host you are connecting
to with the serial line.  You should also add a routingentry with the
route command, for example

route add default remote-address

You can test your SLIP connection immediately with the command

ping remote-address
________________________________
   2The ifconfig and route commands like described here are normally placed to

the startnet script during AmiTCP/IP installation.


System Manual                   AmiTCP/IP                   Section 1.2    3



Common Problems with the SLIP Driver AndAmiTCP/IP

The ifconfig command gives you the following error message, if there is
some problems opening the interface:


ifconfig: ioctl (SIOCGIFFLAGS): no suchinterface


If the device driver is not installed properly or there is no
configuration file, AmiTCP/IP gives thefollowing log message:


<3> OpenDevice: Device or unit failed toopen


In this case, you should check that thefile ENV:Sana2/slip0.config
actually exists and the device driver isin the correct directory.
   If the device driver is ok, but the needed serial device is busy (or
you have set the slip driver to offlinestate), AmiTCP/IP logs the
following message:


<3> slip.device: Device driver is offline (Unit is currently offline)


Then you must free the serial interface,set the slip device to the
online state and give the previous ifconfig command with the ``up''

option3 again.
   If AmiTCP/IP gives no error messages and the serial link still does
not work, it may be due to incorrect information in the
ENV:Sana2/slip0.config-file.  Check thatthe baud rate is correct.  Note
that the slip device loads the configuration file only on startup, which
means that you must restart the AmiTCP/IP if you have already configured
the slip driver with an ifconfig command.



1.2     Configuration


AmiTCP/IP is normally started from the command line with a startup
script.  It starts the AmiTCP/IP process, which loads the configuration
files.  The script also contains ifconfig and route commands to open the
SANA-II device drivers and add the needed route entries, respectively.
   The AmiTCP/IP can be configured with both option files and ARexx
commands.  The option files are stored in the text format and they can be
edited with any text editor.  The '#' character startsa comment, which
continues to the end of the line.  All configuration commands are
presented in the section 2.4 starting from the page 17.
   Configuration files for AmiTCP/IP are stored in the directory
AmiTCP:db.  It contains at least following files:


AmiTCP:db/AmiTCP.config   AmiTCP/IPinternal configuration.


AmiTCP:db/netdb  Network database information, ie.  host names, networks,
    services, protocols, domain name servers and domains.
________________________________
   3The up is needed because the AmiTCP/IP implicitly adds this option when

an address to the interface is first given.   If the second ifconfig specifies
the same address as before, the up option must be given explicitly.


4    Section 1.3                  AmiTCP/IP                    System Manual



AmiTCP:db/hosts.equiv  Host equivalence data used by rlogind, rshd etc.
    (these daemons are currently unimplemented).

AmiTCP:db/inetd.conf  Services provided by Inetd, the internet super
    server.



1.2.1   Options

Normally AmiTCP/IP reads options from the file AmiTCP:db/AmiTCP.config.
You can specify an option file also on the command line (eg.  AmiTCP WITH
myopts) or with the tool type WITH. Youcan prevent AmiTCP/IP from
loading the default option file by the NOCONFIG command line option.



1.2.2   Network  Database

The file AmiTCP:db/netdb is used to store the local net and host name
information.  There is an example file in the distribution, which you
must change according to your local network environment.  The syntax for
the network database file is same as thesyntax for the Arexx command add
(see page 19).
   The mostimportant entries are the name of your own host and the
important hosts in your local net.  For instance, if your host name is
amiga1.hut.fi and your internet address(IP number) is 130.233.61.50,
then there is probably a following linein your AmiTCP:db/netdb file:


     HOST 130.233.61.50 amiga1.hut.fi amiga1 amy1


   The firstentry after the keyword HOST is the internet address of your
host.  It is followed by the official name and an optional list of alias
names to your host.
   Normally,all host and network names will be translated to the actual
internet addresses by a name server.  If you can not use the name
service, then all host names must be inthe AmiTCP:db/netdb file or in an
included file.  In that case it may be easiest to copythe /etc/hosts
file from a nearby Unix machine.
   You can add host names to the network database with ARexx commands at
any time.  For instance, the following command adds a host called
vipunen:

rx "address AMITCP add host 130.233.224.20 vipunen.hut.fi vipunen"

   There arealso service and protocol entries in the network database
files.  Do not change them if you are not an expert user.



1.3     Internet Addressing


Each host in the Internet must have an unique 32 bit binary address.
This address identifies the location ofhost in the internet in an
unambiguous way.  The internet address is divided intoa net part and a
host part.  Because of this elegant feature a single address identifies a
unique host as well as the network whichthe computer is connected to.


System Manual                   AmiTCP/IP                   Section 1.3    5



   When selecting a route to a particular host the whole address is
considered first.  If no direct route to the host can be found, a route
to the host's network can be considered.  If no route to either host or
net can be found, the packet is sent tothe default gateway.
   Because the the internet address defines also the network which the
computer is connected, they must actually be given one per network
connection.  If a host is directly connected to severalnetworks, it has
also several distinct internet addresses.



1.3.1   Internet Dot Notation


Since it is rather inconvenient to use 32-bit integers, the internet
address is normally written in the Internet dot notation.  It is a series
of decimal numbers separated by dots.


              ____________________________________________________
              !_Format__!Size______________________!Example_______!
              ! a       !32-bit                    !169510179    !
              ! a.b     !8-bit.24-bit             !10.1738019   !
              ! a.b.c   !8-bit.8-bit.16-bit       !10.26.34083  !
              !_a.b.c.d_!8-bit.8-bit.8-bit.8-bit_!_10.26.133.35_!_



         Table 1.1:  Four different forms for an Internet address.


   The one with four separate octets is the most common form of the
notation.  See the reference for the function
bsdsocket.library/inet_addr() to additional information (at Appendix
B.3.1, page 159).



1.3.2   Nets and Routing



                0_1_2_3_4______8_____________16____________24___________31_
                ! !           !                                            !
       Class A  !!0!!Netpart  !!                Hostpart                   !!
                __________________________________________________________
                __________________________________________________________!!!!!

       Class B  !!1!!0!!     Netpart         !!        Hostpart            !!
                __________________________________________________________
                __________________________________________________________!!!!!!

       Class C  !!1!!1!!0!!          Netpart               !! Hostpart     !!
                __________________________________________________________
                __________________________________________________________!!!!!!

       Class D  !!1!!1!!1!!0!!         Multicast Address                   !!
                __________________________________________________________
                __________________________________________________________!!!!!*
 *!!

       Class E  !!1!!1!!1!!1!!0!!      Experimental Address                !!
                __________________________________________________________


Figure 1.1:  The Internet address classes.  The different address classes
can be identified by few first bits.


6    Section 1.3                  AmiTCP/IP                    System Manual



   There arefive classes of internet addresses in use, namely A, B, C, D
and E classes.  The difference between address classesis the length of
the network and host part.  An A class address has 7 bits for net address
and 24 bits for host address, a B classaddress has 14 bits for net and
16 bits for host and a C class address has 21 bits for net and 8 bits for
host.  The D class is used for the IP multicast addresses and the E class
for experimental use only4.
   The address class can be determined by the first octet of the address.
If it is in the range 0---127, the address belongs to the A class.  If it
is 128--191, the address belongs to theB class.   If the first octet is
192--223, the address belongs to the C class, otherwise it is an
experimental or a multicast address.



1.3.3   Subnets

The network addresses are managed by a central authority.  Local
administration manages the host addresses.   Because network addresses are
used in routing, the central authority is needed when the local network
changes its structure.  This might be quite a burden tothe central
authority, but there is a solution developed for the Internet.  A network
may be split into several subnets, whichcan then be managed by
independent agencies.  The central network management doesn't have to
know anything about subnets and hosts inthem.
   For instance Kone corporation has been assigned a B class network
138.249.0.0.  This network has been divided to C classlike subnets,
which are then given to the departments.  The HAT department is given
subnet 138.249.2.0, the HATMEC department subnet 138.249.5.0 and so on.
                 0________8________16______24_______

      Address    !!_________________________________1!138.249.!02.03001010!!111*
 *11001!!00000010!!00011110

                 ___________________________________
 AND  Netmask    !!_________________________________1!255.255.255.!10111111!!11*
 *111111!!11111111!!00000000
_______________________________________________________________________

  =    Subnet    !!_________________________________1!138.249.!02.0001010!!1111*
 *1001!!00000010!!00000000



        Figure 1.2:  Using netmask to find out subnetwork address.


   The subnet division is controlled by the netmask parameter.  The actual
subnetwork address is obtained by bit-wise AND between the netmask and
the internet address.  This subnet address is used in routing just like a
normal net address.  However, only hosts directly connected to the
divided net have to know anything aboutnetmasks and subnets.



1.3.4   Broadcast Addresses

There are two kind of broadcast addresses in the Internet.  An obsolete
form used in older BSD 4 versions used internet address with host part 0
________________________________
   4Routers not taking part to such experiments normally discard all

packets of this class.


System Manual                   AmiTCP/IP                   Section 1.4    7



as the broadcast address.  (The newer software usuallyconsiders
addresses like those as network addresses.)   Accordingthe the current
Internet standard the broadcast addresses have the host part all 1's.


      ___________________________________________________________________
      !   Interface    !                !   Network     !  Broadcast     !
      !                !  Netmask       !               !                !
      !    Address     !                !   Address     !   Address      !
      !________________!________________!_______________!________________!
      ! 10.14.123.2   !255.255.255.0   ! 10.14.123.0   ! 10.14.123.255  !
      ! 130.244.5.4   !255.255.255.128 ! 130.244.5.0   ! 130.244.5.127  !
      !_192.36.148.21_!255.255.255.0___!_192.36.148.0__!_192.36.148.255_!_



Table 1.2:  Examples of netmasks, network addresses andbroadcast
addresses.



1.4     Utilities


Currently, only a few networking utilities are ported for the AmiTCP/IP.
They are used to monitor and control network operation with AmiTCP/IP.
There is a separate reference entry foreach network utility and daemon
in the document file netutil.doc.  This autodoc file isincluded in the
appendix A, starting from page 111.



1.4.1   arp

arp displays and modifies the internet to hardware address translation
tables used by the Address Resolution Protocol.   It isused if you are
connected to a broadcast network, eg.  Ethernet or Arcnet.  You may
examine, add, and delete ARP entries.  Usually arp is used to find out
hardware address of hosts.
   The hardware addresses are given as hexadecimal strings, each octet
separated by a colon.
   Examples:


 1.> arp -s puucee 8:0:9:32:f2:4c pub

    This command sets the hardware address for the host 'puucee' as
    '8:0:9:32:f2:4c'.



1.4.2   ifconfig

ifconfig configures network interface parameters.   Itassigns an internet
address to a SANA-II network interface or sets interface parameters.
ifconfig is normally used at the AmiTCP/IP startup.
   Examples:


 1.> ifconfig lo/0 127.1

    This command marks internal loopback device up, and attaches the
    internet address 127.0.0.1 to it.


8    Section 1.4                  AmiTCP/IP                    System Manual



 1.> ifconfig cslip.device/0 inet 193.102.4.144 193.102.4.129

    This command starts the CSLIP driver, attaches an address
    193.102.4.144 (our internet address) and a destination address
    193.102.4.129 (the internet address of the host you are connecting)
    to it.


 1.> ifconfig a2065.device/0 inet 193.124.100.66 +
    netmask 255.255.255.192 up -arp

    This command loads an ethernet driver for the Commodore A2065
    Ethernet adapter unit 0, marks it UP, disables ARP protocol for it,
    attaches an inet address 193.124.100.66 to it and sets its netmask to
    255.255.255.192.  A bitwise logical AND of the netmask and the
    address for the interface forms the subnet address, in this case
    193.124.100.66.  All packets aimed to hosts with same subnet address
    (that is hosts 193.124.100.65--193.124.100.126) are routed to this
    interface.



1.4.3   letnet

letnet is a simple TCP connection tool.  With it you can connect to a TCP
port at given host.  Letnet reads data from standard input and sends it
to the host.  Likewise it receives data from the connection and writes it
to the standard output.  Letnet terminates upon shutdown of the socket or
receiving SIGBREAKF_CTRL_C signal.  Letnet does not handle telnet
protocol.



1.4.4   netstat

netstat shows network status.  It symbolically displaysinformation of
network data structures of the AmiTCP/IP. There are several standard
AmigaDOS style options:


 By default displays all sockets that are not listening.


ALL displays all sockets.


STATUS displays values of several protocol-related variables.


   Example:


 1.> netstat status


   Netstat is an ARexx script which uses the AMITCP port of the AmiTCP/IP
to collect the information.  See section2.5.1 (p.  18) for details about
the ARexx commands supported by the AmiTCP/IP.



1.4.5   NapsaTerm

NapsaTerm is a VT102 terminal emulator for logging remotely to Unix hosts
with rlogin protocol.  It is based on the NiftyTerm version 1.2 for Amiga
by Chris Newman and William Todd.


System Manual                   AmiTCP/IP                   Section 1.5    9



 1.> run napsaterm -d net happi.hut.fi

    This command starts VT102 emulator with a rlogin connection to the
    host happi.hut.fi.



1.4.6   offline

offline5 sends the S2_OFFLINE command to thegiven SANA-II device driver.
This command is normally used to disconnect SANA-II device driver from
the network adapter hardware.  After this command the device driver does
not accept any more read or write requests.
   Example:

 1.> offline slip.device/0

    This command puts the SLIP driver unit 0 offline, which frees then
    the serial port to other use.



1.4.7   online

online sends the S2_ONLINE command to the given SANA-II device driver.
The device driver restarts the network adapter hardware and accepts read
and write request again.
   Example:

 1.> online a2066.device/0

    This command tries to start the Commodore ARCNET network adapter.



1.4.8   route

route manipulates the routing tables.  It is normally used at the
AmiTCP/IP startup sequence to provide the default routing information in
the routing tables.  All needed routing information canbe provided with
this command.
   Routes determine into which network IP packets are sent.  Usually there
is only need to set the default route toyour gateway and the route to
the host itself through the loopback device.   More route entries may be
needed if your host is used as a gateway.



1.5     Errors  and  Logging


There are two kinds of error reports AmiTCP/IP produces:

Errors might be produced when a user process or a network supplies
    invalid data.  These don't cause any problems to AmiTCP/IP. These

    events are logged6 to help the user to find out possible problems
    with his/her system.
________________________________
   5offline and online are compatible with the Commodore supplied SANA-II

utilities with same names.  However, they support the AmiTCP/IP naming
convention.
   6if logging is not disabled


10    Section 1.7                  AmiTCP/IP                   System Manual



Failures are more serious.  These mean that AmiTCP/IP has entered to
    state where there is no way out.

    In Unix systems these cases lead to panic() and immediate restart.
    This is because in Unix systems networking software is integral part
    of the kernel and if something goes wrong, it usually means that the
    whole kernel is corrupted.  This is not the case in Amiga and
    AmiTCP/IP, however.  As AmiTCP/IP runs as a normal process, rest of
    the system can work even if networking fails.


   In Unix systems the syslogd takes care of the error reporting using an
attached console.  In AmigaOS there is no general failure reporting
system, only User Requesters which are inadequate for non-interactive
use.  As logging could be used even while in interruptlevel, AmiTCP/IP
can't write to log-files itself.  This is why the actual logging is done
by the NETTRACE process.  It is started at AmiTCP/IP startup and can be
configured through AMITCP ARexx port.
   ARexx commands can be found in section 2.5.1 (p.  18).



1.6     Troubleshooting


This section is reserved for the frequently asked questions and answers
to them.



1.7     Testing Utilities



There are two testing utilities providedwith the AmiTCP/IP. The agnet7
controls the loopback pseudo device which simulates different networks.
The qwriter simulates some typical application programs.  They can be
used together to test the integrity of the protocol stack.



1.7.1   Agnet


SANA-II pseudo device driver agnet.device works as a network between its
units.  Packets from one unit are sent to another according given
destination address.  You can also arrange an unit-to-unit connection, if
you want to simulate point-to-point devices.
   The loopback device provides nearly full SANA-II device driver
functionality.  It provides different hardware types, packet types and
the variable hardware address width from0 to 128 bits.  It collects all
the required statistics.  It does not provide the multicast
functionality.
   A specialcommand file env:sana2/agnetn.config is used to configure and
control the device.  Configuration parameters may be specified by
supplying its keyword and the wanted value.   Any parameter may be left
out.
________________________________
   7As Good NETwork as you like


System Manual                   AmiTCP/IP                   Section 1.7    11



   The configuration file parsing template is
WIRE/K,MTU/N/K,MINTU/N/K,BPS/N/K,ADDR=ADDRESS/K,
DELAY/N/K,DEV=DEVIATION/N/K,ERRORS/K/N,LOSS/K/N,DST=DSTUNIT/K/N.8
   User configurable parameters are:

WIRE hwiretypei is the hardware type which device driver will report.
    Other default parameters are set according to it.  Default hardware
    type is Ethernet.  With different wire types you can test for
    instance Ethernet specific features of AmiTCP/IP without killing the
    whole Ethernet segment of your network.

ADDRESS hhardware addressi  is the hardware addresses for the unit.
    Address is specified as a hexadecimal octet string.  Octets are
    separated by colons.  The length of the address depends of the
    hardware type.  For example, 8:0:9:14:74:53 is a legal Ethernet
    hardware address.  Alias:  ADDR.

DSTUNIT hunit numberi  is the destination unit for a unit-to-unit
    connection.  If this parameter is given, all packets sent to the unit
    are relayed to specified destination unit regardless of the packet
    destination address.

MTU hnumber of octetsi  is the maximum packet size that pseudo network will
    accept.  Default value is 1500 octets, same as the MTU for the
    Ethernet.

MINMTU hnumber of octetsi  is the minimum packet size that pseudo network
    will accept.  Smaller packets are padded to this minimum length.
    Default value depends on the hardware.  It is for instance 46 octets
    for the Ethernet.

BPS htransmission speedi  is the bit speed which device driver will report
    to the user.

DELAY hdelay timei specifies the delay of network in milliseconds.  By
    default there is no delay.

DEVIATION hstandard deviationi  specifies delay variance in milliseconds.
    Packets are delayed randomly which means that packets may arrive in
    different order they were sent.  Deviation without delay is
    meaningless.  By default the variance is 0 ms and all packets have
    same delay.

ERRORS hprobabilityi  is theprobability of bit errors.  This value can be
    in range [0..100 000 000], ERRORS/100 000 000 indicating probability
    of a single bit error.  Error rate 100 000 000 means that all bits
    have random value.  By default there are no errors (value 0).

LOSS hprobabilityi defines the probability of the packet loss.  This is a
    number in the range [0..1 000 000], LOSS/1 000 000 indicating
    probability.  By default there is no packet loss.  Note that value
    1 000 000 means that all packets are lost.

________________________________
   8Alternative forms of keywordsare specified by using alt=keyword.

Modifier /N specifies that the parameteris numeric.


12    Section 1.7                  AmiTCP/IP                   System Manual



ARexx Port for agnet.device

The Arexx port is normally named as AGNET1.   If thereis multiple
instances of the agnet.device, the second instance has the port AGNET2
and so on.
   There iscurrently three different Arexx commands:


UNIT Alias:  U

    Some configuration parameters may be changed at run-time by Arexx
    commands.  The Arexx configuration commands follow the same syntax as
    the configuration file.  The user must specify the unit to configure
    by preceding the command with the keyword (UNIT, abbreviated as U)
    and a decimal unit number.  For instance, the following is a legal
    Arexx configuration command:


    address AGNET1 unit 0 bps 2400 wire slip delay 100


QUERY Alias:  Q

    The current configuration may be queried from the device by an ARexx
    command Q=QUERY. The command keyword is followed by an unit number
    and wanted configuration parameters.  You can also give a keyword
    ALL, if you want all configuration parameters.  For example,
    following command prints wiretype, delay, deviation and loss
    probability:


    options results
    address AGNET1 query 0 wire delay deviation loss
    say result


EXIT Aliases:  E, EXPUNGE

    The device may be expunged from the system memory by this Arexx
    command.  The command fails, if there are some currently opened
    units.


System Manual                   AmiTCP/IP                   Section 1.7    13



1.7.2   Qwriter


qwriter9 works on the application layer.  It is run as two distinct
processes.  A process acts as a server or a client.  It creates one
socket and sends and receives data through the socket.  It is able to
control data consistency and measures both latency times and throughput
(if appropriate).
   Server part is started first in all tests.  Server starts to listen to
a port, and you can start the client.  Tests are configurable, basic test
types are described below.


telnet simulates typical interactive use.

    In this test a TCP connection is created.  The client end sends one
    character at a time and the server replies with four or more
    characters at a time.

    The most important measurement is the latency time between the sent
    character and the received echo.

nfs simulates the data transfer of a network file system.

    In this test UDP messages are sent between processes.

    Both latency and the throughput are important measurements in this
    test.

ftp is a simple TCP connection.

    In this test a TCP connection is created, then some data is
    transferred from one end to the another.

    In this test throughput is the key measurement.



Command Line Options

-s Act as a server (default).

-c Act as a client.

-t htypei Describes type of test:  ftp, nfs or telnet.  Type can be
    abbreviated to shortest unique length.  Default is telnet.

-n hcounti Describes how many times packets are sent back and forth.
    Applies to nfs and telnet.  Default for hcounti is 1.

-l hlengthi Describes length of data.  Default is 1000 octets.  Length has
    different meaning in different test contexts:


    ftp Length of the requested data for the client.  Length parameter is
        meaningless for a ``ftp'' server.

    nfs The size of the packet to be sent to the other end.

    telnet  The maximum length of data returned from the server.  Actual
        length is random value between 4 and length octets.  See also
        option ``-d''.  This parameter is meaningless for a client.
________________________________
   9Quick WRITER


14    Section 1.7                  AmiTCP/IP                   System Manual



-d hn1,n2,: :,:nNiThis option has meaning for the telnet server and
    overrides the ``-l'' option.  It specifies distibution of data
    lengths of replied packets to help better simulate typical
    interactive use where replies are usually short, but sometimes long
    (few kilobytes).

    Only k = 2i  N first numbers have effect.   Probability to have length
    less than nj (1  j  k) is approximately


                                                 Xk  nj
                              P (j) = P (j 1) + 1_   ___
                                                k    nl
                                                 l=j


    (P (0)   =  0) This can vary depending on random numeber generator and
    because of discret nature of computing.  The largest length is nk.

-b hsizei Size of the buffer tobe allocated for sends and/or replies.
    Default is 30 kilobytes.  Amount of data to be send at once, if
    smaller than data to be sent.  Maximum amount of data to be expected
    from the other end.

-p hporti the server port number.   The default is 1500.

-h hhosti Name of the host to connect.  Has no meaning for servers.  The
    default is address ``127.0.0.1''.

-q Calculate checksum and verify returned messages.   Thisprovides way to
    check for integraty of transferred data.  Checksum method is FCS as
    described in PPP RFC (1331).

-T htimeouti Specifies timeout (in seconds) for retransmission.  Only
    meaningful for nfs client.  The default is 1.0 seconds.





Chapter 2



Interfaces



AmiTCP/IP provides Berkeley sockets compatible interface to the
application programs.  Networking applications can usethis interface to
use TCP and UDP protocols, for example.
   AmiTCP/IPnetworking system uses SANA-II network devices.  SANA-II is
an Amiga standard network device driverinterface at the data link layer.



Figure 2.1:  Interfaces between different modules of the AmiTCP/IP
internetworking system.


   There isalso a standard ARexx interface for logging, statistics and
configuration in AmiTCP/IP.



2.1     AmiTCP/IP Processes


AmiTCP/IP uses one protocol process.  The protocol process starts
listening specified SANA-II device drivers for incoming network frames



                                      15


16    Section 2.3                  AmiTCP/IP                   System Manual



and sends timeout requests periodicallyto the timer device.  Output to
the network is usually done in the API callers context concurrently with
the input processing.
   There isone other task called NETTRACE taking care of error reporting
and the ARexx port of the AmiTCP/IP. Thecommands for this port are
described later in the section 2.5.1.



2.2     Application Interface


Application Interface is implemented asa standard Amiga shared library.
Each task that opens the library (usingthe OpenLibrary() call) is given
an unique data area (called a library base), which AmiTCP/IP uses it to
store task specific information (see section 3.1.2 for more on this
subject).  Once the library is opened, applications cancall the standard
socket functions such as socket(), connect(), bind(), listen(), accept(),
recv() and send().



2.3     SANA-II Interface


AmiTCP/IP can use (hopefully) any SANA-II [SANA-II 1992 ] device.
However, there may be problems with packet types and addressing.
   Many protocols may use the same hardware if each protocol uses unique
packet type number.  For instance, in the Ethernet theIP protocol have
packet type 2048, the Xerox NS protocoluses the packet type 1536.  The
device driver directs packets to different protocols depending of their
type.  IP packet type varies in different hardware, forinstance ARCNET

uses packet type 240 for IP1.
   SANA-II devices are required to follow the hardware type numbers
assigned in the [Reynolds 1990 ].  There is only one hardware typewhich
for instance all Ethernet drivers shoulduse.   The SANA-II interface
module uses the hardware type number todetermine packet types for each
protocol.
   The hardware level addressing complicates the situation further.  It is
not possible to provide a general addressing scheme in hardware level.
AmiTCP/IP can use a driver only if thereis some mapping from IP
addresses to hardware addresses.
   SometimesSANA-II network driver uses an IP compatible addressing

scheme, for instance SLIP or PPP drivers2 use an IP address asthe
hardware address.  Other solution is to use Address Resolution Protocol
(ARP). With ARP AmiTCP/IP can map any IPaddress to the corresponding
hardware address.
   For installing appropriate SANA-II device driver the manual of the
device driver should be consulted.  Note that if the device driver is not
installed into the devs:networks directory, a full path must be specified
when the driver is first referred to after the startup.
________________________________
   1There is an extension to ARCNET IP that is incompatible with old one.

It uses packet type 212 for IP.
   2At the hardware level these protocols do not use addresses at all.


System Manual                   AmiTCP/IP                   Section 2.5    17



   A networkdevice driver can be attached to the AmiTCP/IP with ifconfig
command.  This can be done manually or by the network startup script.



2.3.1   Interface ioctls

The AmiTCP/IP provides an upward compatible ioctl interface to configure
the network interfaces.  Refer to the autodoc entry protocols/if for
standard BSD ioctl interface (see appendix D.1.3, page 190).  The
extension for this interface is meant toconfigure hardware dependent
parameters in an uniform way.
   The ARP interface have been modified to be slightly more generic.  The
length of the hardware address is now passed in the arp_ha address field.
A new ioctl accesses the contents of thewhole ARP mapping cache.  (In
the BSD the static ARP table is accessedvia the /dev/kmem.)



2.4     Configuration Files


The initial state of AmiTCP/IP is set bythe configuration files.  The
syntax differs from one configuration file to another.  For each file
format there is usual a corresponding ARexx command with the same syntax.
For instance, configuration options, which are set in the file
AmiTCP:db/AmiTCP.config, may be set withthe SET command by an ARexx
script.  The entries of the AmiTCP:db/netdb file can beadded manually
with the ADD command.



2.5     ARexx Interface


In Amiga environment Exec message portsare standard way to communicate
between applications.  Because of the ease of programming and the
efficiency the ARexx programming language has become the standard in the
Amiga and structure it uses for messagesis also standard.  AmiTCP/IP
provides ARexx port named AMITCP which can be used to both configure and
gather information from networking.  This is much moreelegant compared
to the BSD Unix way to read directly from the kernel memory.
   The AMITCP port can be used to set and query various variables and
statistic tables.  Brief example of the usage of the port follows:


/*c:rexx
 *
 * An example to query some informationform AmiTCP/IP
 */


address AMITCP
options results /* get results back */


'Q' TASKNAME
say "Name of amitcp task is" result
'SET' TASKNAME "INET"
'QUERY' ICMP CHKSUM IP CHKSUM TCP CONNECT UDP CHKSUM TASKNAME
/* Query count of ICMP, IP and UDP checksums and TCP connects */


18    Section 2.5                  AmiTCP/IP                   System Manual



parse value result with icps_checksum ips_badsum tcps_connects udps_badsum task*
 *name
/* Parse values from result. (Names of the variables are from
 * the stat-structures
 */


say "New name is" taskname


say icps_checksum "bad ICMP checksums"
say ips_badsum "bad IP header checksums"
say tcps_connects "TCP connections established (including accepts)"
say udps_badsum "bad UDP checksums"

   This example will produce output similar to following:

Name of amitcp task is AmiTCP
New name is INET
0 bad ICMP checksums
0 bad IP header checksums
2531 TCP connections established (including accepts)
0 bad UDP checksums



2.5.1   Commands

This section summarizes the commands recognized by the ARexx port of the
AmiTCP/IP. The command lines may containcomments, which are started by
the semicolon.

ADD hentryi This command adds entries to thenetwork database.  Templates
    for the entries are:

    WITH hfile namei [PREFIX=hentry typei]  Include the file hfile namei.
        Entry type for the file may be specified with an optional prefix,
        which may be any of the entry types listed in this list.   The
        file will be searched first from the AmiTCP:db directory, so that
        the actual path may be omitted, if the file resides inthat
        directory.
        For exmaple,
        WITH hosts PREFIX=HOST
        includes the file hosts, which contains only host entries.   The
        host keyword must not be present at the file itself.
        The WITH command is useful for including database files
        downloaded from Unix machines.

    H=HOST haddressi hnamei [aliases]  Add a host entry to the network
        database.  Either H or HOST can be used as the keyword. The
        haddressi is the internet address of the host, the hnamei is the
        official name and [aliases] is an optional list of alias names
        for the host.
        Example:
        H 128.214.6.100 nic.funet.fi nic

    N=NET hnamei haddressi [aliases]  Add a net entry to the network
        database.  Arguments are as above for the HOST.
        Example:


System Manual                   AmiTCP/IP                   Section 2.5    19



        N loopback-net 127 software-loopback-net

    S=SERVICE hnamei hporti/hprotocoli [aliases]  Add a service entry to the
        network database.  The hporti is the port number for the hprotocoli
        for which the server for the service will listen for the service
        requests.  [aliases] is as above.
        Example:

        S daytime 13/tcp

    P=PROTOCOL hnamei hprotocol numberi [aliases]   Add a protocol entry to
        the network database.
        Example:

        P tcp 6

    NS=NAMESERVER haddressi  Add a name server entry to the network
        database.  The haddressi is the address of the name server in the
        internet dot-notation.  The name servers are searched in the
        order specified in the database.
        Example:

        NS 130.233.224.1 ; santra.hut.fi

        Note that the symbolic name is after the ';' character,which
        marks the start of an end of line comment.

    DO=DOMAIN hdomain namei  Add a domain name entry to the network
        database.  The hdomain namei is the part following the first '.'
        in the official host name.  The domain entries specify the
        domains from which a host name is searched.  The search is done
        in the order of the entries added to the network database.
        Example:

        DOMAIN cs.hut.fi


QUERY hvariable namei [: :]:Get the value of the variable.  Many variables
    have a two-level hierarchical structure (especially for variables
    related to the statistics) in which both the name of the table and
    the name of the variable itself must be supplied.

    Values for many variables can be queried with one command by putting
    names of the variables in a row.


RESET Reread the network database file AmiTCP:db/netdb.


SET hvariable namei hvariable valuei [::]:  Set the value of a variable.
    Name of the variable is given as with QUERY and the value is given
    after the name.

    Multiple variables can be set with one command by supplying
    name-variable pairs.

    Note that some variables are read-only and others writeable only
    during configuration.



2.5.2   Variables

Here is a complete list of all configuration and network statistic
variables.


20    Section 2.5                  AmiTCP/IP                   System Manual



WITH Include a file with multiple settings.  (This pseudo variable is a
    extension to the SET command.)

ICMP Variables related to Internet Message Control Protocol.  Alias:  IC


    ERROR  Number ofcalls to icmp_error().  Alias:  E

    SHORTOLD  No error because old IP wastoo short.  Alias:  S

    ICMPOLD  No error because oldwas ICMP. Alias:  I

    CODE  ICMP code out of range.  Alias:  CO

    TOOSHORT  Packet too short.  Alias: T

    CHKSUM  Checksum error.  Alias:  CH

    LENGTH  Data length larger than packet.  Alias:  L

    RESPONSES  Number of responses.  Alias:  R


ICMPHIST ICMP packet send and reception history.  See page 24 for details
    on the output format.  Alias:  ICH

IP Variables related to Internet Protocol.


    TOTAL  Total number of packets.  Alias:  T

    CHKSUM  Checksum error.  Alias:  CH

    TOOSHORT  Packet too short.  Alias: TOOSH

    TOOSMALL  Not enough data.  Alias:  TOOSM

    HEADER  IP header length less than data size.  Alias:  H

    LENGTH  IP header length larger than packet.  Alias:  LE

    FRAGMENTS  Packet fragments received.  Alias:  FS

    FDROP  Fragmentsdropped (duplicates, out of space).  Alias:  FD

    FTIMEOUT  Fragments timed out.  Alias:  FT

    FORWARD  Packets forwarded.  Alias: FO

    FWDCANT  Packets received forunreachable destination.  Alias:  FW

    REDIRECTSENT  Packets forwarded on same net.  Alias:  RED

    NOPROTO  Unknown or unsupported protocol.  Alias:  N

    DELIVER  Packets consumed here.  Alias:  D

    LOCALOUT  Total IP packets generatedhere.  Alias:  LO

    ODROPPED  Lost packets due to nobufs,etc.  Alias:  OD

    REASSEMBLED  Total packets reassembled ok.  Alias:  REA

    FED Output packets fragmented ok.  Alias:  FE

    OFRAGMENTS  Output fragments created.  Alias:  OF

    FCANT  Don't fragment flag was set, etc.  Alias:  FC


TCP Variables related to Transmission Control Protocol.  Alias:  T


    CATTEM  Connections initiated. Alias:  CA

    ACCEPTS  Connections accepted.  Alias:  A


System Manual                   AmiTCP/IP                   Section 2.5    21



    CONNECT  Connections established.  Alias:  CO

    DROPS  Connections  dropped.  Alias:  DR

    CDROPS  Embryonic connections dropped.  Alias:  CD

    CLOSED  Connections closed (incl.  drops).  Alias:  CL

    SEGSTIMED  Segments where we tried to get rtt.  Alias:  SE

    RTTUPDATE  Times we succeed rtt.  Alias:  RTT

    DELACK  Delayed acknowledgments sent.  Alias:  DE

    TIMEODROP  Connection dropped in rxmt timeout.  Alias:  T

    REXMTT  Retransmit timeouts. Alias:  RE

    PERSIST  Persist timeouts.  Alias:  P

    KATIMEO  Keepalive timeouts.  Alias: KAT

    KAPROBE  Keepalive probes sent.  Alias:  KAP

    KADROPS  Connections dropped in keepalive.  Alias:  KAD

    STOTAL  Total packets sent.  Alias:  ST

    SPACK  Data packets sent.  Alias:  SP

    SBYTE  Data bytes sent.  Alias:  SB

    SREPACK  Data packets retransmitted.  Alias:  SREP

    SREBYTE  Data bytes retransmitted.  Alias:  SREB

    SACKS  Ack-onlypackets sent.  Alias:  SA

    SWPROBE  Window probes sent. Alias:  SWP

    SURGENT  Packets sent with URGonly.  Alias:  SU

    SWUPDATE  Window update-only packetssent.  Alias:  SWU

    SCTRL  Control (SYN_FIN_RST) packets sent.  Alias:  SC

    RTOTAL  Total packets received.  Alias:  RTO

    RPACK  Packets received in sequence.  Alias:  RPA

    RBYTE  Bytes received in sequence.  Alias:  RB

    RCHKSUM  Packets received withchecksum errors.  Alias:  RC

    ROFFSET  Packets received withbad offset.  Alias:  ROF

    RPSHORT  Packets received tooshort.  Alias:  RPS

    RDUPPACK  Duplicate-only packets received.  Alias:  RDUPP

    RDUPBYTE  Duplicate-only bytes received.  Alias:  RDUPB

    RPDUPDATA  Packets with some duplicate data. Alias:  RPDUPD

    RPDUPBYTE  Dup.  bytes in part-dup.  packets.  Alias:  RPDUPB

    ROOPACK  Out-of-order packetsreceived.  Alias:  ROOP

    ROOBYTE  Out-of-order bytes received.  Alias:  ROOB

    RPLATE  Packets with data after window.  Alias:  RPL

    RBLATE  Bytes receivedafter window.  Alias:  RBL

    RAFTER  Packets received after close.  Alias:  RAF

    RWPROBE  Received window probepackets.  Alias:  RWP


22    Section 2.5                  AmiTCP/IP                   System Manual



    RDUPACK  Received duplicate acknowledgments.  Alias:  RDUPA

    RACKTOOM  Received acknowledgments for unsent data.  Alias:  RACKT

    RACKPACK  Received acknowledgment packets.  Alias:  RACKP

    RACKBYTE  Bytes acknowledged by received acknowledgments.  Alias:
        RACKB

    RWUPDATE  Received window update packets.  Alias:  RWU


UDP Variables related to User Datagram Protocol.  Alias:  U


    ITOTAL  Total input packets.  Alias:  I

    HEADSHORT  Packet shorter than header.  Alias:  H

    CHKSUM  Checksum error.  Alias:  C

    LENGTH  Data length larger than packet.  Alias:  L

    NOPORT  No socket on port.  Alias:  N

    BCNOPORT  No socket on port, arrivedas broadcast.  Alias:  B

    FULLSOC  Not delivered, inputsocket full.  Alias:  F

    MISPCB  Input packets missing pcb cache.  Alias:  M

    OTOTAL  Total output packets.  Alias:  O


CONNECTIONS  Returns a list ofall TCP and UDP connections, including
    server (listening) sockets.  See page 24 for the output format
    description.

MBUF_STAT Memory buffer statistics.  Alias:  MBS


    MBUFS  Total number of allocated memory buffers.  Alias:  M

    CLUSTERS  Total number of allocated memory buffer clusters.  Alias:
        CL

    CLFREE  Number of memory buffer clusters free.  Alias:  CLF

    MDROPS  Times failed tofind space.  Alias:  MD

    NWAITED  Times waited for space.  Alias:  NW

    NDRAINED  Times drained protocols forspace.  Alias:  ND

    TOTALMEMORYUSED  Total amount of memory used for the mbufs.  Alias:
        TMU


MBUF_TYPE_STATS Returns type specific statistics of mbuf allocations.  The
    last number is the total number of mbufs allocated.  Alias:  MBTS

MBUF_CONF Memory buffer configuration.  Alias:  MBC


    INITIAL  Number of mbuf chunksto allocate initially.  Alias:  I

    CHUNK  Number ofmbufs to allocate at a time.  Alias:  CH

    CLCHUNK  Number of clusters toallocate at a time.  Alias:  CL

    MAXMEM  Maximum memoryto use (in kilobytes).  Alias:  MM

    CLUSTERSIZE  Size of an mbuf cluster.  Alias:  CS


System Manual                   AmiTCP/IP                   Section 2.5    23



LOG Logging system configuration.


    COUNT  Number oflog messages to use.

    LEN Maximum length of a log message.


TASKNAME Name of AmiTCP/IP task.


NTHBASE Current AmiTCP/IP has nth bsdsocket.library base currently in
    memory.  Alias:  NTH


DEBUGSANA  Boolean to switch the SANA-II device interface debugging on and

    off3.  Alias:  DBSANA


DEBUGICMP  Boolean to switch the ICMP debugging on and off.  Alias:
    DBICMP


DEBUGIP Boolean telling whether IP should log debugging information.
    Alias:  DBIP


GATEWAY Boolean to switch gateway functionality on and off.  Alias:  GTW


IPSENDREDIRECTS  Boolean telling whether IP should send ICMP redirect
    messages.  Alias:  REDIR


USENAMESERVER  How to use name server.  Possible values are:


    NO Do not use name server at all.  Local database will be used
        instead.

    FIRST  Query thename servers first and if that fails, use local
        database.

    SECOND  First look up the local database, then, if that fails, query
        the name servers.


    Alias:  USENS


USELOOPBACK  If true use the local loop device for local traffic.  Alias:
    ULO


TCP_SENDSPACE  Default size of the sending socket buffer (TCP). Alias:
    TCPSND


TCP_RECVSPACE  Default size of the receiving socket buffer (TCP). Alias:
    TCPRCV


CONSOLENAME  Filename for thelog console.  Alias:  CON


LOGFILENAME  Filename for thelog file.  Alias:  LOGF


________________________________
   3See page 24 for description about boolean variable.


24    Section 2.5                  AmiTCP/IP                   System Manual



Boolean variables

The variables documented as boolean accept their values in various

formats.  Boolean false may be given asNO4 , FALSE, OFF or 0.  YES, TRUE,
ON and 1 are considered as boolean true.
   The firstalternatives are used on output.



CONNECTIONS output format

CONNECTIONS query returns its result ina format which has
space-separated fields, connection afterconnection (not sorted).  Format
is as follows:

     _____________________________________________________________________
     !_Field_length_!___Value_type____!Description_______________________!_
     !_______1_______!char_`t'_or_`u'_!t_for_TCP_connection,_u_for_UDP_!__
     !_______4_______!__4-char_hex____!Receive_queue_length_____________!_
     !_______4_______!__4-char_hex____!Send_queue_length________________!_
     !_______8_______!__8-char_hex____!Local_address_____________________!_
     !_______4_______!__4-char_hex____!Local_port_number________________!_
     !_______8_______!__8-char_hex____!Foreign_address___________________!_
     !_______4_______!__4-char_hex____!Foreign_port_number______________!_
     !_______1_______!__1-char_hex____!State_of_connection______________!_


   The hexadecimal values are zero padded from left to their full length.
Last item presents the state of the TCPfinite state machine.  Possible
values for it are:

              ____________________________________________________
              !_Value_!State_of_TCP_FSM________________________!__
              !___0___!Closed___________________________________!_
              !___1___!Listening_for_connection________________!__
              !___2___!Active,_has_sent_SYN____________________!__
              !___3___!Has_send_and_received_SYN______________!___
              !___4___!Established______________________________!_
              !___5___!Received_FIN,_waiting_forclose_________!___
              !___6___!Has_been_closed,_sent_FIN______________!___
              !___7___!Closed_exchanged_FIN;_awaiting_FIN_ACK_!___
              !___8___!Had_FIN_and_close;_awaiting_FIN_ACK_____!__
              !___9___!Has_been_closed,_FIN_is_acknowledged___!___
              !___A___!Is_in_2*msl_quiet_wait_after_close______!__



ICMPHIST output format

ICMPHIST query returns the ICMP historytable entries on one line
separated by spaces.  Outhistory is returned first beginning from the
entry 0.  Both tables contains 19 entries for differentICMP messages.
Note that all message types are not in use.   Message types are as
follows:________________________

   4Upper case keywords are used here for clarity only.  Lower case (or

mixed case) keywords are accepted as well.


System Manual                   AmiTCP/IP                   Section 2.5    25



                        ________________________________
                        !__0_e!cho_reply_______________!_
                        !__1_n!ot_used_________________!_
                        !__2_n!ot_used_________________!_
                        !__3_D!estination_unreachable_!_
                        !__4_P!acket_lost,_slow_down__!_
                        !__5_S!horter_route____________!_
                        !__6_n!ot_used_________________!_
                        !__7_n!ot_used_________________!_
                        !__8_E!cho_service_____________!_
                        !__9_n!ot_used_________________!_
                        !_10_!not_used_________________!_
                        !_11_!Time_exceeded____________!_
                        !_12_!IP_header_bad____________!_
                        !_13_!Timestamp_request________!_
                        !_14_!Timestamp_reply__________!_
                        !_15_!Information_request_____!_
                        !_16_!Information_reply________!_
                        !_17_!Address_mask_request____!_
                        !_18_!Address_mask_reply______!_


26    Section 2.5                  AmiTCP/IP                   System Manual





Chapter 3



Programmer's  Manual



This chapter provides an in depth description of the AmiTCP/IP
application programming interface.  Following sectionsintroduce the
socket model of communication (3.1) andthe bsdsocket.library function
calls implementing the socket abstraction.   Some useful supporting
routines are described in section 3.2.  The client/server model is
introduced in section 3.3.  Some more advanced topics are discussed in
section 3.4.  Section 3.5 summarizes the small differences between
AmiTCP/IP and 4.3BSD socket APIs.  The full function reference of the
AmiTCP/IP API functions is in appendix Bstarting from page 128.
   The textin sections 3.1 -- 3.4 is based on the [Leffler et al 1991a ].



3.1     Socket Concepts


The basic building block for communication is the socket.  A socket is an
endpoint of communication to which a name may be bound.  Each socket in
use has a type and one or more associated processes.  Sockets exist
within communication domains.  A communication domain is an abstraction
introduced to bundle common properties of processes communicating through
sockets.  One such property is the scheme used to name sockets.  Sockets

normally exchange data only with socketsin the same domain1.   The
AmiTCP/IP system supports currently onlyone communication domain:  the
Internet domain, which is used by processes which communicate using the
the DARPA standard communication protocols.   The underlying communication
facilities provided by the domains havea significant influence on the internal
system implementation as well as the interface to socket facilities available
to a user.



3.1.1   Socket  Types

Sockets are typed according to the communication properties visible to a
user.  Processes are presumed to communicate only between sockets of the
same type, although there is nothing that prevents communication between
________________________________
   1It may be possible to cross domain boundaries, but only if some

translation process is performed.



                                      27


28    Section 3.1                  AmiTCP/IP                   System Manual



sockets of different types should the underlying communication protocols
support this.
   Three types of sockets currently are available to a user.  A stream
socket provides for the bidirectional, reliable, sequenced, and
unduplicated flow of data without recordboundaries.   Aside from the
bidirectionality of data flow, a pair ofconnected stream sockets

provides an interface nearly identical to that of pipes.2
   A datagram socket supports bidirectional flow of data which is not
promised to be sequenced, reliable, or unduplicated.  That is, a process
receiving messages on a datagram socketmay find messages duplicated,
and, possibly, in an order different from the order in which it was sent.
An important characteristic of a datagram socket is that record
boundaries in data are preserved.  Datagram sockets closely model the
facilities found in many contemporary packet switched networks such as
the Ethernet.
   A raw socket provides users access to the underlying communication
protocols which support socket abstractions.   These sockets are normally
datagram oriented, though their exact characteristics are dependent on
the interface provided by the protocol.  Raw sockets are not intended for
the general user; they have been provided mainly for those interested in
developing new communication protocols,or for gaining access to some of
the more esoteric facilities of an existing protocol.  The use of raw
sockets is considered in section 3.4.
   Another potential socket type which has interesting properties is the
reliably delivered message socket.  The reliably delivered message socket
has similar properties to a datagram socket, but with reliable delivery.
There is currently no support for this type of socket, but a reliably
delivered message protocol similar to Xerox's Packet Exchange Protocol
(PEX) may be simulated at the user level.   More information on this topic
can be found in section 3.4.



3.1.2   Using The Socket Library

As any other Amiga shared library the bsdsocket.library must be opened to
be able to access the functions in the library.   Thiscan be done with
Exec's OpenLibrary() call.  The call returns a librarybase pointer which
is task specfic, which means that each separate task (or process) must
open the library itself.  This is because the AmiTCP/IPstores task
specific information to the library basestructure.
   The library base pointer returned by the OpenLibrary() must be stored
in to a variable accessable from the program (usually global) named
SocketBase.  Example of opening the library follows:


#include <exec/libraries.h>
 ...
struct Library *SocketBase = NULL;
 ...
    if ((SocketBase = OpenLibrary("bsdsocket.library", 2)) == NULL) -
________________________________
   2In the UNIX systems pipes havebeen implemented internally as simply

a pair of connected stream sockets.


System Manual                   AmiTCP/IP                   Section 3.1    29



         /* couldnot open the library */
          ...
    "
    else -
         /* SocketBase now points to socket base of this task */
          ...
    "


   Note thatthe library version argument of the OpenLibrary() call is
given as 2, which means that at least version 2 is needed.  This is the
minimum version which should be requested, since the version 1 is
incompatible with the version 2 and up.  If the application uses features
defined for some specific version (and up), a later version number should
be specified.
   After theapplication is done with sockets the library must be closed.
This is done with CloseLibrary() as follows:


    if (SocketBase) -
         CloseLibrary(SocketBase);
         SocketBase = NULL;
    "


   Note thatif the application in question is multithreaded, each task
(or process) need to open/close its ownlibrary base.  The base opened by
the net.lib may be used by the originaltask only!
   Many programs expect the error values of the socket calls to be placed
in a global variable named errno.  By default a sharedlibrary cannot
know the address (nor size) of the applications variables, however.
There are two remedies to this:


 1. Use function Errno() to retrieve the error value, or


 2. Tell the address and the size of the errno variable to the AmiTCP/IP
    by using the SetErrnoPtr() call.


   The latter method requires only one additional function call to the
startup of the application, and is thusthe preferred method.  The call
may look like:


#include <errno.h>
#include <sys/socket.h>
 ...
    SetErrnoPtr(&errno, sizeof(errno));


   All thisis done automatically for the application if it is linked with

the net.lib3.  See section 3.1.3 for more information about the net.lib
and about compiling and linking the applications.
________________________________
   3The net.lib is compiler dependent and is currently defined for SASC 6

only.  The actual name of the library varies and depends on the compiler
options used.


30    Section 3.1                  AmiTCP/IP                   System Manual



3.1.3   Compiling and Linking The Applications

AmiTCP/IP provides standard BSD Unix header files to be used by the
applications.  Normally they are installed to a directory which is
assigned to a name NETINCLUDE: (see section 1.1).   This means that you
should add the NETINCLUDE: to the compilers search path for include
files.
   The include files are decribed briefly in the following subsection:



The NETINCLUDE Header Files

bsdsocket.h  This file includes compiler specific prototypes and inline
    functions for bsdsocket.library.  Currently supported compilers are
    GCC and SAS C version 6.  The prototypes for the library functions
    are automatically included by the include files when appropriate,
    i.e.  when the prototypes where declared in the original BSD
    includes.  Thus the bsdsocket.h is included by sys/socket.h, netdb.h
    and arpa/inet.h.

    For other compilers only C prototypes are included, so stub routines
    should be used to call the functions.

errno.h Replacement for the errno.h included in the standard C-compiler
    headers.  This includes the file sys/errno.h, which defines symbolic
    constants for the error values returned by socket library calls.
    This file is BSD compatible and may well replace file provided by the
    SAS/C 6.

netdb.h Contains definitions and prototypes for the network database
    functions, such as the gethostbyname().

 Standard BSD System Headers


    sys/errno.h  Error code definitions for system functions.

    sys/ioctl.h  Definitions for socket IO control.

    sys/param.h  General machine independent parameter definitions.

    sys/socket.h  Definitions related to sockets:  types, address
        families, options and prototypes.

    sys/syslog.h  Definations for system logging facilities.

    sys/time.h  Definition of structure timeval.

    sys/types.h  Common C type definitions and file descriptorset macros
        for select().


 Internet Related Headers


    arpa/inet.h  Inet library function prototypes (inet_addr() etc.).
        Included for compatibility and only includes other include files.

    netinet/in.h  Protocol numbers, port conventions, inet address
        definitions.

    netinet/in_systm.h  Some network byte order type definitions.

    netinet/ip.h  IP packet header, packet options, timestamp.


System Manual                   AmiTCP/IP                   Section 3.1    31



    netinet/ip_icmp.h  ICMP packet structure.

    netinet/ip_var.h  Defines IP statistics, external IP packet header,
        reassemble queues structures.

    netinet/tcp.h  Defines the TCP packet structure.

    netinet/udp.h  Defines the UDP packet structure.


 Network Related Headers

    net/if.h  Defines the interface for network adapter drivers.

    net/if_arp.h  General protocol independent ARP structures.

    net/route.h  Routing ioctl definitions.

    net/sana2errno.h  Sana-II related error definitions.

    net/sana2tags.h  Tag definitions for configuring the Sana-II software
        network interface.

 Inetd Support

    inetd.h  Internet daemon interface definitions.

    inetdlib.h  Internet daemon library definitions.

 Prototypes

    clib/socket_inlines.h   Inline function definitions for those BSD
        socket API functions, which are not implemented strictly like
        originals by bsdsocket.library.

    clib/socket_protos.h  bsdsocket.library function call prototypes.

 SAS/C Pragmas

    pragmas/socket_pragmas.h   SAS/C pragma library calls for
        bsdsocket.library.

 SAS/C Proto -file

    proto/socket.h  Include file normally included by the SAS/C programs.
        Defines the socket base variable and includes the files
        clib/socket_protos.h and pragmas/socket_pragmas.h.

 GCC Inline Functions

    inline/socket.h  GCC inline functions for the bsdsocket.library
        functions.

 Function Description File

    fd/socket_lib.fd  Standard fd-file which specifies in which registers
        the arguments to the bsdsocket.library functions are passed.
        This file can be used to obtain information needed to call the
        bsdsocket.library functions by the assembler programs.

 Sana-II Header Files

    devices/sana2.h  Definitions for the Sana-II network device driver
        interface.


32    Section 3.1                  AmiTCP/IP                   System Manual



    devices/sana2specialstats.h   Special statistics definitions for the
        Sana-II.

 Miscellaneous

    charread.h  Macro package to do buffered byte-by-byte reading from a
        socket.

    lineread.h  Definitions for buffered line orientedreading from a
        socket.



Linking With net.lib

AmiTCP/IP distribution includes a link library named net.lib to be used
by the applications.  It is normally located in the directory which has
an assigned name NETLIB:.
   The library contains compiler dependent code which makes the library

itself compiler dependent.  Currently only SASC version6 is supported4.
   net.lib features automatic initialization and termination functions
which open and close the bsdsocket.library for the application.  Using
this feature it is possible to compile some typical BSD Unix socket based
applications with AmiTCP/IP without anymodifications to the original
source code.  Note that this base may be used by the process starting the
program, i.e.  the one that executes themain().  This applies to the
included utility functions which call the socket library, too.
   The library also defines new array of error names to be used by
perror() library function.  This is done because the error name array
normally used by Amiga C compilers doesnot contain enough error entries,
resulting perror() to print "Unknown error code" if some socket error is
passed.  Note that for perror() to work the error valuemust be placed
into the global errno variable.  This is accomplished by the
SetErrnoPrt() call made in the automaticinitialization function.
   For the library functions to take effect, the library must be specified
before the C compiler own libraries in the link command line.



3.1.4   Socket  Creation

To create a socket the socket() system call is used:

    s = socket(domain, type, protocol);

This call requests that the system create a socket in the specified
domain and of the specified type.  A particular protocol may also be
requested.  If the protocol is left unspecified (a value of 0), the
system will select an appropriate protocol from those protocols which
comprise the communication domain and which may be used to support the
requested socket type.  The user is returned a descriptor (a small
integer number) which may be used in later system calls which operate on
sockets.  The domain is specified as one of the manifest constants
________________________________
   4But since the source for the library is provided, it can be used with

any C compiler.


System Manual                   AmiTCP/IP                   Section 3.1    33



defined in the file sys/socket.h.  For the Internet domain the constant

is AF_INET5. The socket types are also defined in this file and one of
SOCK_STREAM, SOCK_DGRAM or SOCK_RAW mustbe specified.  To create a stream socket
in the Internet domain the following call might be used:

    s = socket(AF_INET, SOCK_STREAM, 0);

This call would result in a stream socket being created with the TCP
protocol providing the underlying communication support.  To create a
datagram socket the call might be:

    s = socket(AF_INET, SOCK_DGRAM, 0);

   The default protocol (used when the protocol argument to the socket()
call is 0) should be correct for most every situation.  However, it is
possible to specify a protocol other than the default; this will be
covered in section 3.4.
   There areseveral reasons a socket() call may fail.  Aside from the
rare occurrence of lack of memory (ENOBUFS), a socket request may fail
due to a request for an unknown protocol(EPROTONOSUPPORT), or a request
for a type of socket for which there isno supporting protocol
(EPROTOTYPE).



3.1.5   Binding Local Names

A socket is created without a name.  Until a name is bound to a socket,
processes have no way to reference it and, consequently, no messages may
be received on it.  Communicating processes are bound by an association.
In the Internet domain, an association is composed of local and foreign
addresses, and local and foreign ports,In most domains, associations
must be unique.  In the Internet domain there may neverbe duplicate
<protocol, local address, local port, foreign address, foreign port>
tuples.
   The bind() system call allows a process to specify half of an
association, <local address, local port>, while the connect() and
accept() calls are used to complete a socket's association.
   In the Internet domain, binding names to sockets can be fairly complex.
Fortunately, it is usually not necessaryto specifically bind an address
and port number to a socket, because theconnect() and send() calls will
automatically bind an appropriate address if they are used with an
unbound socket.
   The bind() system call is used as follows:

    bind(s, name, namelen);

The bound name is a variable length bytestring which is interpreted by
the supporting protocol(s).  Its interpretation may vary from
communication domain to communication domain (this is one of the
properties which comprise the domain).  As mentioned, in the Internet
domain names contain an Internet addressand port number.
   In binding an Internet address things are a little complicated:
________________________________
   5The manifest constants are named AF _whatever as they indicate the

``address format'' to use in interpreting names.


34    Section 3.1                  AmiTCP/IP                   System Manual



    #include <sys/types.h>
    #include <netinet/in.h>
     ...
    struct sockaddr_in sin;
     ...
    bind(s, (struct sockaddr *) &sin, sizeof (sin));

The selection of what to place in the address sin requires some
discussion.  We will come back to the problem of formulating Internet
addresses in section 3.2 when the library routines used in name
resolution are discussed.



3.1.6   Connection Establishment

Connection establishment is asymmetric,with one process a ``client'' and
the other a ``server''.  The server, when willing to offer its advertised
services, binds a socket to a well--known address associated with the
service and then passively ``listens'' on its socket.  It is then
possible for an unrelated process to rendezvous with the server.  The
client requests services from the serverby initiating a ``connection''
to the server's socket.  On the client side the connect() call is used to
initiate a connection.  Using the Internet domain, thismight apper as:

    struct sockaddr_in server;
     ...
    connect(s, (struct sockaddr *)&server, sizeof (server));

   where server in the example above would contain Internet address and
port number of the server to which the client process wishes to speak.
If the client process's socket is unbound at the time of the connect
call, the system will automatically select and bind a name to the socket
if necessary.  This is the usual way that local addresses are bound to a
socket.
   An erroris returned if the connection was unsuccessful (any name
automatically bound by the system, however, remains).  Otherwise, the
socket is associated with the server anddata transfer may begin.  Some
of the more common errors returned whena connection attempt fails are:


 ETIMEDOUT After failing to establish a connection for a period of time,
    the system decided there was no point in retrying the connection
    attempt any more.  This usually occurs because the destination host
    is down, or because problems in the network resulted in transmissions
    being lost.

 ECONNREFUSED The host refusedservice for some reason.  This is usually
    due to a server process not being present at the requested name.

 ENETDOWN or EHOSTDOWN These operational errors are returned based on
    status information delivered to the client host by the underlying
    communication services.

 ENETUNREACH or EHOSTUNREACH These operational errors can occur either
    because the network or host is unknown (no route to the network or


System Manual                   AmiTCP/IP                   Section 3.1    35



    host is present), or because of status information returned by
    intermediate gateways or switching nodes.  Many times the status
    returned is not sufficient to distinguish a network being down from a
    host being down, in which case the system indicates the entire
    network is unreachable.


   For the server to receive a client's connection it must perform two
steps after binding its socket.  The first is to indicate a willingness
to listen for incoming connection requests:


    listen(s, 5);


The second parameter to the listen() call specifies the maximum number of
outstanding connections which may be queued awaiting acceptance by the
server process; this number may be limited by the system.  Should a
connection be requested while the queueis full, the connection will not
be refused, but rather the individual messages which comprise the request
will be ignored.  This gives a harried server time to make room in its
pending connection queue while the client retries the connection request.
Had the connection been returned with the ECONNREFUSED error, the client
would be unable to tell if the server was up or not.  As it is now it is
still possible to get the ETIMEDOUT error back, though this is unlikely.
The backlog figure supplied with the listen call is currently limited by the
system to a maximum of 5 pending connections on any one queue.  This avoids
the problem of processes hogging systemresources by setting an infinite backlog,
then ignoring all connection requests.
   With a socket marked as listening, a server may accept a connection:


    struct sockaddr_in from;
     ...
    fromlen = sizeof (from);
    newsock = accept(s, (struct sockaddr *)&from, &fromlen);


A new descriptor is returned on receiptof a connection (along with a new
socket).  If the server wishes to find out who its client is, it may
supply a buffer for the client socket'sname.   The value--result
parameter fromlen is initialized by theserver to indicate how much space
is associated with from, then modified on return to reflect the true size
of the name.  If the client's name is not of interest,the second
parameter may be a NULL pointer.
   accept()normally blocks.  That is, accept() will not return until a

connection is available or the system call is interrupted by a signal6 to
the process.  Further, there is no way for a process toindicate it will
accept connections from only a specificindividual, or individuals.  It
is up to the user process to consider who the connection is from and
close down the connection if it does notwish to speak to the process.
If the server process wants to accept connections on more than one
socket, or wants to avoid blocking on the accept call, there are
alternatives; they will be considered insection 3.4.
________________________________
   6By default, the CTRL-C signalinterrupts the system calls, but the

application may change this, however.


36    Section 3.1                  AmiTCP/IP                   System Manual



3.1.7   Data  Transfer


With a connection established, data maybegin to flow.  To send and
receive data there are a number of possible calls.   With the peer entity
at each end of a connection anchored, auser can send or receive a
message without specifying the peer.  The calls send()and recv() may be
used:


    send(s, buf, sizeof (buf), flags);
    recv(s, buf, sizeof (buf), flags);


While send() and recv() are virtually identical to the standard I/O
routines, the extra flags argument is important.   Theflags, defined in
sys/socket.h, may be specified as a non--zero value if one or more of the
following is required:


 MSG_OOB Send/receive out of band data.


 MSG_PEEK Lookat data without reading.


 MSG_DONTROUTESend data without routing packets.


   Out of band data is a notion specific to stream sockets, and one which
we will not immediately consider.  The option to have data sent without
routing applied to the outgoing packetsis currently used only by the
routing table management process, and isunlikely to be of interest to
the casual user.  The ability to preview data is, however, of interest.
When MSG_PEEK is specified with a recv() call, any data present is
returned to the user, but treated as still ``unread''.  That is, the next
recv() call applied to the socket will return the data previously
previewed.



3.1.8   Discarding Sockets


Once a socket is no longer of interest,it may be discarded by applying a
CloseSocket() to the descriptor,


    CloseSocket(s);


If data is associated with a socket which promises reliable delivery
(e.g.  a stream socket) when a close takes place, the system will
continue to attempt to transfer the data.   However, after a fairly long
period of time, if the data is still undelivered, it will be discarded.
Should a user have no use for any pending data, it may perform a
shutdown() on the socket prior to closing it.   This call is of the form:


    shutdown(s, how);


where how is 0 if the user is no longerinterested in reading data, 1 if
no more data will be sent, or 2 if no data is to be sent or received.


System Manual                   AmiTCP/IP                   Section 3.1    37



3.1.9   Connectionless Sockets

To this point we have been concerned mostly with sockets which follow a
connection oriented model.  However, there is also support for
connectionless interactions typical of the datagram facilities found in
contemporary packet switched networks.  A datagram socket provides a
symmetric interface to data exchange.  While processesare still likely
to be client and server, there is no requirement for connection
establishment.  Instead, each message includes the destination address.
   Datagramsockets are created as before.  If a particular local address
is needed, the bind operation must precede the first data transmission.
Otherwise, the system will set the localaddress and/or port when data is
first sent.  To send data, the sendto() call is used,

    sendto(s, buf, buflen, flags, (struct sockaddr *)&to, tolen);

The s, buf, buflen, and flags parametersare used as before.  The to and
tolen values are used to indicate the address of the intended recipient
of the message.  When using an unreliable datagram interface, it is
unlikely that any errors will be reported to the sender.  When
information is present locally to recognize a message that can not be
delivered (for instance when a network is unreachable), the call will
return -1 and the global value errno will contain an error number (See
section 3.1.2 for discussion about errno).
   To receive messages on an unconnected datagram socket, the recvfrom()
call is provided:

    recvfrom(s, buf, buflen, flags, (struct sockaddr *)&from, &fromlen);

Once again, the fromlen parameter is handled in a value--result fashion,
initially containing the size of the from buffer, and modified on return
to indicate the actual size of the address from which the datagram was
received.
   In addition to the two calls mentioned above, datagram sockets may also
use the connect() call to associate a socket with a specific destination
address.  In this case, any data sent on the socket will automatically be
addressed to the connected peer, and only data received from that peer
will be delivered to the user.  Only one connected address is permitted
for each socket at one time; a second connect() will change the
destination address, and a connect() toa null address (family AF_UNSPEC)
will disconnect.  Connect requests on datagram socketsreturn
immediately, as this simply results in the system recording the peer's
address (as compared to a stream socket,where a connect request
initiates establishment of an end to endconnection).  accept() and listen()
are not used with datagram sockets.
   While a datagram socket is connected, errors from recent send() calls
may be returned asynchronously.  These errors may be reported on
subsequent operations on the socket, ora special socket option used with
getsockopt(), SO_ERROR,may be used to interrogate the error status.  A
select() for reading or writing will return true when an error indication
has been received.  The next operation will return theerror, and the
error status is cleared.  Other of the less important details of datagram
sockets are described in section 3.4.


38    Section 3.1                  AmiTCP/IP                   System Manual



3.1.10   Input/Output  Multiplexing

One last facility often used in developing applications is the ability to
multiplex i/o requests among multiple sockets.   This is done using the
select() call.  The select() call provided by AmiTCP/IPis actually a
compile time inline function (or normalstub with compilers without
inline facility) which calls the WaitSelect().   The WaitSelect() call is
similar to the normal select() call, buthas one extra argument
specifying a pointer to a signal mask for the signals which should break
the selection (in addition to the timeouts and the break signal).  This
makes possible to use WaitSelect() instead of normal Wait() as a driver
for the applications event loop.  If the pointer is given as NULL the
functionality is as with BSD select().  The inline (orstub) function for select*
 *()
actually just calls the WaitSelect() with last argument as NULL.
   Here is abrief example of the usage of the WaitSelect():


    #include <sys/time.h>
    #include <sys/types.h>
     ...


    fd_set readmask, writemask, exceptmask;
    struct timeval timeout;
    ULONG signalmask;
     ...
    WaitSelect(nfds, &readmask, &writemask, &exceptmask, &timeout,
                &signalmask);


WaitSelect() takes as arguments pointersto three sets, one for the set
of file descriptors for which the callerwishes to be able to read data
on, one for those descriptors to which data is to be written, and one for
which exceptional conditions are pending; out-of-band data is the only
exceptional condition currently implemented.   If the user is not
interested in certain conditions (i.e.,read, write, or exceptions), the
corresponding argument to the select() should be a NULL pointer.
   Each setis actually a structure containing an array of long integer
bit masks; the size of the array is setby the definition FD_SETSIZE. The
array is long enough to hold one bit foreach of FD_SETSIZE file
descriptors.
   The macros FD_SET(fd, &mask) and FD_CLR(fd, &mask) have been provided
for adding and removing file descriptorfd in the set mask.  The set
should be zeroed before use, and the macro FD_ZERO(&mask) has been
provided to clear the set mask.  The parameter nfds inthe select() call
specifies the range of file descriptors(i.e.   one plusthe value of the
largest descriptor) to be examined in aset.
   A timeoutvalue may be specified if the selection is not to last more
than a predetermined period of time.  If the fields intimeout are set to
0, the selection takes the form of a poll, returning immediately.  If the

last parameter is a NULL pointer, the selection will block indefinitely7.
________________________________
   7To be more specific, a returntakes place only when a descriptor is

selectable, or when a signal is receivedby the caller, interrupting the
system call.


System Manual                   AmiTCP/IP                   Section 3.1    39



   The lastargument is a pointer to the mask specifying signals for which
the WaitSelect() should break.  WaitSelect() normally returns the number
of file descriptors selected; if the WaitSelect() call returns due to the
timeout expiring, then the value 0 is returned.   If the WaitSelect()
terminates because of an error or interruption, a -1 is returned with the
error number in errno, and with the filedescriptor masks unchanged.  The
signal mask is altered on return to holdthe bits for the signals which
caused the break.
   Assuminga successful return, the three sets will indicate which file
descriptors are ready to be read from, written to, or have exceptional
conditions pending.  The status of a file descriptor ina select mask may
be tested with the FD_ISSET(fd, &mask) macro, which returns a non-zero
value if fd is a member of the set mask,and 0 if it is not.
   To determine if there are connections waiting on a socket to be used
with an accept() call, select() can be used, followed by a
FD_ISSET(fd, &mask) macro to check for read readiness on the appropriate
socket.  If FD_ISSET() returns a non-zero value, indicating permission to
read, then a connection is pending on the socket.
   As an example, to read data from two sockets, s1 and s2 as it is
available from each and with a one--second timeout, the following code
might be used:


    #include <sys/time.h>
    #include <sys/types.h>
    #include <sys/socket.h>
     ...
    fd_set read_template;
    struct timeval wait;
    int nb;
    int s1,s2;
    int maxfd;
     ...
    maxfd = s1 > s2 ? s1 : s2;
    for (;;) -
         wait.tv_sec = 1;         /* onesecond */
         wait.tv_usec = 0;


         FD_ZERO(&read_template);


         FD_SET(s1,  &read_template);
         FD_SET(s2,  &read_template);


         nb = select(maxfd, &read_template, NULL, NULL, &wait);
         if (nb <=0) -
             /* An error occurred during the select, or
                the select timed out. */
         "


         if (FD_ISSET(s1, &read_template)) -
             /* Socket #1 is ready to be readfrom. */
         "


         if (FD_ISSET(s2, &read_template)) -
             /* Socket #2 is ready to be readfrom. */


40    Section 3.2                  AmiTCP/IP                   System Manual



         "
    "


   Note theusage of the select(), which calls WaitSelect() with NULL
signal mask pointer.
   In 4.2BSD, the arguments to select() were pointers to integers instead
of pointers to fd_sets.  This type ofcall will still work as long as the
number of file descriptors being examined is less than the number of bits
in an integer; however, the methods illustrated above should be used in
all current programs.
   select()provides a synchronous multiplexing scheme.  Asynchronous
notification of output completion, inputavailability, and exceptional
conditions is possible through use of the SigIO and SigURG signals
described in section 3.4.



3.2     Network  Library  Routines


The discussion in section 3.1 indicatedthe possible need to locate and
construct network addresses when using the interprocess communication
facilities in a distributed environment.  To aid in this task a number of
routines have been added to the Amiga shared socket library.  In this
section we will consider the routines provided to manipulate network
addresses.
   Locatinga service on a remote host requires many levels of mapping
before client and server may communicate.   A service is assigned a name
which is intended for human consumption;e.g.   ``the login server on host
monet''.  This name, and the name of the peer host, must then be
translated into network addresses whichare not necessarily suitable for
human consumption.  Finally, the address must then usedin locating a
physical location and route to the service.   The specifics of these three
mappings are likely to vary between network architectures.  For instance,
it is desirable for a network to not require hosts to be named in such a
way that their physical location is known by the client host.  Instead,
underlying services in the network may discover the actual location of the
host at the time a client host wishes tocommunicate.  This ability to have
hosts named in a location independent manner may induce overhead in connection
establishment, as a discovery process must take place, but allows a host to
be physically mobile without requiring it to notify its clientele of its current
location.
   Standardroutines are provided for:  mapping host names to network
addresses, network names to network numbers, protocol names to protocol
numbers, and service names to port numbers and the appropriate protocol
to use in communicating with the serverprocess.   The file netdb.h must
be included when using any of these routines.



3.2.1   Host  Names


An Internet host name to address mappingis represented by the hostent
structure:


System Manual                   AmiTCP/IP                   Section 3.2    41



    struct  hostent -
         char    *h_name;         /* official name of host */
         char    **h_aliases;     /* alias list */
         int     h_addrtype;      /* host address type (e.g., AF_INET) */
         int     h_length;       /* length of address */
         char    **h_addr_list;  /* list of addresses, nullterminated */
    ";


    #define h_addr  h_addr_list[0]  /* first address, network byte order */


   The routine gethostbyname() takes an Internet host name and returns a
hostent structure, while the routine gethostbyaddr() maps Internet host
addresses into a hostent structure.
   The official name of the host and its public aliases are returned by
these routines, along with the address type (family) and a null
terminated list of variable length addresses.   This list of addresses is
required because it is possible for a host to have many addresses, all
having the same name.  The h_addr definition is provided for backward
compatibility, and is defined to be thefirst address in the list of
addresses in the hostent structure.
   The database for these calls is provided either by the configuration
file or by use of a name server.  Because of the differences in these
databases and their access protocols, the information returned may
differ.  When using the host table version of gethostbyname(), only one
address will be returned, but all listedaliases will be included.  The
name server version may return alternateaddresses, but will not provide
any aliases other than one given as argument.



3.2.2   Network  Names

As for host names, routines for mappingnetwork names to numbers, and
back, are provided.  These routines return a netent structure:


    /*
     * Assumption here is that a network number
     * fits in 32 bits -- probably a poor one.
     */
    struct  netent -
         char    *n_name;         /* official name of net */
         char    **n_aliases;     /* alias list */
         int     n_addrtype;      /* net address type */
         int     n_net;           /* networknumber, host byte order */
    ";


   The routines getnetbyname(), andgetnetbynumber() are the network
counterparts to the host routines described above.   The routines uses
data read from AmiTCP/IP configuration file.



3.2.3   Protocol Names

For protocols, the protoent structure defines the protocol--name mapping
used with the routines getprotobyname()and getprotobynumber():


42    Section 3.2                  AmiTCP/IP                   System Manual



    struct  protoent -
         char    *p_name;         /* official protocol name */
         char    **p_aliases;     /* alias list */
         int     p_proto;         /* protocol number */
    ";



3.2.4   Service  Names


Information regarding services is a bitmore complicated.  A service is
expected to reside at a specific ``port'' and employ a particular
communication protocol.  This view is consistent with the Internet
domain, but inconsistent with other network architectures.  Further, a
service may reside on multiple ports.  If this occurs,the higher level
library routines will have to be bypassed or extended.  A service mapping
is described by the servent structure:



    struct  servent -
         char    *s_name;         /* official service name */
         char    **s_aliases;     /* alias list */
         int     s_port;          /*port number, network byte order */
         char    *s_proto;       /* protocol to use */
    ";


   The routine getservbyname() maps service names to a servent structure
by specifying a service name and, optionally, a qualifying protocol.
Thus the call


    sp = getservbyname("telnet", NULL);


returns the service specification for atelnet server using any protocol,
while the call


    sp = getservbyname("telnet", "tcp");


returns only that telnet server which uses the TCP protocol.  The routine
getservbyport() is also provided.  The getservbyport()routine has an
interface similar to that provided by getservbyname(); an optional
protocol name may be specified to qualify lookups.



3.2.5   Miscellaneous


With the support routines described above, an Internet application
program should rarely have to deal directly with addresses.  This allows
services to be developed as much as possible in a network independent
fashion.  It is clear, however, that purging all network dependencies is
very difficult.  So long as the user is required to supply network
addresses when naming services and sockets there will always some network
dependency in a program.  For example, the normal codeincluded in client
programs, such as the remote login program, is as follows:


System Manual                   AmiTCP/IP                   Section 3.2    43



Remote Login Client Code

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdio.h>
    #include <netdb.h>
     ...
    int main(int argc, char *argv[])
    -
            struct sockaddr_in server;
            struct servent *sp;
            struct hostent *hp;
            int s;
             ...
            sp = getservbyname("login","tcp");
            if (sp == NULL) -
               fprintf(stderr, "rlogin: tcp/login: unknown service"n");
               exit(1);
            "
            hp = gethostbyname(argv[1]);
            if (hp == NULL) -
               fprintf(stderr, "rlogin: %s: unknown host"n",argv[1]);
               exit(2);
            "
            bzero((char *)&server, sizeof (server));
            server.sin_port = sp->s_port;
            bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
            server.sin_family = hp->h_addrtype;


            s = socket(AF_INET, SOCK_STREAM, 0);
            if (s < 0) -
               perror("rlogin: socket");
               exit(3);
            "
             ...
            /* Connect does the bind()for us */


            if (connect(s, (struct sockaddr *)&server, sizeof (server)) < 0) -
               perror("rlogin: connect");
               exit(5);
            "
             ...
    "



   (This example will be considered in more detail in section 3.3.)



  If we wanted to make the remote login program independent of the
Internet protocols and addressing schemewe would be forced to add a
layer of routines which masked the network dependent aspects from the
mainstream login code.  For the current facilities available in the
system this does not appear to be worthwhile.
   Aside from the address-related data base routines, there are several
other routines available in the run-timelibrary which are of interest to


44    Section 3.3                  AmiTCP/IP                   System Manual



users.  These are intended mostly to simplify manipulation of names and
addresses.  The routines for manipulating variable length byte strings
and handling byte swapping of network addresses and values are summarized

below:8.


bcmp(s1, s2, n)

    Compare byte-strings; 0 if same, not 0 otherwise.

bcopy(s1, s2, n)

    Copy n bytes from s1 to s2.

bzero(base, n)

    Zero-fill n bytes starting at base.

htonl(val)

    Convert 32-bit quantity from host to network byte order.

htons(val)

    Convert 16-bit quantity from host to network byte order.

ntohl(val)

    Convert 32-bit quantity from network to host byte order.

ntohs(val)

    Convert 16-bit quantity from network to host byte order.


   The byteswapping routines are provided because the operating system
expects addresses to be supplied in network order.   Onsome
architectures, such as the VAX, host byte ordering is different than
network byte ordering.  Consequently, programs are sometimes required to
byte swap quantities.  The library routines which return network
addresses provide them in network orderso that they may simply be copied
into the structures provided to the system.   This implies users should
encounter the byte swapping problem onlywhen interpreting network
addresses.  For example, if an Internet port is to be printed out the
following code would be required:

    printf("port number %d"n", ntohs(sp->s_port));

On machines where unneeded (as on Amiga)these routines are defined as
null macros.



3.3     Client/Server Model


The most commonly used paradigm in constructing distributed applications
is the client/server model.  In this scheme client applications request
services from a server process.  This implies an asymmetry in
establishing communication between the client and server which has been
________________________________
   8The byte string functions areprovided by the C-compiler.  The byte

order functions are provided as preprocessor macros.


System Manual                   AmiTCP/IP                   Section 3.3    45



examined in section 3.1.  In this section we will lookmore closely at
the interactions between client and server, and consider some of the
problems in developing client and serverapplications.
   The client and server require a well known set of conventions before
service may be rendered (and accepted).  This set of conventions
comprises a protocol which must be implemented at both ends of a
connection.  Depending on the situation, the protocol may be symmetric or
asymmetric.  In a symmetric protocol, either side may play the master or
slave roles.  In an asymmetric protocol, one side is immutably recognized
as the master, with the other as the slave.   An example of a symmetric
protocol is the TELNET protocol used inthe Internet for remote terminal
emulation.  An example of an asymmetric protocol is theInternet file
transfer protocol, FTP. No matter whether the specific protocol used in
obtaining a service is symmetric or asymmetric, when accessing a service there
is a ``client process'' and a ``server process''.   Wewill first consider the
properties of server processes, then client processes.
   A serverprocess normally listens at a well known address for service
requests.  That is, the server process remains dormantuntil a connection
is requested by a client's connection tothe server's address.  At such a
time the server process ``wakes up'' andservices the client, performing
whatever appropriate actions the clientrequests of it.
   Alternative schemes which use a service server may be used to eliminate
a flock of server processes clogging thesystem while remaining dormant
most of the time.  For Internet servers in 4.3BSD, thisscheme has been
implemented via inetd, the so called ``internet super-server.''  Inetd
listens at a variety of ports, determined at start-up by reading a
configuration file.  When a connection is requested toa port on which
inetd is listening, inetd executes the appropriate server program to
handle the client.  Inetd will be described in more detail in section
3.4.



3.3.1   Servers

In 4.3BSD most servers are accessed at well known Internet addresses or
UNIX domain names.  For example, the remote login server's main loop is
of the form shown below (AmiTCP/IP way):


    main(int argc, char *argv)
    -
         int f;
         struct sockaddr_in from;
         struct servent *sp;


         sp = getservbyname("login", "tcp");
         if (sp ==NULL) -
             fprintf(stderr, "rlogind: tcp/login: unknown service"n");
             exit(1);
         "
          ...


         sin.sin_port = sp->s_port;  /* Restricted port */
          ...


46    Section 3.3                  AmiTCP/IP                   System Manual



         f = socket(AF_INET, SOCK_STREAM, 0);
          ...
         if (bind(f, (struct sockaddr *) &sin, sizeof (sin)) < 0) -
          ...
         "
          ...
         listen(f, 5);
         for (;;)-
             int g, len = sizeof (from);


             g = accept(f, (struct sockaddr *)&from, &len);
             if (g < 0) -
                 if (errno != EINTR)
                      syslog(LOG_ERR, "rlogind: accept: %s", errors[errno]);
                 continue;
             "
             /*
              * AmiTCP code follows...
              */
             id = ReleaseSocket(g, UNIQUE_ID);
             startit(id, &from);
         "
    "

   The firststep taken by the server is look up its service definition:

    sp = getservbyname("login", "tcp");
    if (sp == NULL) -
         fprintf(stderr, "rlogind: tcp/login: unknown service"n");
         exit(1);
    "

The result of the getservbyname call isused in later portions of the
code to define the Internet port at which it listens for service requests
(indicated by a connection).
   Once a server has established a pristine environment, it creates a
socket and begins accepting service requests.   The bind() call is
required to insure the server listens atits expected location.
   The mainbody of the loop is fairly simple:

    for (;;) -
         int g, len = sizeof (from);


         g = accept(f, (struct sockaddr *)&from, &len);
         if (g < 0) -
             if (errno != EINTR)
                 syslog(LOG_ERR, "rlogind: accept: %s", errors[errno]);
             continue;
         "
         /*
          * AmiTCP code follows...
          */
         id = ReleaseSocket(g, UNIQUE_ID);
         startit(id,  &from);
    "


System Manual                   AmiTCP/IP                   Section 3.3    47



   An accept() call blocks the server until a client requests service.
This call could return a failure statusif the call is interrupted by a
signal such as CTRL-C (to be discussed in section 3.4).  Therefore, the
return value from accept() is checked toinsure a connection has actually
been established.
   With a connection in hand, servers using AmiTCP/IP socket library,
this new socket is released to an external list inside AmiTCP/IP process
via ReleaseSocket() call.  ReleaseSocket() returns an id (unique if
requested).  startit() starts a new AmigaOS task and informs the id for
it.  This new task then uses ObtainSocket() with id asargument to
receive the socket.  The address of the client is alsohandled the new
task because it requires it in authenticating clients.



3.3.2   Clients

The client side of the remote login service was shown earlier in section
3.2.  One can see the separate, asymmetric roles of theclient and server
clearly in the code.  The server is a passive entity, listening for
client connections, while the client process is an active entity,
initiating a connection when invoked.
   Let us consider more closely the steps taken by the client remote login
process.  As in the server process, the first step is to locate the
service definition for a remote login:


    sp = getservbyname("login", "tcp");
    if (sp == NULL) -
         fprintf(stderr, "rlogin: tcp/login: unknown service"n");
         exit(1);
    "

   Next thedestination host is looked up with a gethostbyname() call:


    hp = gethostbyname(argv[1]);
    if (hp == NULL) -
         fprintf(stderr, "rlogin: %s: unknown host"n", argv[1]);
         exit(2);
    "

With this accomplished, all that is required is to establish a connection
to the server at the requested host andstart up the remote login
protocol.  The address buffer is filled in with the Internet address and
rlogin port number of the foreign host.


    bzero((char *)&server, sizeof (server));
    server.sin_port = sp->s_port;
    bcopy(hp->h_addr, (char *) &server.sin_addr, hp->h_length);
    server.sin_family = hp->h_addrtype;

A socket is created, and a connection initiated.   Notethat connect()
implicitly performs a bind() call, because s is unbound.


    s = socket(hp->h_addrtype, SOCK_STREAM, 0);
    if (s < 0) -


48    Section 3.3                  AmiTCP/IP                   System Manual



         perror("rlogin: socket");
         exit(3);
    "
     ...
    if (connect(s, (struct sockaddr *) &server,
             sizeof (server)) < 0) -
         perror("rlogin: connect");
         exit(4);
    "

The details of the remote login protocolwill not be considered here.



3.3.3   Connectionless Servers

While connection-based services are thenorm, some services are based on
the use of datagram sockets.  One, in particular, is the ``rwho'' service
which provides users with status information for hosts connected to a
local area network.  This service, while predicated onthe ability to
broadcast information to all hosts connected to a particular network, is
of interest as an example usage of datagram sockets.
   A user onany machine running the rwho server may find out the current
status of a machine with the ruptime program.   The output generated is
illustrated below.



Ruptime Output

arpa         up   9:45,        5 users, load    1.15,    1.39,    1.31
cad          up    2+12:04,     8 users, load    4.67,    5.13,    4.59
calder       up    10:10,       0 users,load    0.27,    0.15,    0.14
dali         up   2+06:28,     9 users, load   1.04,    1.20,    1.65
degas       up    25+09:48,    0 users, load    1.49,    1.43,    1.41
ear          up    5+00:05,     0 users, load    1.51,    1.54,    1.56
ernie     down   0:24
esvax     down   17:04
ingres    down   0:26
kim          up    3+09:16,     8 users, load    2.03,    2.46,    3.11
matisse     up    3+06:18,    0 users, load    0.03,    0.03,    0.05
medea       up    3+09:39,     2 users,load    0.35,    0.37,    0.50
merlin    down   19+15:37
miro         up   1+07:20,     7 users, load   4.59,    3.28,    2.12
monet       up    1+00:43,     2 users,load    0.22,    0.09,    0.07
oz         down   16:09
statvax     up    2+15:57,    3 users, load    1.52,    1.81,    1.86
ucbvax      up    9:34,        2 users, load    6.08,   5.16,    3.28


   Status information for each host is periodically broadcast by rwho
server processes on each machine.  The same server process also receives
the status information and uses it to update a database.  This database
is then interpreted to generate the status information for each host.
Servers operate autonomously, coupled only by the local network and its
broadcast capabilities.
   Note thatthe use of broadcast for such a task is fairly inefficient,
as all hosts must process each message,whether or not using an rwho


System Manual                   AmiTCP/IP                   Section 3.3    49



server.  Unless such a service is sufficiently universal and is
frequently used, the expense of periodicbroadcasts outweighs the
simplicity.

   The rwhoserver, in a simplified form, is pictured next9:


    BYTE alrmsig;


    main()
    -
         long on;
         fd_set readfds;
          ...
         sp = getservbyname("who", "udp");
         sin.sin_port = sp->s_port;
         net = getnetbyname("localnet");
         sin.sin_addr = inet_makeaddr(INADDR_ANY, net);
          ...
         s = socket(AF_INET, SOCK_DGRAM, 0);
          ...
         on = 1;
         if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) -
             syslog(LOG_ERR, "rwhod: setsockopt SO_BROADCAST: %s",
                    strerror(errno));
             exit(1);
         "
         bind(s, (struct sockaddr *) &sin, sizeof (sin));
          ...
         alrmsig =AllocSignal(-1);
         onalrm();/* activate and handle periodic alarm system */


         FD_ZERO(&readfds);
         FD_SET(s, &readfds);


         for (;;)-
             struct whod wd;
             struct sockaddr_in from;
             int n, cc, whod, len = sizeof (from);
             ULONG alrmmask;


             alrmmask = 1 << alrmsig;
             n = WaitSelect(s, &readfds, NULL,NULL, NULL, &alrmmask);
             if (n < 0) -
                 syslog(LOG_ERR, "rwhod: WaitSelect: %s", strerror(errno));
                 exit(1);
             "
             if (alrmmask)
               onalrm(); /* handles the alarm */
             if (n > 0) -
                 cc = recvfrom(s, (char *)&wd, sizeof (wd), 0,
                                (struct sockaddr *)&from, &len);
                 if (cc <= 0) -
________________________________
   9A real code must always test the return values of various services

against errors.  Thes e tests are partly omitted from this code to show
the matters important to this section.


50    Section 3.3                  AmiTCP/IP                   System Manual



                      if (cc < 0)
                          syslog(LOG_ERR, "rwhod: recv: %s", strerror(errno));
                      continue;
                 "
                 if (from.sin_port != sin.sin_port) -
                      syslog(LOG_ERR, "rwhod: %ld: bad from port",
                             ntohs(from.sin_port));
                      continue;
                 "
                 ...
                 if (!verify(wd.wd_hostname)) -
                      syslog(LOG_ERR, "rwhod: malformed host name from %lx",
                             ntohl(from.sin_addr.s_addr));
                      continue;
                 "
                 (void) sprintf(path, "%s/whod.%s", RWHODIR, wd.wd_hostname);
                 whod = open(path, O_WRONLY _ O_CREAT _ O_TRUNC, 0666);
                 ...
                 (void) time(&wd.wd_recvtime);
                 (void) write(whod, (char *)&wd, cc);
                 (void) close(whod);
             "
         "
    "


   There aretwo separate tasks performed by the server.  The first task
is to act as a receiver of status information broadcast by other hosts on
the network.  This job is carried out in the main loopof the program.
Packets received at the rwho port are interrogated to insure they've been
sent by another rwho server process, then are time stamped with their
arrival time and used to update a file indicating the status of the host.
When a host has not been heard from foran extended period of time, the
database interpretation routines assumethe host is down and indicate
such on the status reports.  This algorithm is prone toerror as a server
may be down while a host is actually up,but serves our current needs.
   The second task performed by the server is to supply information
regarding the status of its host.  This involves periodically acquiring
system status information, packaging itup in a message and broadcasting
it on the local network for other rwho servers to hear.  The supply
function is triggered by a timer and runs off a signal.  Locating the
system status information is somewhat involved, but uninteresting.
Deciding where to transmit the resultantpacket is somewhat
problematical, however.
   Status information must be broadcast on the local network.  For
networks which do not support the notionof broadcast another scheme must
be used to simulate or replace broadcasting.   One possibility is to
enumerate the known neighbors (based onthe status messages received from
other rwho servers).  This, unfortunately, requires some bootstrapping
information, for a server will have no idea what machines are its
neighbors until it receives status messages from them.  Therefore, if all
machines on a net are freshly booted, nomachine will have any known
neighbors and thus never receive, or send, any status information.  This
is the identical problem faced by the routing table management process in


System Manual                   AmiTCP/IP                   Section 3.4    51



propagating routing status information.  The standard solution, unsatisfactory
as it may be, is to inform one or more servers of known neighbors and request
that theyalways communicate with these neighbors.   Ifeach server has at least
one neighbor supplied to it, status information may then propagate through
a neighbor to hosts which are not (possibly) directly neighbors.  If the server
is able to support networks which provide a broadcast capability, as well as
those which do not, then networks with an arbitrary topology may share status

information10
   It is important that software operating in a distributed environment
not have any site-dependent informationcompiled into it.  This would
require a separate copy of the server ateach host and make maintenance a
severe headache.  4.3BSD attempts to isolate host-specific information
from applications by providing system calls which return the necessary

information11.  A mechanism exists, in the form of an IoctlSocket() call,
for finding the collection of networks to which a host is directly
connected.  Further, a local network broadcasting mechanism has been
implemented at the socket level.  Combining these two features allows a
process to broadcast on any directly connected local network which
supports the notion of broadcasting in asite independent manner.  This allows
4.3BSD to solve the problem of decidinghow to propagate status information
in the case of rwho, or more generally in broadcasting:  Such status information
is broadcast to connected networks at the socket level, where the connected
networks have been obtained via the appropriate ioctl calls.  The specifics
of such broadcastings are complex, however, and will be covered in section
3.4.



3.4     Advanced Topics


A number of facilities have yet to be discussed.   Formost users of the
AmiTCP/IP the mechanisms already described will suffice in constructing
distributed applications.  However, others will find the need to utilize
some of the features which we consider in this section.



3.4.1   OutOf Band Data

The stream socket abstraction includes the notion of ``out of band''
data.  Out of band data is a logically independent transmission channel
associated with each pair of connected stream sockets.  Out of band data
is delivered to the user independently of normal data.  The abstraction
defines that the out of band data facilities must support the reliable
delivery of at least one out of band message at a time.  This message may
contain at least one byte of data, and at least one message may be
pending delivery to the user at any onetime.   For communications
protocols which support only in-band signaling (i.e.  the urgent data is
________________________________
  10One must, however, be concerned about loops.  That is, if a host is

connected to multiple networks, it willreceive status information from
itself.  This can lead to an endless, wasteful, exchange of information.
  11An example of such a system call is the gethostname() call which returns

the host's official name.


52    Section 3.4                  AmiTCP/IP                   System Manual



delivered in sequence with the normal data), the system normally extracts
the data from the normal data stream andstores it separately.  This allows
users to choose between receiving the urgent data in order and receiving it
out of sequence without having to bufferall the intervening data.  It is possib*
 *le
to ``peek'' (via MSG_PEEK) at out of band data.  If the socket has an owner,
a signal is generated when the protocolis notified of its existence.  A process
can set the task to be informed by a signal via the appropriate IoctlSocket()
and SetSocketSignals() calls, as described below in section 3.4.3.  If multiple
sockets may have out of band data awaiting delivery, a select() call for except*
 *ional
conditions may be used to determine those sockets with such data pending.  Neit*
 *her
the signal nor the select() indicate theactual arrival of the out-of-band
data, but only notification that it is pending.
   In addition to the information passed, a logical mark is placed in the
data stream to indicate the point at which the out of band data was

sent12.  The remote login and remote shell applications use this facility
to propagate signals between client andserver processes.  When a signal
flushs any pending output from the remote process(es), all data up to the
mark in the data stream is discarded.
   To send an out of band message the MSG_OOB flag is supplied to a send()
or sendto() calls, while to receive outof band data MSG_OOB should be
indicated when performing a recvfrom() or recv() call.  To find out if
the read pointer is currently pointing at the mark in the data stream,
the SIOCATMARK ioctl is provided:


    IoctlSocket(s, SIOCATMARK, &yes);

If yes is a 1 on return, the next read will return data after the mark.
Otherwise (assuming out of band data hasarrived), the next read will
provide data sent by the client prior totransmission of the out of band
signal.  The routine used in the remote login process to flush output on
receipt of an interrupt or quit signal is shown below:

    #include <sys/ioctl.h>
    #include <sys/socket.h>
     ...
    oob()
    -
         int mark;
         char waste[BUFSIZ];


         /* flushterminal I/O on receipt of out of band data */


         for (;;)-
             if (IoctlSocket(rem, SIOCATMARK,&mark) < 0) -
                 perror("IoctlSocket");
                 break;
             "
             if (mark)
                 break;
             recv(rem, waste, sizeof (waste),0);
________________________________
  12AmiTCP/IP follows the BSD interpretation of the RFC 793 in which the

concept of out-of-band data is introduced.   The BSD interpretation is in
conflict with (later) defined Host Requirements laid down in RFC 1122.


System Manual                   AmiTCP/IP                   Section 3.4    53



         "
         if (recv(rem, &mark, 1, MSG_OOB) < 0) -
             perror("recv");
              ...
         "
          ...
    "

   The normal data up to the mark if first read (discarding it), then the
out-of-band byte is read.
   A processmay also read or peek at the out-of-band data without first
reading up to the mark.  This is more difficult when the underlying
protocol delivers the urgent data in-band with the normal data, and only
sends notification of its presence aheadof time (e.g., the TCP protocol
used to implement streams in the Internet domain).   With such protocols,
the out-of-band byte may not yet have arrived when a recv() is done with
the MSG_OOB flag.  In that case, the call will return an error of
EWOULDBLOCK. Worse, there may be enoughin-band data in the input buffer
that normal flow control prevents the peer from sending the urgent data
until the buffer is cleared.  The process must then read enough of the
queued data that the urgent data may bedelivered.
   Certain programs that use multiple bytes of urgent data and must handle
multiple urgent signals (e.g., telnet) need to retain the position of
urgent data within the stream.  This treatment is available as a
socket-level option, SO_OOBINLINE; see function reference for
setsockopt() for usage.  With this option, the positionof urgent data
(the ``mark'') is retained, but the urgent data immediately follows the
mark within the normal data stream returned without the MSG_OOB flag.
Reception of multiple urgent indicationscauses the mark to move, but no
out-of-band data are lost.



3.4.2   Non-Blocking Sockets

It is occasionally convenient to make use of sockets which do not block;
that is, I/O requests which cannot complete immediately and would
therefore cause the process to be suspended awaiting completion are not
executed, and an error code is returned.  Once a sockethas been created
via the socket() call, it may be markedas non-blocking by IoctlSocket()
as follows:

    #include <sys/ioctl.h>
     ...
    int      s;
     long     yes = TRUE;
     ...
    s = socket(AF_INET, SOCK_STREAM, 0);
     ...
    if (IoctlSocket(s, FIONBIO, &yes) < 0)
         perror("IoctlSocket FIONBIO");
         exit(1);
    "
     ...

   When performing non-blocking I/O on sockets, one must be careful to
check for the error EWOULDBLOCK (storedin the global variable errno),


54    Section 3.4                  AmiTCP/IP                   System Manual



which occurs when an operation would normally block, but the socket it
was performed on is marked as non-blocking.   In particular, accept(),
connect(), send(), sendto(), recv() andrecvto() can all return
EWOULDBLOCK, and processes should be prepared to deal with such return
codes.  If an operation such as a send() cannot be donein its entirety,
but partial writes are sensible (for example, when using a stream
socket), the data that can be sent immediately will be processed, and the
return value will indicate the amount actually sent.



3.4.3   Signal Driven Socket I/O

The AmiTCP/IP allows a task to be notified via a signal when a socket
has either normal or out-of-band data waiting to be read.  Use of this
facility requres four steps:

 1. The signals to be used must be allocated with Exec AllocSignal()
    call.

 2. The allocated signal(s) must be registered to the AmiTCP/IP with the
    SetSocketSignals() call.  The signals registered with
    SetSocketSignals() affect all sockets of the calling task, so this is
    usually done only after OpenLibrary() call.

 3. The owner of the socket must be set to the task itself (note that the
    owner of a socket is unspecified by default).  This is accomplished
    by the use of an IoctlSocket() call.

 4. Asynchronous notification for the socket must be enabled with another
    IoctlSocket() call

Note that it is application's responsibility to react on received
signals.
   Sample code to allow a given process to receive information on pending
I/O requests as they occur for a sockets is given below:

    #include <exec/tasks.h>
    #include <sys/ioctl.h>
     ...
    BYTE SIGIO = -1, SIGURG = -1;
     ...
    struct Task *thisTask = FindTask(NULL); /* our task pointer */
    long yes = TRUE;


    /* Allocate signals for asynchronous notification */


    if ((SIGIO = AllocSignal(-1)) == -1) -
         fprintf(stderr, "allocSignal failed."n");
         exit(1);
    "
    atexit(freeSignals); /* free allocated signals on exit */
    if ((SIGURG = AllocSignal(-1)) == -1) -
         fprintf(stderr, "allocSignal failed."n");
         exit(1);
    "


System Manual                   AmiTCP/IP                   Section 3.4    55



    /* Set socket signals for this task */


    SetSocketSignals(SIGBREAKF_CTRL_C, 1 << SIGIO, 1 << SIGURG);


    /* Set the process receiving SIGIO/SIGURG signals to us */


    if (IoctlSocket(s, FIOSETOWN, &thisTask) < 0) -
         perror("IoctlSocket FIOSETOWN");
         exit(1);
    "


    /* Allow receipt of asynchronous I/O signals */


    if (IoctlSocket(s, FIOASYNC, &yes) < 0) -
         perror("IoctlSocket FIOASYNC");
         exit(1);
    "



3.4.4   Selecting Specific Protocols

If the third argument to the socket() call is 0, socket will select a
default protocol to use with the returned socket of the type requested.
The default protocol is usually correct,and alternate choices are not
usually available.  However, when using ``raw'' socketsto communicate
directly with lower-level protocols or hardware interfaces, the protocol
argument may be important for setting updemultiplexing.  For example,
raw sockets in the Internet family may be used to implement a new
protocol above IP, and the socket will receive packets only for the
protocol specified.  To obtain a particular protocol one determines the
protocol number as defined within the communication domain.  For the
Internet domain one may use one of the library routines discussed in section
3.2, such as getprotobyname():

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
     ...
    pp = getprotobyname("newtcp");
    s = socket(AF_INET, SOCK_STREAM, pp->p_proto);

This would result in a socket s using astream based connection, but with
protocol type of ``newtcp'' instead of the default ``tcp.''



3.4.5   Address  Binding

As was mentioned in section 3.1, bindingaddresses to sockets in the
Internet domains can be fairly complex.  As a brief reminder, these
associations are composed of local and foreign addresses, and local and
foreign ports.  Port numbers are allocated out of separate spaces, one
for each system and one for each domainon that system.  Through the
bind() call, a process may specify halfof an association, the <local
address, local port> part, while the connect() and accept() calls are


56    Section 3.4                  AmiTCP/IP                   System Manual



used to complete a socket's associationby specifying the <foreign
address, foreign port> part.  Since the association iscreated in two
steps the association uniqueness requirement indicated previously could
be violated unless care is taken.  Further, it is unrealistic to expect user
programs to always know proper values touse for the local address and local
port since a host may reside on multiplenetworks and the set of allocated
port numbers is not directly accessibleto a user.
   To simplify local address binding in the Internet domain the notion of
a ``wildcard'' address has been provided.   When an address is specified
as INADDR_ANY (a manifest constant defined in file netinet/in.h), the
system interprets the address as ``any valid address''.  For example, to
bind a specific port number to a socket,but leave the local address
unspecified, the following code might beused:

    #include <sys/types.h>
    #include <netinet/in.h>
     ...
    struct sockaddr_in sin;
     ...
    s = socket(AF_INET, SOCK_STREAM, 0);
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(MYPORT);
    bzero(sin.sin_zero, sizeof(sin.sin_zero));
    bind(s, (struct sockaddr *) &sin, sizeof (sin));

Sockets with wildcarded local addressesmay receive messages directed to
the specified port number, and sent to any of the possible addresses
assigned to a host.  For example, if a host has addresses 128.32.0.4 and
10.0.0.78, and a socket is bound as above, the process will be able to
accept connection requests which are addressed to 128.32.0.4 or
10.0.0.78.  If a server process wished to only allow hosts on a given
network connect to it, it would bind theaddress of the host on the
appropriate network.
   In a similar fashion, a local port may be left unspecified (specified
as zero), in which case the system willselect an appropriate port number
for it.  For example, to bind a specific local addressto a socket, but
to leave the local port number unspecified:

    hp = gethostbyname(hostname);
    if (hp == NULL) -
          ...
    "
    bzero(&sin, sizeof(sin));
    bcopy(hp->h_addr, (char *) sin.sin_addr, hp->h_length);
    sin.sin_port = htons(0);
    bind(s, (struct sockaddr *) &sin, sizeof (sin));

The system selects the local port numberbased on two criteria.  The
first is that on 4BSD systems, Internetports below IPPORT_RESERVED

(1024) are reserved for privileged processes13 ; Internet ports above
________________________________
  13All processes in AmigaOS are considered as privileged.


System Manual                   AmiTCP/IP                   Section 3.4    57



IPPORT_USERRESERVED (5000) are reserved for non-privileged servers.  The
second is that the port number is not currently bound to some other
socket.  In order to find a free Internet port number in the privileged
range the rresvport() library routine may be used as follows to return a
stream socket in with a privileged portnumber:

    int lport = IPPORT_RESERVED - 1;
    int s;
    s = rresvport(&lport);
    if (s < 0) -
         if (errno== EAGAIN)
             fprintf(stderr, "socket: all ports in use"n");
         else
             perror("rresvport: socket");
          ...
    "

The restriction on allocating ports wasdone to allow processes executing
in a secure environment to perform authentication based on the
originating address and port number.  For example, therlogin command
allows users to log in across a networkwithout being asked for a
password, if two conditions hold:  First, the name of the system the user

is logging in from is in the file AmiTCP:db/hosts.equiv14  on the system
he is logging into (or the system name and the user name are in the
user's .rhosts file in the user's home directory), and second, that the
user's rlogin process is coming from a privileged port on the machine
from which he is logging.  The port number and networkaddress of the
machine from which the user is logging in can be determined either by the from
result of the accept() call, or from thegetpeername() call.
   In certain cases the algorithm used by the system in selecting port
numbers is unsuitable for an application.   This is because associations
are created in a two step process.  For example, the Internet file
transfer protocol, FTP, specifies that data connections must always
originate from the same local port.  However, duplicateassociations are
avoided by connecting to different foreign ports.   Inthis situation the
system would disallow binding the same local address and port number to a
socket if a previous data connection's socket still existed.  To override
the default port selection algorithm, anoption call must be performed
prior to address binding:

     ...
     long     on = 1;
     ...
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    bind(s, (struct sockaddr *) &sin, sizeof (sin));

With the above call, local addresses maybe bound which are already in
use.  This does not violate the uniqueness requirementas the system
still checks at connect time to be sureany other sockets with the same
local address and port do not have the same foreign address and port.  If
the association already exists, the error EADDRINUSE is returned.
________________________________
  14In UNIX /etc/hosts.equiv


58    Section 3.4                  AmiTCP/IP                   System Manual



3.4.6   Broadcasting And Determining Network Configuration

By using a datagram socket, it is possible to send broadcast packets on
many networks supported by the system.  The network itself must support
broadcast; the system provides no simulation of broadcast in software.
Broadcast messages can place a high loadon a network since they force
every host on the network to service them.   Consequently, the ability to
send broadcast packets has been limitedto sockets which are explicitly
marked as allowing broadcasting.  Broadcast is typically used for one of
two reasons:  it is desired to find a resource on a local network without
prior knowledge of its address, or important functions such as routing
require that information be sent to allaccessible neighbors.
   To send abroadcast message, a datagram socket should be created:

    s = socket(AF_INET, SOCK_DGRAM, 0);

The socket is marked as allowing broadcasting,

     long     on = 1;


    setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on));

and at least a port number should be bound to the socket:

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(MYPORT);
    bzero(sin.sin_zero, sizeof(sin.sin_zero));
    bind(s, (struct sockaddr *) &sin, sizeof (sin));

The destination address of the message to be broadcast depends on the
network(s) on which the message is to bebroadcast.   The Internet domain
supports a shorthand notation for broadcast on the local network, the
address INADDR_BROADCAST (defined in netinet/in.h).  To determine the
list of addresses for all reachable neighbors requires knowledge of the
networks to which the host is connected.  Since this information should
be obtained in a host independent fashion and may be impossible to
derive, 4.3BSD provides a method of retrieving this information from the
system data structures.  The SIOCGIFCONF IoctlSocket()call returns the
interface configuration of a host in theform of a single ifconf
structure; this structure contains a ``data area'' which is made up of an array
of of ifreq structures, one for each network interface to which the host is
connected.  These structures are defined in net/if.h asfollows:

    struct ifconf -
         int ifc_len;      /* size of associated buffer */
         union -
             caddr_t         ifcu_buf;
             struct ifreq *ifcu_req;
         " ifc_ifcu;
    ";


    #define ifc_buf     ifc_ifcu.ifcu_buf/* buffer address */
    #define ifc_req     ifc_ifcu.ifcu_req/* array of structures returned */


     #define IFNAMSIZ     64


System Manual                   AmiTCP/IP                   Section 3.4    59



    struct ifreq -
         char   ifr_name[IFNAMSIZ]; /*if name, e.g. "en0" */
         union -
             struct sockaddr ifru_addr;
             struct sockaddr ifru_dstaddr;
             struct sockaddr ifru_broadaddr;
             short  ifru_flags;
             caddr_t         ifru_data;
         " ifr_ifru;
    ";


     #define ifr_addr      ifr_ifru.ifru_addr     /* address */
    #define ifr_dstaddr   ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
    #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
    #define ifr_flags     ifr_ifru.ifru_flags   /* flags */
     #define ifr_data      ifr_ifru.ifru_data     /* for use by interface */

   The actual call which obtains the interface configuration is

    struct ifconf ifc;
    char buf[BUFSIZ];


    ifc.ifc_len = sizeof (buf);
    ifc.ifc_buf = buf;
    if (IoctlSocket(s, SIOCGIFCONF, (char *) &ifc) < 0) -
          ...
    "

After this call buf will contain one ifreq structure for each network to
which the host is connected, and ifc.ifc_len will have been modified to
reflect the number of bytes used by theifreq structures.
   For eachstructure there exists a set of ``interface flags'' which tell
whether the network corresponding to that interface is up or down, point
to point or broadcast, etc.  The SIOCGIFFLAGS IoctlSocket() retrieves
these flags for an interface specified by an ifreq structure as follows:

    struct ifreq *ifr;


    ifr = ifc.ifc_req;


    for (n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++) -
         /*
          * We must be careful that we don't use an interface
          * devoted to anaddress family other than those intended;
          * if we were interested in NS interfaces, the
          * AF_INET wouldbe AF_NS.
          */
         if (ifr->ifr_addr.sa_family != AF_INET)
             continue;
         if (IoctlSocket(s, SIOCGIFFLAGS, (char *) ifr) < 0) -
              ...
         "
         /*


60    Section 3.4                  AmiTCP/IP                   System Manual



          * Skip boring cases.
          */
         if ((ifr->ifr_flags & IFF_UP) == 0 __
             (ifr->ifr_flags & IFF_LOOPBACK) __
             (ifr->ifr_flags & (IFF_BROADCAST_ IFF_POINTTOPOINT)) == 0)
             continue;

Once the flags have been obtained, the broadcast address must be
obtained.  In the case of broadcast networks this is done via the
SIOCGIFBRDADDR IoctlSocket(), while forpoint-to-point networks the
address of the destination host is obtained with SIOCGIFDSTADDR.

    struct sockaddr dst;


    if (ifr->ifr_flags & IFF_POINTTOPOINT) -
         if (IoctlSocket(s, SIOCGIFDSTADDR, (char *) ifr) < 0) -
              ...
         "
         bcopy((char *) ifr->ifr_dstaddr, (char *) &dst,
               sizeof (ifr->ifr_dstaddr));
    " else if (ifr->ifr_flags & IFF_BROADCAST) -
         if (IoctlSocket(s, SIOCGIFBRDADDR, (char *) ifr) < 0) -
              ...
         "
         bcopy((char *) ifr->ifr_broadaddr, (char *) &dst,
               sizeof (ifr->ifr_broadaddr));
    "

After the appropriate ioctl's have obtained the broadcast or destination
address (now in dst), the sendto() callmay be used:

         sendto(s,buf, buflen, 0, (struct sockaddr *)&dst, sizeof (dst));
    "

In the above loop one sendto() occurs for every interface to which the
host is connected that supports the notion of broadcast or point-to-point
addressing.  If a process only wished to send broadcastmessages on a
given network, code similar to that outlined above would be used, but the
loop would need to find the correct destination address.
   Receivedbroadcast messages contain the senders address and port, as
datagram sockets are bound before a message is allowed to go out.



AmiTCP/IP specific extensions

Extensions to interface ioctls

The following ioctls are used to configure protocol and hardware specific
properties of a sana_softc interface.  They are used in the AmiTCP/IP
only.

SIOCSSANATAGS  Set SANA-II specific properties with a tag list.

SIOCGSANATAGS  Get SANA-II specific properties into the
    wiretype_parameters structure and a user tag list.

    These ioctls use the following structure as a argument:


System Manual                   AmiTCP/IP                   Section 3.4    61



         struct wiretype_parameters
         -
           ULONG  wiretype;       /* the wiretype of the interface */
           WORD   flags;                                /* iff_flags */
           struct TagItem *tags;         /* tag list user provides */
         ";


SIOCGARPT  Getthe contents of an ARP mapping cache into a struct arpreq
    table.

    This ioctl takes the following arptabreq structure as an argument:


         /*
          * An AmiTCP/IP specific ARP table ioctl request
          */
         struct arptabreq -
            struct arpreq atr_arpreq;  /* To identify theinterface */
            long   atr_size;           /* # of elementsin atr_table */
            long   atr_inuse;                /* # of elements in use */
            struct arpreq *atr_table;
         ";


    The atr_arpreq specifies the used interface.  The hardware address
    for the interface is returned in the arp_ha field of atr_arpreq
    structure.

    The SIOCGARPT ioctl reads at most atr_size entries from the cache
    into the user supplied buffer atr_table, if it is not NULL. Actual
    amount of returned entries is returned in atr_size.  The current
    amount of cached mappings is returned in the atr_inuse.



3.4.7   Socket  Options

It is possible to set and get a number of options on sockets via the
setsockopt() and getsockopt() calls.  These options include such things
as marking a socket for broadcasting, not to route, to linger on close,
etc.  The general forms of the calls are:

    setsockopt(s, level, optname, optval, optlen);

and

    getsockopt(s, level, optname, optval, optlen);

   The parameters to the calls are as follows:  s is the socket on which
the option is to be applied.  level specifies the protocol layer on which
the option is to be applied; in most cases this is the ``socket level'',
indicated by the symbolic constant SOL_SOCKET, defined in sys/socket.h.
The actual option is specified in optname, and is a symbolic constant
also defined in sys/socket.h.  optval and optlen pointto the value of
the option (in most cases, whether the option is to be turned on or off),
and the length of the value of the option, respectively.  For
getsockopt(), optlen is a value--resultparameter, initially set to the


62    Section 3.4                  AmiTCP/IP                   System Manual



size of the storage area pointed to by optval, and modified upon return
to indicate the actual amount of storageused.
   An example should help clarify things.  It is sometimes useful to
determine the type (e.g., stream, datagram, etc.)   ofan existing socket;
programs under inetd (described in section 3.4.8) may need to perform
this task.  This can be accomplished as follows via theSO _TYPE socket
option and the getsockopt() call:


    #include <sys/types.h>
    #include <sys/socket.h>


    long type, size;


    size = sizeof (type);


    if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &type, &size) < 0) -
          ...
    "


After the getsockopt() call, type will be set to the value of the socket
type, as defined in sys/socket.h.  If, for example, thesocket were a
datagram socket, type would have the value corresponding to SOCK_DGRAM.



3.4.8   Inetd

One of the daemons provided with AmiTCP/IP is inetd, the so called
``internet super--server.''  Inetd is invoked at start-up time, and
determines the servers, for which it isto listen, from the file
AmiTCP:db/inetd.conf15.  Once this information has been read and a
pristine environment created, inetd proceeds to create one socket for
each service it is to listen for, binding the appropriate port number to
each socket.
   Inetd then performs a select() on all these sockets for read
availability, waiting for somebody wishing a connection to the service
corresponding to that socket.  Inetd then performs an accept() on the
socket in question, releases the socketwith a ReleaseSocket() call and
starts the appropriate server.
   Servers making use of inetd are considerably simplified, as inetd takes
care of the majority of the work required in establishing a connection.
The server invoked by inetd expects thesocket connected to its client to
be found by calling ObtainSocket().  The client socketID for the server
is found in a DaemonMessage structure given to the server process.
Usually the netlib:autoinitd.o module takes care of obtaining the client
socket into global variable server_socket.  For practical purposes the
code might assume this socket to be 0.
   One callwhich may be of interest to individuals writing servers under
inetd is the getpeername() call, which returns the address of the peer
(process) connected on the other end ofthe socket.   For example, to log
the Internet address in ``dot notation''(e.g., ``128.32.0.4'') of a
________________________________
  15In UNIX systems /etc/inetd.conf.


System Manual                   AmiTCP/IP                   Section 3.5    63



client connected to a server under inetd, the following code might be
used:

    struct sockaddr_in name;
    int namelen = sizeof (name);
     ...
    if (getpeername(0, (struct sockaddr *)&name, &namelen) < 0) -
         syslog(LOG_ERR, "getpeername: %m");
         exit(1);
    " else
         syslog(LOG_INFO, "Connection from %s", inet_ntoa(name.sin_addr));
     ...

While the getpeername() call is especially useful when writing programs
to run with inetd, it can be used underother circumstances.
   Sources for a very simple TCP protocol server is included with
AmiTCP/IP as an example.



3.5     Deviation  From  Berkeley  Sockets


This section discusses the differences between the API of the AmiTCP/IP
and the 4.3BSD. They are not so numerousas it might seem to, but worth
taking attention to when porting existing 4.3BSD software to AmiTCP/IP.



3.5.1   Opening and Closing the Shared Library

Since the API is provided as a shared library, it must be opened to be
able to access the functions it provides.   Note that any two tasks may
not share a socket library base, since the base contains task specific
information.
   AmiTCP/IPdoes resource tracking based on the information stored in a
library base, so it is essential that the library is closed after use,
since the resources used by the base aregone if the application exits
without closing the base.
   See section 3.1.2 for examples and more discussion on the subject.



3.5.2   Naming Conventions of the API Functions

The API functions which preserve the semantics of the BSD calls are named
the same as the original functions.  In the name of binary compatibility
between different C compilers the functions which either take a structure
as an argument or return a structure asa value had to be changed not to
do so.  These functions are named differently; all words in these

function names begin with an upper caseletter.   Inlinefunctions16  are
provided with the original semantics, however.   This makes it possible to
keep using the original functions when writing the code and still be
binary compatible.  The inline functions are mostly trivial; for example
the select() call is actually an inlinewhich calls WaitSelect() with
last argument as NULL.
________________________________
  16Or linker stubs in compilers with no inline functions.


64    Section 3.5                  AmiTCP/IP                   System Manual



   This is amatter which should be totally invisible for C users, but
assembler programmers should take attention and be sure to pass arguments
as described in the function reference for the non-inline versions.



3.5.3   errno


Unix libraries return error values in aglobal variable named errno.
Since a shared library cannot know the address of any variables of an
application, the address of the errno must be explicitly told to the
AmiTCP/IP. An alternative is to use Errno() call to fetch the error
value, but since the first method needsno modifications to the existing
sources (besides calling SetErrnoPtr() once in the beginning), it is the
preferred method.  Section 3.1.2 contains examples andmore discussion
about the matter.



3.5.4   NewField in the sockaddr Structures


Since AmiTCP/IP is based on the BSD Net/2 release, it has few
differences to the 4.3BSD. Most notableone is that the sockaddr and
sockaddr_in structureshave a new field telling the length of the
structure.  These are named as sa_len and sin_len respectively.   These
fields are used by the AmiTCP/IP to determine the real length of the
address given.
   In addition the sockaddr_in structure has a field named sin_zero, which
should be initialized to zero before passed to the AmiTCP/IP, since any
garbage left there will be used by the routing facility (which obviously
leads to undesired behaviour).



3.5.5   Linger  Time


The unit of the linger time of a socketis a second.   The Net/2 code

seemed to use ticks17.



3.5.6   Transferring Sockets from a Task to Another


Since AmigaOS has no fork() call, in which the child process inherits the
file descriptors, and hence sockets, a mechanism for transferring sockets
from a task to another must be provided.  This is accomplished by the
calls ReleaseSocket(), ReleaseCopyOfSocket() and ObtainSocket(), which
release a socket, a copy of a socket andobtain a released socket,
respectively.  An id is given to a socket placed in thelist of released
sockets.  This id can be either unique or be based on aservice number in
cases where it is irrelevant which instance of the server process for the
service in question obtains the socket.  If an unique id is used, the
releasing task is responsible of transferring the id to the obtaining
task.
________________________________
  17One tick is 1/hz:th of a second, where hz is the frequency of the

electricity of the wall socket.


System Manual                   AmiTCP/IP                   Section 3.5    65



   This feature affects the server processes only, since the clients
usually create the socket(s) on their own.



3.5.7   Ioctl  Differences

The Unix ioctl() function is renamed asIoctlSocket() in AmiTCP/IP to
avoid name clashes with some C runtime libraries.
   Followingsummarizes other differences in the ioctl calls:

 1. FIOCLEX and FIONCLEX are silently ignored, that is, they are
    accepted, but have no effect.  Whether sockets should be closed on
    exec() or not is irrelevant, since AmigaOS has no such feature (see
    discussion about fork() above).

 2. FIOSETOWN and SIOCSPGRP take a pointer to a struct Task * as an
    argument instead of a pointer to a process (or group) id.  Note that
    if the task in question has not opened the bsdsocket.library the
    owner of the precess is set to NULL (disabled).  The task pointer is
    used as the receiver of the asynchronous notification signals if
    asynchronous notification is enabled.

 3. FIOGETOWN and SIOCGPGRP take a pointer to a struct Task * as an
    argument in which the current task pointer of the owner of the socket
    in question is placed on return.



3.5.8   Signal  Handling

There is a fundamental difference between BSD Unix and Amiga signal
handling and the system call interface.  In the Unix systems a received
signal may interrupt a process executinga system call.  If there is a
signal handler installed, it can be executed before the system call
returns to the main execution branch with an error code.
   However,there are some system calls which may not be interrupted.  If
a Unix process has a negative priority,tsleep() does not wake up until
the specified condition is met.
   The interrupted system call does not have any unrecoverable effects,
the execution of the program may continue after the errno is checked
against other errors than EINTR.
   In the AmigaOS, Exec, there are no specific system calls.  All OS
functions are provided by shared libraries.   There areeither no separate
kernel and user memory spaces, the one common memory space is shared by
all processes.  The IO system is based on messages, which are implemented
as shared memory areas.  When a program receives a message to a port, it
is delivered a signal associated with the port.
   While itis possible to use signal handlers with Exec, they are even
more dangerous to use and restricted than in Unix systems.  This is not
recommended, since the exception handlermust behave like any real
interrupt handler.  Calls provided by AmiTCP/IP are notcallable from
interrupts.  Further, it is not possible to interrupt asystem call
implemented as a shared library function.
   The application must itself react on receipt of the signals.  The
recommended way of handling these signals is by the normal Wait() of by


66    Section 3.5                  AmiTCP/IP                   System Manual



AmiTCP/IP call WaitSelect(), which allows an application to specify a
signal mask which should abort the selection.   The application then
checks the received signals and calls appropriate handler for the signal.



3.5.9   Asynchronous I/O


AmigaOS does not have any reserved signals for networking, such as SIGIO
or SIGURG in Unix systems, and so the scheme used in asynchronous
notification must be changed a little.
   The application can set a group of signal masks, with function named
SetSocketSignals(), to be used by the AmiTCP/IP. First argument
specifies the signal mask which should break the blocking of the blocking
socket calls.  It is by default set to the signal for CTRL-C. Second
argument specifies the signal(s) to be sent when asynchronous
notification for readiness to read is necessary.   Thismask lets the
application define which signal should be used as replacement for SIGIO
signal of the Unix systems.  Third and last argument specifies the
corresponding mask for the asynchronousnotification of urgent
(out-of-band) data (SIGURG). These lasttwo masks are zero by default.
   Note thatthere is no way to query the current settings of these
signals form the AmiTCP/IP, so the application must store the signal
numbers (or masks) for later use.  Also note that the break mask must be
explicitly given if SetSocketSignals() is called, since the values
supplied override the default settings.



3.5.10   Constructing an Event Loop


Amiga programs are often constructed around an event loop, in which
Wait() function is used to wait for somesubset of given signals to
arrive.  When a signal is received, some actions are taken and if IO is
performed, it is usually asynchronous.
   Many Unixprograms use to do synchronous IO and let the signal handlers
to handle special events (window size changes, timeouts, etc.).  This can
be emulated to some extent with AmigaOS,since it is possible to specify
an exeption function to handle receptionof given signals.  This is very
limited, though, since the exeption codeis executed at true interrupt
level, and may thus pre-empt the main process in an arbitrary location.
Also note that a very limited set of shared library functions can be
called while in interrupt, especially note that any AmiTCP/IP function
may NOT be called from interrupt code.
   AmiTCP/IPoffers remedy for this, however.  The application can use
WaitSelect() to handle both Amiga signals and socket IO multiplexing.

Selecting assures that the following socket calls will not block18.
   Another possiblility is to use signal driven socket IO (see section
3.4.3).
   Yet another possibility is to specify a special break mask with
SetSocketSignals() function.  The signals in the mask cause any blocking
socket IO routine to return with the error code EINTR. Note that the
________________________________
  18See NOTES section of the reference for the WaitSelect().


System Manual                   AmiTCP/IP                   Section 3.5    67



signals are not cleared in this procedure.   The Wait()with the same
signal mask can be used to determine (and clear) the received signals.
This allows the usage of synchronous socket IO, but the EINTR error code
must be checked after each failing call.



3.5.11   ''Killing'' the Processes

In AmigaOS the applications must co-operate with the OS for the user to
be able to stop them.  This is why the blocking operations of the
AmiTCP/IP can be aborted.  By default the reception ofCTRL-C signal
aborts any blocking call.  The call returns an error value (in errno) of
EINTR when aborted.  In addition the signal which caused the break will
remain set for the application to be able to react on it in its normal
event processing.  This means that the application neednot specially
check for EINTR after every socket callas long as they eventually check
for the break signal.
   All sockets left open by the application are closed by the
CloseLibrary() call.  You may left the sockets open when aborting the
program, because the socket library is closed automatically during the
exit process if either autotermination function (specific to SAS C) or
ANSI atexit() function is installed before the exit is done.  .
   The signals which cause the abort can be set with the
SetSocketSignals() call.  The break signal mask is given as the first
argument.  Calling this function discards the previousvalues of the
sockets signal masks.  Aborting can be disabled by giving the mask as 0L.
See section 3.5.9 for more discussion about the SetSocketSignals() call.



3.5.12   WaitSelect()

In AmiTCP/IP no other than socket I/O can be multiplexed with the
select() call.  This may be a major pain as I/O is normally multiplexed
with an Wait() loop, waiting for given signals to arrive.  This is the
motivation for the WaitSelect() call.  It combines theselection and
waiting in a single call19.  The WaitSelect() takes one argument in
addition to the normal select() call.  It is a pointerto signal mask to
wait for in addition to the signals thatthe AmiTCP/IP uses internally.
If any of these signals is received, they are returned as a result in the
same signal mask.  Signals specified in the given signal mask override
the signals of the break mask (see previous section).  If the same signal
is specified in both the SIGINTR mask and the mask given to the WaitSelect(),
the reception of the signal causes it tobe cleared and returned in the mask
as the result.
   WaitSelect() can be used as replacement for the Wait() in applications
which require to multiplex both socket related and other Amiga I/O.



________________________________
  19This feature was really easy to implement, since AmiTCP/IP uses a Wait()

to wait for I/O events itself.


68    Section 3.5                  AmiTCP/IP                   System Manual





Chapter 4



Internal Description



4.1     Source  File  Structure


The source tree of AmiTCP/IP is dividedto few main parts:


 1. Directory sys contains BSD Unix system header files, which are ported
    to the Amiga environment.


 2. Directory net contains modules for the general networking services.
    They are independent of any particular protocol family.


 3. Directory netinet contains the modules for the internet (inet)
    protocol family.  IP, ICMP, TCP and UDP are internet protocols.


 4. Directory kern contains modules, which provide the BSD kernel
    environment for the networking routines.


 5. Directory api contains the BSD socket compatible shared library API
    code.


   The filesare briefly described in the following paragraphs.  Note that

some of the header files are actually located to the NETINCLUDE:1
directory.



4.1.1   System Include Files

 General Headers


    sys/cdefs.h  Definitions to harmonize various C language dialects.

    sys/param.h  General machine independent parameter definitions.

    sys/time.h  Definition of structure timeval.

    sys/types.h  Common C type definitions and file descriptorset macros
        for select().


 BSD Socket API
________________________________
   1See section 3.1.3 on page 30.



                                      69


70    Section 4.1                  AmiTCP/IP                   System Manual



    sys/errno.h  Error code definitions for system functions.

    sys/ioctl.h  Definitions for socket IO control.

    sys/socket.h  Definitions related to sockets:  types, address
        families, options and prototypes.

    sys/uio.h  IO structure definition for sendmsg() and recvmsg()2.


 BSD Kernel Data Structures


    sys/domain.h  Domain structure and global domain pointer declarations.

    sys/kernel.h  Global kernel variable definitions (used throughoutthe
        kernel).

    sys/malloc.h  Defines the bsd_malloc() and bsd_free() functions.

    sys/mbuf.h  Mbuf structure definition and inline macros.

    sys/protosw.h  Protocol switch structure definition with related
        definitions (options, actions, etc.).

    sys/queue.h  General queue data structures.

    sys/socketvar.h  Socket structure definition and related utility
        macros.

    sys/synch.h  Declarations for tsleep and spl functions.

    sys/syslog.h  Logging related definitions.

    sys/systm.h  System wide definitions and prototypes.



4.1.2   Protocol Independent Network Routines

 Network Interface


    net/if.c  General network interface routines.

    net/if.h  Defines the interface for network adapter drivers.

    net/if_arp.h  General protocol independent ARP structures.

    net/if_dl.h  Defines the Link Level sockaddr structure.

    net/if_loop.c  Loopback device routines.

    net/if_sana.c  Interface module for the SANA-IInetwork adapter
        drivers.

    net/if_sana.h  Defines the interface for the SANA-II network adapter
        drivers.

    net/if_types.h  Interface type numbers.  Obsolete.

    net/netisr.h  and

    net/netisr.c  Defines the network input queue scheduling routines.

    net/sana2arp.c  ARP routines for Sana-II devices.

    net/sana2arp.h  SANA-II private ARP headers.

    net/sana2copybuff.c   Buffer management routines called from SANA-II
________device_driver.__________

   2These functions are not implemented in this release of the AmiTCP/IP


System Manual                   AmiTCP/IP                   Section 4.1    71



    net/sana2errno.h  SANA-II error lists and printing header.

    net/sana2request.c   Moduleto handle SANA-II IO Requests.

    net/sana2request.h   Inlineroutines to manage different SANA-II IO
        requests.

    net/sana2tags.c  Common customization parameters for the sana_softc
        network interface.

    net/sana2tags.h  Defines the tags to customize sana_softc network
        interface.

    netlib:sana2perror.c   Printing routines for SANA-II error messages.


 Routing


    net/radix.c  Routines for searching, adding and removing data items in
        the radix binary tree.

    net/radix.h  Defines the radix tree data structures.

    net/route.c  General, protocol independent routing functions.

    net/route.h  Defines data structures for routing entries,tables and
        statistics.

    net/rtsock.c  The socket interface to the routing information.


 Raw Sockets


    net/raw_cb.c  Routines to manage the rawprotocol control blocks.

    net/raw_cb.h  The raw protocol control block definition.

    net/raw_usrreq.c  The raw socket interface to the low level protocols
        and network adapters.



4.1.3   Internet Protocol Modules

 Inet Domain


    netinet/in.c  Generic Internet addressing routines.

    netinet/in.h  Protocol numbers, port conventions, inet address
        definitions.

    netinet/in_cksum.c  Calculates checksum for internet protocol headers.

    netinet/in_pcb.c  Generic internet protocol routines, binding,
        addressing.

    netinet/in_pcb.h  Declares generic internet protocol control block.

    netinet/in_proto.c  Defines internet protocol control blocks.

    netinet/in_systm.h  Some network byte order type definitions.

    netinet/in_var.h  Define an interface address structure for internet.


 IP, ICMP


    netinet/icmp_var.h  ICMP statistics.

    netinet/ip.h  IP packet header, packet options, timestamp.


72    Section 4.1                  AmiTCP/IP                   System Manual



    netinet/ip_icmp.c  Routines to generate, receive and reflect ICMP
        packets.

    netinet/ip_icmp.h  ICMP packet structure.

    netinet/ip_input.c  IP input, packet reassemble and packet forwarding.

    netinet/ip_output.c  IP output, packet fragmenting.

    netinet/ip_var.h  Define IP statistics, external IP packet header,
        reassemble queues structures.

    netinet/raw_ip.c  Provide a raw interface to the IP protocol.


 TCP


    netinet/tcp.h  Define the TCP packet structure.

    netinet/tcp_debug.c  TCP debugging routines.

    netinet/tcp_debug.h  Header for TCP debugging.

    netinet/tcp_fsm.h  TCP Finite State Machine states.

    netinet/tcp_input.c  TCP input routines.

    netinet/tcp_output.c  TCP output routines.

    netinet/tcp_seq.h  TCP sequence numbering.

    netinet/tcp_subr.c  Various TCP subroutines for initializing,
        connection maintenance etc.

    netinet/tcp_timer.c  TCP timeout routines.

    netinet/tcp_timer.h  TCP timing constants.

    netinet/tcp_usrreq.c  Process TCP user requests (send, timeout),
        attach, disconnect.

    netinet/tcp_var.h  Define TCP control block and TCP statistics.

    netinet/tcpip.h  Define the overlaid TCPIP packet header structure.


 UDP


    netinet/udp.h  Define the UDP packet structure.

    netinet/udp_usrreq.c  Routines to UDP output, input and notification.

    netinet/udp_var.h  Define UDPIP packet overlay, UDP statistics.



4.1.4   BSDKernel Service Modules

 BSD Kernel Support


    kern/amiga_includes.h   Include file which includes all amiga specific
        include files.

    kern/amiga_main.c  Main module of the AmiTCP/IP.

    kern/amiga_subr.h  Miscellaneous function definitions (usually short
        inline functions).

    kern/amiga_time.c  Timer module for the timeout functions.

    kern/amiga_time.h  Amiga timer.device related functions.


System Manual                   AmiTCP/IP                   Section 4.1    73



    kern/kern_malloc.c  Malloc & free related functions.

    kern/kern_synch.c  tsleep and spl function definitions.

    kern/uipc_mbuf.c  Mbuf functions.


 Socket Level Functions


    kern/uipc_domain.c  Domain functions, especially pfslowtimo() and
        pffasttimo().

    kern/uipc_socket.c  Higher level so-level functions (socreate(),
        sobind() etc.).

    kern/uipc_socket2.c  Lower level so-level functions (soisconnecting(),
        soqremque(), sowakeup() etc.).


 NETTRACE Maintenance Process Support


    kern/amiga_config.c  Configuration and ARexx command support routines.

    kern/amiga_config.h  Defines the structure for configuration
        variables.

    kern/amiga_cstat.c  Query support routines.

    kern/amiga_log.c  Functions for initialization of log task and code
        for task itself.

    kern/amiga_log.h  Header file for logging functions.

    kern/amiga_netdb.c  Network database parsing and support functions.

    kern/amiga_netdb.h  Declares the network database structures and
        types.

    kern/amiga_rexx.c  Arexx-interface.

    kern/amiga_rexx.h  Arexx-interface definitions.

    kern/config_var.awk  Awk script to generate both code and
        documentation from the file kern/variables.src.

    kern/subr_prf.c  Interfaces for (s)printf(), panic() and log()

    kern/variables.src   Definition and documentation for configuration
        variables



4.1.5   BSDSocket API

 Shared Library Interface


    api/allocdatabuffer.c   Client data buffer allocation functions.

    api/allocdatabuffer.h   Client data buffer allocation definitions.

    api/amiga_api.c  Contains API initialization and deinitialization
        functions and data.  Opening and Closing of the AmiTCP/IP socket
        library bases.

    api/amiga_api.h  Description of the SocketBase structure (forinternal
        AmiTCP/IP use only), and some inline functions relatedto the API
        functionality.


74    Section 4.1                  AmiTCP/IP                   System Manual



    api/amiga_libcallentry.h   Included in every module which defines
        AmiTCP/IP socket library calls.

    api/amiga_libtables.c   Exec library base list and AmiTCP/IP socket
        library function tables for MakeLibrary().

    api/amiga_raf.h  Compiler dependent macros for Register Argument
        Functions.

    api/apicalls.h  Includes either api/apicalls_gnuc.h or
        api/apicalls_sasc.h.

    api/apicalls_gnuc.h  Inline functions for internal API calls for GNUC.

    api/apicalls_sasc.h  Inline functions for internal API calls for SASC.

 API Functions

    api/amiga_generic.c  General Unix system calls related to file
        descriptors ported for AmiTCP/IP socket library.  There are also
        some Amiga specific extensions to the BSD Unix system calls in
        this module.

    api/amiga_libcalls.c  Inet library functions (link library in Unix
        system).  These inet functions are provided as a part of the
        AmiTCP/IP socket library.

    api/amiga_syscalls.c  Standard BSD style socket functions ported to
        the AmiTCP/IP socket library.

    api/gethostnamadr.c   Functions that calls resolver in order to obtain
        host information from nameserver.  Calls netdatabase functions if
        information can not be resolved.

    api/gethtbynamadr.h   Prototypes for two functions in api/getxbyy.h.

    api/getxbyy.c  Host (without nameserver), network, service ja protocol
        query functions (also a link library in unix system).

    api/hostbuf.h  Structure definition for host queries and few minor
        netdb stuff.

 Resolver Functions

    api/arpa_nameser.h  Information for nameserver query.

    api/res_comp.c  Routines to translate domain names between
        conventional ascii and the compressed format used in queries.

    api/res_debug.c  Functions that output debugging information3

    api/res_init.h  Resolver initializer function.  Very simple in
        AmiTCP/IP implementation.

    api/res_mkquery.c  Function that forms a domain name query in buffer.

    api/res_query.c  Functions to generate query sequence and append
        domains to incomplete hostnames.

    api/res_send.c  Function to send and receive query to and from a
        nameserver, respectively.

    api/resolv.h  Resolver datatypes, defines, variables and prototypes.
________________________________
   3If RES_DEBUG defined at compile time


System Manual                   AmiTCP/IP                   Section 4.2    75



4.1.6   Miscellaneous Files


 Makefiles


    GCCOPTS  Compiler options forthe GCC.

    GNUmakefile  Makefile used with GNU make in HP-UX workstations, where
        the source tree is maintained.

    SCOPTIONS  Compiler options for the SAS/C 6.x

    Smakefile  Makefile for SAS/C smake 6.x to compile the AmiTCP/IP.


 Revision Support


    bsdsocket.library_rev.rev   Contains revision numberof the current
        version (number of the latest build).  This file is updated with

        the BumpRev utility4.

    bsdsocket.library_rev.h   Automaticallygenerated by BumpRev.  Contains
        build date, version and revision strings.


 SAS/C 6.x GST Support


    all_includes.c  C file for GST generation.  Just includes the
        all_includes.h file.

    all_includes.h  Includes all header files needed by theAmiTCP/IP,
        which are suitable for inclusion in a GST. Note that any headers
        with inline functions can not be included in a GST.


 Other Files


    conf/conf.h  Static configuration information in form of preprocessor
        defines.  Every C module must include this as the first include
        file.

    conf/rcs.h  RCS header inclusion macro for GCC. InSAS/C this macro is
        defined in the SCOPTIONS file.

    protos/*/*.h  Prototypes for functions in various modules.



4.2     AmiTCP/IP Initialization


All more or less distinct modules of theAmiTCP/IP must be initialized
before they can be used for the real work.   Initialization is done in
module kern/amiga_main.c, which definesfunctions init_all() and
deinit_all().  The main() function calls the init_all()after it has done
all needed local initializations.  If init_all() failsthe deinit_all() is
called to clean up.

________________________________
   4The BumpRev is supplied by Commodore.


76    Section 4.2                  AmiTCP/IP                   System Manual



4.2.1   init _all()

This function calls the initialization routines of all modules which have
such.  This must be done carefully in the correct partial order.
   There arefew general heuristics which can be applied on initialization
(with respect to the ordering requirements):


 1. Initialize the modules for which the initialization cannot fail.
    This includes semaphore initializations and such.

 2. Initialize the modules which are most likely to fail, e.g.  large
    memory allocations, modules which require recent versions of some
    libraries etc.

 3. Initialize modules left over by rules 1 and 2.


   Semaphoreinitializations are first, because later steps may use them
to protect against race conditions.
   The initialization process of the AmiTCP/IP is fully reversible.  If
the initialization fails in any step thedeinit _all() function can be
used to collect the garbage.
   init_all() does the initializations in following order, returning
nonzero if all steps succeed.  Numbers in the parenthesis are the section
and page numbers for more information, respectively:


 1. malloc_init() initializes the malloc_semaphore.  This is first since
    later steps may want to use bsd_malloc() to allocatememory (5.2.2,
    95).

 2. spl_init() initializes the priority level subsystem,which is used
    throughout the code to protect critical sections (5.3.1, 96).

 3. sleep_init() initializes the sleep_semaphore and the sleep queues
    (5.3.2, 97).

 4. readconfig() reads in and parses the command line arguments and the
    configuration file.  This is the first phase which is expected to
    fail.  This is done at the beginning in order to allow other
    initialization functions to use the configuration information given.
    Note that since the logging subsystem is not initialized yet,
    readconfig() cannot log any errors encountered (4.11, 91).

 5. log_init() initializes the logging subsystem.  From now on other
    initialization functions can log needed error messages (4.8, 89).

 6. mbinit() allocates memory to be used by the protocols.  This is a
    candidate to fail if the memory is nearly exhausted (4.5, 79).

 7. timer_init() initializes the timeout module.  This requires version
    36 or greater of the operating system.  Returns the signal mask to
    wait for the timeout messages (5.1, 93).

 8. api_init() initializes and creates the master socketbase structure
    (4.10.2, 91).

 9. res_init() initializes resolver structure and semaphore.


System Manual                   AmiTCP/IP                   Section 4.3    77



10. sana_init() initializes the SANA-II network interface module.   This
    returns the signal mask to be used for waiting the network related
    messages (4.7, 84).

11. domaininit() initializes all configured protocols.  This is left at
    the end of the initialization, since this requires the other parts of
    the system to be initialized.

12. readnetdb() initializes and reads in the network data base
    information from ENV:AmInet/netdb (4.12, 92).

13. api_show() makes the shared library interface visible on the Exec
    library list (4.10.2, 91).



4.2.2   deinit _all()

deinit_all() is the reverse of init_all(); it deinitializes required
modules in reverse order with respect tothe initialization.
   If the initialization process for a module does not allocate any
resources, then there is no deinitialization function for that module.
The deinitialization functions called are (in this order):


 1. api_hide() removes the library from the Exec librarylist, so no-one
    can open the library any more (4.10.2, 91).

 2. sana_deinit() deinitializes the network driver module (4.7, 84).

 3. api_deinit() deinitializes the API (4.10.2, 91).

 4. timer_deinit() deinitializes the timer module (5.1,93).

 5. mbdeinit() frees all memory used by mbufs (4.5, 79).

 6. log_deinit() deinitializes the logging subsystem (4.8, 89).



4.3     The  Main  Module


The main() function is defined in the file kern/amiga_main.c.  On startup
it initializes all modules by calling init _all().  After a successful
initialization it first starts the AmiTCP/IP timeouts by calling
timer_send().  Then it enters the event loop.
   AmigaOS function Wait() returns when one of the signals specified in
the signal mask given as argument is received.   The mask currently
specifies signals for SANA-II drivers, timeouts and the break signal.
When some set of these signals is received the Wait() returns and its
return value, which indicates the received signals, is checked.  The
functions sana_poll() and timer_poll() are each called in turn if their
signal was received.  They each return boolean tellingif they would like
to be called again before waiting again.  The loop in which these
functions are called is terminated either when no one of the poll
functions wants to continue or when thebreak signal is received.
   The pollfunctions do handle only one message at a time, so that any of
them should not starve.


78    Section 4.4                  AmiTCP/IP                   System Manual



   When thebreak signal is received the AmiTCP/IP terminates if no
library bases opened by API users are open any more.  On termination all
reserved resources are freed by callingdeinit _all().



4.4     Protocol Entities


One design goal was to keep the protocolentities intact.  This is
achieved through implementing all external dependencies of the protocol
entities.  Fortunately the protocol entities in BSD arehighly
independent of other UNIX kernel services.   For example, all dynamic

memory management is done through the memory buffer5  abstraction, which
means that we only had to provide the mbuf interface and the problem of
memory management was solved.
   All protocol entities in a protocol family are defined in terms of a
protocol switch structure.  This structure is fully defined in the header
file sys/protosw.h and [Leffler et al 1991b ].  The protocol switch
structure is defined as follows:


struct protosw -
    short   pr_type;             /* socket type used for */
    struct  domain *pr_domain;  /* domain protocol a member of */
    short   pr_protocol;         /* protocol number */
    short   pr_flags;            /* protocol flags */
/* protocol-protocol hooks */
     void     (*pr_input)();      /* input to protocol (from below) */
    int      (*pr_output)();      /* output to protocol (from above)*/
     void     (*pr_ctlinput)();   /* control input (from below) */
    int      (*pr_ctloutput)();   /* control output (from above) */
/* user-protocol hook */
    int      (*pr_usrreq)();      /* user request hook */
/* utility hooks */
     void     (*pr_init)();       /* initialization hook */
     void     (*pr_fasttimo)();   /* fast timeout (200ms) */
     void     (*pr_slowtimo)();   /* slow timeout (500ms) */
     void     (*pr_drain)();      /* flush any excess space possible */
";


   Note thatthe actual prototypes for the function pointers are omitted,
see the file sys/protosw.h for full definition.
   When protocol is started the pr_init() is called first to allow the
protocol to initialize all needed internal structures.  Then the input
process will call pr_fasttimo() and pr_slowtimo() entries periodically if

defined6.  The pr_drain() entry asks the protocol tofree all
non-critical memory buffers in a low-memory situation.
   Protocolscall each other through the protocol--protocol interface.  To
pass a packet up in the hierarchy a protocol calls the pr_input()-entry
of the protocol above it.  pr_output()-entry is called when a protocol
wishes to pass a packet down in the protocol hierarchy (towards network).
________________________________
   5or mbuf for short

   6Member function is defined when the value of its address is not NULL.


System Manual                   AmiTCP/IP                   Section 4.5    79



   Protocolssend control information to each other through the
pr_ctlinput() and pr_ctloutput() entries.
   All requests coming from the API are dispatched through the pr_usrreq()
entry.



4.5     Memory Management


As stated earlier, the memory managementof the protocol stack is done
with memory buffers.  An mbuf is a structure containinglittle amount of
storage (usually 128 bytes).  Some bytes of this storage are used for the
header, but most of it is used to storeuser data.   These small buffers
are linked together to get storage for larger data.
   Mbufs arehighly efficient in a network protocol environment where it
must be able to attach and strip protocol headers with minimum overhead
and most importantly, without copying the data as doing so.  When data is
stored in an mbuf chain, attaching a header is achieved by simply linking
the mbuf containing the header to the head of the chain.  Removing a
header is also done simply by removing the first mbuf or by incrementing
the data pointer inside the mbuf.
   In general there are two types of mbufs.  Ones with an packet header
and ones without.  An Mbuf with packet header is used as the first mbuf
of every packet.  This header contains extra information needed per
packet.  See the header file sys/mbuf.h for the mbuf header definition.
   Mbufs canbe chained in two dimensions.  First they may be linked to
form the storage for the whole message.  Second these messages may be
linked together so that the boundaries of messages are maintained.  This
second feature is mainly used by messageoriented protocols such as UDP.
   To gain efficiency an mbuf may have a reference to external memory page
(a cluster), where a big message is copied instead of splitting it apart
to many mbufs.  The main advantage of this feature is avoidance of
copying the data when sending it with TCP, since the clusters are shared

between copies7.



4.5.1   Mbuf  Functions


Mbufs are accessed through set of functions which can be grouped as
follows:



Maintenance


int mb_check_conf(void *dp, LONG newvalue)

    Check configurable variable whose address is dp.  Return TRUE if the
    newvalue is acceptable value for that variable.  See section 4.11 for
    information about the configuration.


BOOL mbinit(void)
________________________________
   7TCP must keep a copy of the sent data for possible retransmissions.


80    Section 4.5                  AmiTCP/IP                   System Manual



    Initialize the whole mbuf-subsystem.  Allocate a chunk of mbufs and
    clusters (using m_alloc() and m_clalloc).  Must be called before any
    other mbuf-related function (except that mb_check_conf() can be
    called anytime).


void mbdeinit(void)

    Free all resources used by mbuf subsystem.  Must be called as the
    last mbuf-related function in the program.


BOOL m_alloc(int howmany, int canwait)

    Allocate howmany mbufs and place them on the mbuf free list.  If
    canwait is true the caller can wait if memory is not readily
    available.


BOOL m_clalloc(int ncl, int canwait);

    Allocate ncl mbuf clusters and place them on the cluster free list.


struct mbuf *m_retry(int i, int t)

    Ask protocols to free space when short of memory and re-attempt to
    allocate an mbuf.


void m_reclaim(void)

    Ask protocols to free space when short of memory.



Allocation and Deallocation

struct mbuf *m_get(int canwait, int type)

    Allocate an mbuf of type type.  If no mbufs are available we can wait
    for them if canwait is M_WAIT. Initialize mbuf to contain internal
    data.


void MGET(struct mbuf *m, int canwait, int type)

    This is an macro form of above.


struct mbuf *m_gethdr(int canwait, int type)

    Allocate an mbuf of type type.  If no mbufs are available we can wait
    for them if canwait is M_WAIT. Initialize mbuf to contain a packet
    header and internal data.


void MGETHDR(struct mbuf *m, int canwait, int type)

    This is a macro form of above.


struct mbuf *m_getclr(int canwait, int type)

    Allocate an mbuf of type type.  If no mbufs are available we can wait
    for them if canwait is M_WAIT. If allocation succeeds the data buffer
    is zeroed before returning.


MCLALLOC(struct mcluster *p, int canwait)

    A macro to allocate an mbuf cluster.  The result is placed in p.


System Manual                   AmiTCP/IP                   Section 4.5    81



MCLGET(struct mcluster *p, int canwait)

    A macro to add a cluster to a normal mbuf.  M_EXT flag of the mbufis
    set on success.

struct mbuf *m_free(struct mbuf *m)

    Free an mbuf.  Next mbuf in the chain is returned, if any.

void MFREE(struct mbuf *m, struct mbuf *n)

    This is an macro form of above.  Successor mbuf is returned in n.

MCLFREE(struct mcluster *p)

    A macro to free an mbuf cluster.

void m_freem(struct mbuf *m)

    Free the whole chain of mbufs starting from m.



Utility Functions

struct mbuf *m_copym(struct mbuf *m, intoff0, int len, int canwait)

    Make a copy of an mbuf chain starting off0 bytes from the beginning
    of m, continuing for len bytes.  If len is M_COPYALL, copy to endof
    mbuf.

void m_copydata(struct mbuf *m, int off,int len, caddr_t cp)

    Copy data from an mbuf chain starting off bytes from the beginning,
    continuing for len bytes, into buffer cp.

struct mbuf *m_prepend(struct mbuf *m, int len, int canwait)

    Prepend a chain of mbufs (m) with new mbuf with len bytes allocated
    from the first mbuf aligned on a long word boundary.

void M_PREPEND(struct mbuf *m, int plen,int canwait)

    Macro version of above optimized for the most general cases.

void M_COPY_PKTHDR(struct mbuf *to, struct mbuf *from)

    Macro for copying an mbuf packet header from from to to.  from must
    have flag M_PKTHDR set, and to must be empty.

void M_ALIGN(struct mbuf *m, int len)

    Macro to set the m data pointer of a newly--allocated mbuf (with
    m_get()/MGET()) to place an object of the size len at the end of the
    mbuf, long word aligned.

void MH_ALIGN(struct mbuf *m, int len)

    As above, but for mbufs allocated with m_gethdr()/MGETHDR() or
    initialized by M_COPY_PKTHDR().

int M_LEADINGSPACE(struct mbuf *m)

    Compute the amount of space available before the current start of
    data in an mbuf.


82    Section 4.6                  AmiTCP/IP                   System Manual



int M_TRAILINGSPACE(struct mbuf *m)

    Compute the amount of space available after the end of data in an
    mbuf.


void MCHTYPE(struct mbuf *m, type t)

    Change mbuf to a new type.


void m_cat(struct mbuf *m, struct mbuf *n)

    Concatenate mbuf chain n to m.  Both chains must be of the same type.


m_adj(struct mbuf *mp, int req_len)

    Trim req_len bytes from the head of the mbuf chain mp if req_len is
    positive, else trim -- req_len bytes from the tail of the mbuf chain.


struct mbuf *m_pullup(struct mbuf *n, int len)

    Rearrange an mbuf chain so that len bytes from the beginning of the
    mbuf chain n are contiguous and in the data area of the mbuf so that
    the data can be used as a structure.



Utility Macros

type t mtod(struct mbuf *m, type t)

    Convert mbuf pointer to a pointer to the start of the data area of
    the mbuf casted to type t.


struct mbuf *dtom(type *x)

    Convert data pointer within an mbuf to mbuf pointer.



4.6     Concurrency Control


The protocol implementation in the BSD net/2 is driven by network and
timer interrupts and user processes calling the system functions.  As the
whole protocol stack is moved inside normal AmigaOS process, some
modifications are in place.
   The processor priority levels are the main concurrency control tool of
the BSD kernel.  The levels defined are SPL0 (user level), SPLSOFTCLOCK,
SPLNET and SPLIMP (the most privileged level).   Execution at a higher
level disables the execution at all lower levels.   InAmiTCP/IP the
concurrency control is implemented either with semaphores (when
debugging) or with prevention of the task switches (Forbid()/Permit()),
see section 5.3.1 on page 96 for the implementation notes.
   The protocol input and timeouts are driven by a single process that
manages the whole protocol stack.  The process sends appropriate IO
requests to the timer device and the SANA-II device drivers in question.
Actions are then taken as response to the returned requests.  Before any
protocol routines are called the priority level is raised either to
SPLSOFTCLOCK or SPLNET. After the function returns the priority level is
lowered back to SPL0 and the request issent back to the device driver.


System Manual                   AmiTCP/IP                   Section 4.7    83



   On the API side the concurrent execution of system calls is mostly
prohibited, because in UNIX the system calls are atomic in the sense that
there is never more than one system callin execution.  In AmigaOS the
shared library functions must be re-entrant so the protection must be
provided by the library functions themselves.
   The priority at which the main process runs must be above the default
value of 0 to provide enough time to process the networking protocols.
On the other side there is no sense to drive the main process at greater
priority than the SANA-II device drivers.



4.7     Network  Device  Drivers


AmiTCP/IP uses standard SANA-II driversas its external network device
drivers.  A little glue is needed to attach a SANA-II driver into BSD
net/2 code.



Network Interface

The BSD net/2 networking code provides aclean interface to the network
device drivers.  The network interface provides a consistent interface
for all protocols that may be present inthe BSD Unix kernel.  Each
hardware device is associated with an unique network interface which may
be used by one or more protocol families.
   The network interface is flexible enough to attach different SANA-II
network device drivers into the AmiTCP/IP networking system.  Common
part of all network interfaces is described in [Leffler et al 1991b  ]:


struct ifnet -
         char    *if_name;               /* name, e.g. "en" or "lo" */
         short   if_unit;                /* sub-unit for lower level driver */
         short   if_mtu;                 /* maximum transmission unit */
         short   if_flags;               /* up/down, broadcast, etc. */
         short   if_timer;               /* time 'til if_watchdog called */
         int     if_metric;              /* routing metric (external only) */
         struct  ifaddr *if_addrlist;    /* linked list of addresses per if */
         struct  ifqueue -
                 struct  mbuf *ifq_head;
                 struct  mbuf *ifq_tail;
                 int      ifq_len;
                 int      ifq_maxlen;
                 int      ifq_drops;
         " if_snd;                       /* output queue */
/* procedure handles */
         int     (*if_init)();           /*init routine */
         int     (*if_output)();         /* output routine (enqueue) */
         int     (*if_start)();         /* initiate output routine */
         int     (*if_done)();           /*output complete routine */
         int     (*if_ioctl)();         /* ioctl routine */
         int     (*if_reset)();         /* bus reset routine */
         int     (*if_watchdog)();      /* timer routine */
/* generic interface statistics */
         int     if_ipackets;            /* packetsreceived on interface */


84    Section 4.7                  AmiTCP/IP                   System Manual



         int     if_ierrors;             /* input errors on interface */
         int     if_opackets;            /* packetssent on interface */
         int     if_oerrors;             /* output errorson interface */
         int     if_collisions;         /* collisions on csma interfaces */
/* end statistics */
         struct  ifnet *if_next;
";


   Network interface for SANA-II devices are handled in the module
net/if_sana.c.  This is the only module aware of SANA-II devices inside
the AmiTCP/IP network process.  It hides most SANA-II specific details
from the rest of the code.



Module Initialization

ULONG sana_init(void)

    This initialization routine is called at startup time before any
    interfaces have been added to system.  It creates the common message
    port used for all SANA-II network interfaces.  It also attaches the
    loopback device into system.  It returns the signal mask of the
    message port, if its creation was successful.

void sana_deinit(void)

    This routine frees all resources allocated by the SANA-II interface
    module.  It aborts all pending IO requests, frees them, closes
    network device drivers and frees the corresponding network
    interfaces.  Finally it deletes the message port.



4.7.1   SANA-II Soft Network Interface

A message passing system based on the normal Exec IO requests is used to
transfer packets between the AmiTCP/IP and SANA-II devices.  The IO can
be either synchronous or asynchronous.  The SANA-II interface module has
a message port, which receives all fulfilled or aborted asynchronous IO
messages.  A dispatch method (currently a dispatch function pointer) have
been added to all asynchronously sent IOrequests.   Dispatching function
handles the received message in an appropriate way.
   A messagemay contain received packet, some buffers allocated for the
sent message or an event mask.  Dispatcher functions feed the received
data to the protocol input queues.  If needed, the protocol input
routines are run.  Dispatchers also free the memory allocated for the
sent packets, or relays events to the higher level protocols.
   Because the interface for the SANA-II device driver must handle many
different protocols and network adapters, it has some private data hidden
from the rest of the system.  The struct sana_softc network interface is
defined in file net/if_sana.h:

/*
 * SANA-II Interface descriptor
 *      NOTE: most of the code outside will believe this to be simply
 *      a "struct ifnet". The other information is, on the other hand,
 *      our own business.


System Manual                   AmiTCP/IP                   Section 4.7    85



 */
struct sana_softc -
  struct ifnet    ss_if;               /* network-visible interface */
  struct in_addr  ss_ipaddr;          /* copy of ip address */
  ULONG            ss_hwtype;           /* wiretype */
  UBYTE            ss_hwaddr[MAXADDRSANA]; /* Generalhardware address */
  struct Device  *ss_dev;              /* pointer todevice */
  struct Unit    *ss_unit;             /* pointer to unit */
  VOID            *ss_bufmgnt;         /* magic cookie for buffer mngement */
  UWORD            ss_reqno;            /* # of requests to allocate */
  struct IOIPReq *ss_reqs;             /* allocated requests*/
  struct MinList  ss_freereq;         /* free requests */
#if     INET
  struct -
    UWORD reqno;               /* for listening ip packets */
    UWORD sent;
    ULONG type;
  " ss_ip;
  struct -                        /* for ARP */
    UWORD reqno;
    UWORD sent;
    ULONG type;                  /* ARP packet type */
    ULONG hrd;                    /*ARP header type */
    struct arptable *table;     /* ARP/IP table */
  " ss_arp;
#endif  /* INET */
  UWORD            ss_rawreqno;        /* for raw packets */
  UWORD            ss_rawsent;
  struct sana_softc *ss_next;
  char             ss_name[IFNAMSIZ];  /* namelives here */
";

   There isan external interface to this structure via SIOCSSANATAGS and
SIOCGSANATAGS ioctls.


struct ifnet *iface_find(char *name)

    This function initializes a network interface for given interface.
    It is called on a non-existent interface from ifunit().  It tries to
    open the appropriate SANA-II device driver, and if successful it
    initializes a descriptor and calls if_attach() with it.

    Its argument is the device driver name concatenated with a slash and
    unit number.  This name is used by AmiTCP/IP to open appropriate
    unit of the SANA-II driver.

    The initialization routine provides the specified SANA-II network

    device unit with the CopyToBuf() and CopyFromBuf() function tags8.
    Those tags are used to copy data to and from the internal buffers of
    the network device.  The taglist given to the device driver is
    defined in file net/sana2copybuff.c.

    After successful open iface_find() initializes the appropriate
    members of the new sana_softc structure.  It stores the device and
    unit pointers, magic cookie for buffer management, hardware type, MTU
________________________________
   8For discussion for these functions, see [SANA-II 1992 add  ]


86    Section 4.7                  AmiTCP/IP                   System Manual



    and address length.  It also searches for the hardware type specific
    taglist, and sets the rest of interface parameters according the
    taglist.

    Next the interface initialization routine attaches the new network
    interface into ifnet list with if_attach().  Then it initializes
    interface with if_init().



Interface Routines

BOOL sana_poll(void)

    The AmiTCP/IP processes received messages by calling this function.
    It effectively hides the actual implementation from the rest of the
    system.  This routine is called when AmiTCP/IP receives the signal
    allocated by sana_init(), and it returns TRUE, if itshould be called
    again before Wait().

    sana_poll() retrieves messages from the message port, dispatches them
    and then runs the input queues.

int sana_output(struct ifnet *ifp, struct mbuf *m0,
                struct sockaddr *dst, struct rtentry *rt)

    This function is used as the if_output() method.  It tries to get a
    free IO request from the ss_freereq list.  If no free request is
    available it drops the packet.  It attaches the packet m0 to request,
    sets dispatching function to free_written_packet() and sends the
    request to the device driver.

    The raw packets to the SANA-II interface use the following variation
    of socket address.  The addressing family of the raw packets must be
    AF_UNSPEC. Currently only the ARP uses the raw SANA-II packets.


    /*
     * A socket address for a generic SANA-II host
     */
    struct sockaddr_sana2 -
       u_char ss2_len;
       u_char ss2_family;
       u_long ss2_type;
       u_char ss2_host[MAXADDRSANA];
    ";


void sana_ioctl(struct ifnet *ifp, int cmd, caddr_t data)

    This function is used as the if_ioctl() method.  SANA-II devices and
    their respective network interfaces are configured via raw sockets by
    the IoctlSocket() requests.  When the sana_ioctl() gets the
    SIOCSIFADDR request, it changes the IP address of the interface.  The
    SIOCGIFFLAGS ioctl is used to set the parameter flags of the

    interface9.

    Special SANA-II configuration is done with SIOCSSANATAGS ioctl.  It
    passes a tag list to the parse_sana_param_tags() function.
________________________________
   9See file sys/ioctl.h for full listof all ioctls


System Manual                   AmiTCP/IP                   Section 4.7    87



void if_down(struct ifnet *ifp)

    This function pulls into if_ioctl() from net/if.h.  if_down() marks
    the interface down and informs all affected network protocols about
    the matter.  If the interface handles SANA-II device, it calls
    sana_down(), which handles the dirty work to put theinterface down.

static void sana_run(struct sana_softc *ssc, int n, struct ifaddr *ifa)

    sana_run() configures the SANA-II interface and allocates the IO
    requests to use with the SANA-II device driver.  Because the SANA-II
    device can be configured only once (see S2_CONFIGINTERFACE in
    [SANA-II 1992 add  ]) the initialization routine does not configure it.
    Among other things the hardware address of the network adapter is set
    in configuration process.  This function is called by the SIOGSIFADDR
    ioctl, which also sets the protocol address of the interface.

static void sana_up(struct sana_softc *ssc)

    sana_up() marks interface up and enables the interface to listen the
    packets from the network.  It sends read request with an appropriate
    packet type number and dispatch function to the device.

static BOOL sana_down(struct sana_softc*ssc)

    sana_down() aborts all pending requests sent to a SANA-II device
    driver.

static void sana_ip_read(struct sana_softc *ssc,
    struct IOIPReq *req) and

static void sana_arp_read(struct sana_softc *ssc,
    struct IOIPReq *req)

    These dispatch functions are used to feed data from a network device
    to the protocol input queues.  The network interface has not the
    input routines as members.  Dispatching functions allocate mbufs for
    the next packet and send IO requests again to the network device.



Statistics

BSD Network interface contains a lot ofexcessive statistical data.  Most
of it is made redundant by the statistics gathered by the SANA-II driver.
Because network statistics are not retrieved by looking at /dev/kmem,
there is no need to gather BSD compatible statistics.  A public ARexx
port, named AMITCP, is set up for statistics retrieval and we can use
appropriate SANA-II commands to get needed data when asked.



4.7.2   ARP

The requirements for the ARP implementation for a SANA-II interface
differ radically from the original implementation BSD. The original code
was written exclusively for the Ethernet, which has a global addressing
scheme and a fixed address length.
   The SANA-II ARP (in the module net/sana2arp.c) holds a separate address
mapping cache for each interface.  The number of entries in the cache may


88    Section 4.8                  AmiTCP/IP                   System Manual



be configured at the run time.  The hardware address length varies from
one interface to another.  The mapping caches are hashtables with linked
lists, so there is no limitations in thebucket size.  ARP Table locking
is done with a signal semaphore insteadof spln() functions.
   The ARP table is externally accessed only by IoctlSocket() calls.  With
the new SIOCGARPT ioctl the whole ARP cache may be read at once.  There
is no need to awkwardly read /dev/kmem.



4.8     Logging


As everything is not predictable, programs like to inform the user about
certain situations to help the user and/or maintainer to get programs
work better.  This is the motivation for log() and panic() functions.
The fact that the file I/O routines can't be called from interrupts must
be taken into account, since a program may want to inform the user even
while executing at an interrupt level.
   Among thevery few functions of the AmigaOS which are callable from
interrupts are GetMsg() and PutMsg().  These are used to implement the
logging subsystem.
   When AmiTCP/IP has something to tell to the user, it first checks if
there is any free messages available.  There is only alimited number of
these messages to use, since they are preallocated during

initialization10.  If there is no message available, a counter indicating
that the message could not be deliveredis incremented.  If a free
message is available, the text given bycaller is printed into the buffer
of the message.  Then the message is sent to the private port of the
NETTRACE task.
   The NETTRACE task is created early in the initialization of the
AmiTCP/IP. This task waits for incomingmessages and when one arrives,
it prints the message to the log windowand/or log file.  Then message is
freed by sending it back to AmiTCP/IP for reuse.   If loss of log
messages is detected, log() is called totell that to the user.
   The functions are defined as follows:


int log(unsigned long level, const char*fmt, ...)

    This logs a message with format specified in exec.library/RawDoFmt(),
    similar to the printf().  It is preceded with ``<N>'' where N is a
    level as defined in file sys/syslog.h.

void panic(const char *fmt, ...)

    When this function is called, we are in BIG trouble.  If task, which
    called this, is not AmiTCP/IP, we just halt this task and send a
    message to AmiTCP/IP to halt immediately and free all resources.
    Format is as in exec.library/RawDoFmt().

    If AmiTCP/IP runs into a panic() it first patches all API functions
    to return an error code to the caller.  Then, if the panic() was not
    in the context of the AmiTCP/IP it signals the AmiTCP/IP and halts.
    As the AmiTCP/IP receives the signal, it send a message to the log
________________________________
  10This is because memory cannotbe allocated from interrupt code.


System Manual                   AmiTCP/IP                   Section 4.9    89



    and signals all application programs waiting for network to take
    attention.  As this is done, it opens an User Requester to inform the
    user.  After the user responds, AmiTCP/IP waits for all library
    openers to close libraries and finally unloads itself from the
    memory.

int printf(const char *fmt, ...)

    Like the normal C--library printf (with format of
    exec.library/RawDoFmt()) except that the printing is done using the
    logging mechanism.

int sprintf(char *buf, const char *fmt,...)

    As in a normal C--library.  Format is as in exec.library/RawDoFmt().


   All functions (except panic()) return number of printed (or logged)
characters.



Initialization Routines

BOOL log_init(void)

    This function initializes NETTRACE subsystem by opening
    intuition.library for opening UserRequest in the case of panic().
    The the log messages are initialized to use by preallocating memory
    for them.

    Then NETTRACE is started and AmiTCP/IP waits for a signal from it.
    If NETTRACE success in it's initialization, then it sends a message
    back, which is then replied.  If initialization fails, a variable is
    set to specific value and CTRL-F is sent to the AmiTCP/IP. If all
    this succeeds, the log messages are initialized and sent to
    logReplyPort which works as a queue for the free messages.

void log_deinit(void)

    This works as reverse to initialization process.  If NETTRACE is
    still running, a message is sent to it telling it to terminate.  Then
    AmiTCP/IP waits until the message is replied.  Then the memory
    reserved by the messages can be freed.  Finally the intuition.library
    is closed.



4.9     ARexx Interface


The ARexx port of the AmiTCP/IP is maintained by the NETTRACE task.  The
messages are parsed with parseline() (defined in kern/amiga_config.c).



Initialization Routines

ULONG rexx_init(void)

    This initialization routine is called at the startup time of the
    NETTRACE process.  It opens the utility.library and the
    rexxsyslib.library to be used by the ARexx code and creates a public


90    Section 4.10                 AmiTCP/IP                  System Manual



    ARexx message port.  The signal mask of the ARexx port is returned
    upon a successful initialization.


void rexx_deinit(void)

    Free all resources allocated by the ARexx interface module.  First
    the ARexx port is removed from the system's list of message ports so
    that no-one is able find the port any more to send new messages.
    Then all pending messages are returned with error code set.  Finally
    the ARexx port is deleted and libraries opened by rexx_init() are
    closed.



Reply Routine

BOOL rexx_poll(void)

    Checks if any ARexx messages has arrived and handles them one at a
    time.  The parseline() function is used to parse and execute the
    given command.  Returns TRUE if there might still be messages to
    handle, otherwise the return value is FALSE.



4.10     Application  Interface  Concepts


4.10.1   SocketBase -- an Extension of the Task Structure

In Unix systems, where the network codeis integrated into the kernel, a
process structure holds fields for per-process information of network
related data.  In AmiTCP/IP, where socket API is implemented as a shared
library, each opener gets a newly created library base that holds data
used by the AmiTCP/IP system.  Each library base function makes sure
that the caller is from the right Amigatask and refuses to operate if
wrong task is attempting to use it (seesection 5.5 on page 100 for
detailed information).



4.10.2   The System Call Semaphore and Task Priorities

Currently, when program enters to some of socket library functions, it
attempts to get semaphore to hold othercallers executing library code
simultaneously.  This is done so, since in Unix system,where this code
originally runs, doesn't pre-empt process that is executing system call.
In BSDSS, where ``Unix system calls'' run in user mode, system call
emulation glue uses a mutex to prevent simultaneous use of that part of
the server code.  Although spl functions are used in NET/2 code to
prevent simultaneous access of criticalsections, there may still be some
sections that leave out protection if system call semaphore is removed.
Unnecessary system call semaphore usageis going to be removed in later
releases.  Hopefully it, and the overhead it generates,becomes obsolete.
   The priority of the application process is raised to the same with the
AmiTCP/IP, while the application executes AmiTCP/IP code.  This is to
prevent situations where a process witha low priority gets blocked for a
long time while holding e.g.  the system call semaphore, since otherwise


System Manual                  AmiTCP/IP                 Section 4.11    91



all networking programs would be blockedwith it.   Thisapplies to all
semaphores used internally by the AmiTCP/IP, not just the system call
semaphore.



Initialization Routines

Making application interface visible andoperative contains a few steps:
call to api_init() creates the master socket library base and initializes
semaphores and lists API needs.  Library base is not inExec library base
list yet.  Routine api_show() checks first if bsdsocket.library is
already in Exec list and if not, calls Exec AddLibrary() to make it
visible.
   AmiTCP/IPcan remove socket library from the Exec list at any time,
i.e.  make it not visible, by calling api _hide().  No new socket bases
can be opened after this call.  Socket bases opened before api _hide()
operate normally.  If AmiTCP/IP calls api_show() again, new libraries can
be opened.
   api_setfunctions() takes all socket library bases out of operation.  It
sets all function vectors in every socket base to return an error.  This
function is called if AmiTCP/IP panic()ed and all libraries are expected
to be closed.
   When application interface is to be removed from system, api_deinit()
is called.  It waits for all opened libraries to closeand then calls
expunge function to deallocate the master socket base from the memory.



4.11     Configuration  Variables


The configuration variable definitions are stored into a structure named
cfg_variable.  It is defined in kern/amiga_netdb.h as follows:


/* Variable types */
/* Note: Query calls value, Set calls notify functions */
enum var_type
-
 VAR_FUNC = 1,           /* value is function pointer */
 VAR_LONG,               /* value is pointer to LONG */
 VAR_STRP,               /* value is pointer to string */
 VAR_FLAG,               /* LONG value is set once */
 VAR_INET,               /* struct sockaddr_in */
 VAR_ENUM                /* value is pointer to long, whose value is set
                             according to a enumeration string in notify*/
";


typedef LONG
  (*var_f)(struct CSource *args, UBYTE **errstrp, struct CSource *res);
typedef int (*notify_f)(void *pt, LONG new);


/* Configureable variable structure */
struct cfg_variable -
  enum var_type type;            /* type of value */


92    Section 4.12                 AmiTCP/IP                  System Manual



  WORD  flags;                   /* see below */
  const UBYTE *index;            /* optional index keyword list */
  void  *value;                  /* pointer to value... */
  notify_f notify;               /* notification function */
";


#define boolean_enum (notify_f)"NO=FALSE=OFF=0,YES=TRUE=ON=1"


/* Variable flags */
#define VF_TABLE    (1<<0) /* with an index... */
#define VF_READ     (1<<1) /* readable */
#define VF_WRITE    (1<<2) /* writeable */
#define VF_CONF     (1<<3) /* writeable only during configuration */
#define VF_RW       (VF_WRITE_VF_READ)
#define VF_RCONF    (VF_CONF_VF_READ)
#define VF_FREE     (1<<8) /* free when replaced? */


   The configuration file (by default AmiTCP:db/AmiTCP.config) is read
with the function readconfig().  This function also parses the command
line arguments.



4.12     Network  Database


The network database is initialized by the init _netdb() function.  This
function allocates the NetDataBase structure and parses the file
AmiTCP:db/netdb.  The NetDataBase structure is definedas follows:


struct NetDataBase -
  struct SignalSemaphore ndb_Lock;
  struct MinList          ndb_Hosts;
  struct MinList          ndb_Networks;
  struct MinList          ndb_Services;
  struct MinList          ndb_Protocols;
  struct MinList          ndb_NameServers;
  struct MinList          ndb_Domains;
";


   This structure contains a lock and lists for the different network
database entries.  The lock semaphore is obtained in the shared mode for
reading, and in the exclusive mode for writing.   See section 2.5.1 for
the information about the different entries.





Chapter 5



Implementation Notes



This chapter describes some points of the implementation of the
AmiTCP/IP. The code that is not changedfrom the BSD net/2 -release is
not reviewed.  [Leffler et al 1989 ] describes the design and
implementation of the BSD Unix, including the networking system.
[Leffler et al 1991b ] is also very helpful.
   Most of the knowledge gathered during this project is gained by reading
the source code itself.  This chapter does not try to make that totally
unnecessary.



5.1     Time outs


The Unix timeout() function implements the time out needs of the Unix
kernel.  When kernel code calls timeout(), the functiongiven as argument
will be called after the specified timeout has elapsed.  In AmigaOS time
outs are provided by the timer device.  AmiTCP/IP sendstime out
requests to the device and gets them back when the time specified has
elapsed.
   The functions called by the time out service are:


if_slowtimo()

    This is the time out function of the network interfaces and is
    defined in net/if.c.


arptimer()

    Handles the time outs of ARP protocol (net/sana2arp.c).


pfslowtimo()

    This is the main slow time out function for all protocols.  It calls
    the pr_slowtimo() function of each configured protocol.   The interval
    of this timer is 500 ms (kern/uipc_domain.c).


pffasttimo()

    Is the corresponding function for fast (200 ms) time outs.



                                      93


94    Section 5.1                  AmiTCP/IP                   System Manual



   The request structure used by AmiTCP/IP has few fields in addition to

the normal struct timerequest1.  The structure is defined in
kern/amiga_time.h as follows:

struct timeoutRequest -
  struct timerequest timeout_request;   /* timer.device sees only this */
  struct timeval     timeout_timeval;   /* timeout interval */
  TimerCallback_t    timeout_function;  /* timeout function to be called */
";


   In this implementation the time out functions themselves do not call
any time out services, but the functionsare called by timer_poll(),
which is called by main() when there might be a message to handle (e.g.
when the timer signal is received).  timer_poll() checks the reply port
to see if there really is a message to handle.   Afterthe time out
function is serviced timer_poll() sends the request back to the timer
device and returns.
   Time outservice is implemented by files kern/amiga_time.c and
kern/amiga_time.h.  The functions defined are:


ULONG timer_init(void)

    Initializes the time out subsystem by allocating the IO requests and
    opening the timer device.  Note that AmiTCP/IP uses functions that
    are new to version 36 of the timer device, so the code refuses to
    success with Kickstart 1.3 (or lower).

    Returns the signal mask to wait for if successful.

void timer_deinit(void)

    Frees all resources used by time out subsystem.

void timer_send(void)

    Sends time out requests allocated by timer_init() tothe timer
    device.

struct timeoutRequest *createTimeoutRequest(TimerCallback_t fun,
    ULONG seconds, ULONG micros)

    Creates a new time out request.  This can be called only after
    successful timer_init().

void deleteTimeoutRequest(struct timeoutRequest *tr)

    Deletes requests created by createTimeoutRequest().

BOOL timer_poll(VOID)

    Checks if there are any timer requests in the reply port and if there
    is handles them by calling the handleTimeoutRequest().  Then it sends
    the request back to the timer device.

void handleTimeoutRequest(struct timeoutRequest *tr)

    Inline function which simply calls the function specified in the time
    out request.
________________________________
   1See standard Amiga include file devices/timer.h


System Manual                   AmiTCP/IP                   Section 5.2    95



void sendTimeoutRequest(struct timeoutRequest *tr)

    Inline function which sends the request to the timer device.


   See the files kern/amiga_main.c and kern/amiga_time.c for example of
the usage.



5.2     Memory Management


5.2.1   Mbufs

Mbufs are ported just as they are.  Memory is allocatedin small chunks
for both mbufs and clusters.  The size of the cluster and the number of
mbufs to allocate in one chunk are configurable variables, see section
2.4 for summary of the configurable variables in general.
   Note thatsince data must be copied at the SANA-II interface there is
no need to use trailer protocols (whosemain gain is avoidance of that

copy) and so the mbuf clusters need notbegin at page boundaries2.   This
fact lead to the implementation of the clusters where the size of the
cluster may be arbitrary (now user configurable) and the reference count
of the cluster is stored in a little header before the actual data.
   One noteon allocating memory for the mbufs:  Since the mbuf must be
perfectly aligned (i.e.  128 byte mbuf must be 128--aligned), we need to
allocate one extra mbuf to be able to align the mbufs in arbitrary memory
chunk returned by Exec AllocMem().
   The 'canwait' argument of the mbuf functions is ignored by now, more
memory will be allocated if limit of maximum memory usage is not hit.
This is all right as long as the mbuf allocation functions are not called
from interrupts.  The only functions in the AmiTCP/IP which may get
called from the interrupt code are the SANA-II callback functions
m_copy_from_mbuf() and m_copy_to_mbuf()defined in file
net/sana2copybuff.c.
   The function descriptions for the mbufs are on section 4.5.  See files
sys/mbuf.h and kern/uipc_mbuf.c for the actual implementation.



5.2.2   malloc() & free()

Do not call the malloc() and free() functions directly!  Since AmiTCP/IP
is multi--threaded program these functions are not safe, since they use
static data.  File sys/malloc.h defines two inline functions to be used
instead.  They are defined as follows:


static inline void * bsd_malloc(unsignedlong size, int type, int flags)

    This function calls malloc() to allocate memory of size size and type
    type.  The types are defined in sys/malloc.h and are used for
    bookkeeping purposes.  The flags may have either value M_WAITOK or
    M_NOWAIT. The flags are not used by this implementation, however, but
    are defined for portability.
________________________________
   2Well, there is no virtual memory in Amiga either.


96    Section 5.3                  AmiTCP/IP                   System Manual



static inline void bsd_free(void *addr,int type)

    Frees memory allocated by bsd_malloc().


   The malloc() and free() are made safe by malloc_semaphore, which
protects mallocs and frees from collisions.   It is obtained before the
actual calls to malloc() or free() and released after them.
   In addition to these functions sys/malloc.h defines macro versions for
the most usual usages.
   Initialization for these functions is done by:


BOOL malloc_init(void)

    Initializes the malloc_semaphore.  This must be called early in the
    initialization process, since bsd_malloc() nor bsd_free() cannot be
    called before malloc_semaphore is initialized.



5.3     Concurrency Control


5.3.1   Processor Priority Levels

In Unix systems the critical sections are mainly protected by raising the
processor priority level (i.e.  preventing interrupts upto a certain
level).  This crude way might hurt a real time operating system as the
AmigaOS, so it can not be implemented assuch.   Besides, the AmiTCP/IP
runs as a normal user level process which has no needed privilege to
alter the interrupt levels of the processor.
   The implementation in AmiTCP/IP is twofold; a semaphore is used in the
debugging mode and task switch prevention is used in the production
version.  Using semaphore makes debugging easy as single stepping and
tracing is possible while keeping the system alive.   The semaphore adds
certain overhead which is not acceptablein the production version, so
the prevention of the task switches is used.
   When thepreprocessor symbol DEBUG is defined the spl_semaphore is
used.  When this semaphore is free the process is at level SPL0 (user
level) and when the semaphore is allocated the process is at
``interrupt'' level (SPLSOFTCLOCK, SPLNET or SPLIMP), effectively
disallowing anyone else to enter critical section.   When the symbol DEBUG
is not defined the functions and macrosare defined differently.  They
manipulate directly the Task Disable Nest Count (TDNextCnt field of the
SysBase).  This field is normally used by Exec functions Forbid() and
Permit() which increment and decrement the value of the field,
respectively.  Since an assembler macro is provided byCommodore for the

Forbid() function, the semantics of thefield cannot change in the future3.
The semantics of the TDNestCnt is littleabused by the AmiTCP/IP, however.
The value of the spl level in question is directly assigned as the value of
the field.  This is not visible outside of the AmiTCP/IP, since basically
functions which use this field either directly or indirectly (via Forbid()/Perm*
 *it())
need to return the value of the field asit was when the function was called.
This is also the semantics of the usageof the spl functions.
________________________________
   3If it would, then all the codeusing that official macro would break.


System Manual                   AmiTCP/IP                   Section 5.3    97



   The spl_semaphore is initialized by the function BOOL spl_init(void)
which is called among the very first functions in the initialization
process.
   The function spl _n(int) (defined in sys/synch.h) is used to alter the
priority levels.  In the non-debugging mode there are two other
functions, too:  spl_const(), which isused with a constant (non-zero)
argument, and spl_0() which is used to switch to the level 0.  In
addition, a macro has been defined for each separate level for
portability.  The macros are as follows:


spl0() switches to the normal execution level.


splsoftclock()  is the level on which timer eventsare executed.


splnet() is the level of the network interrupts in UNIX.


splimp() is the highest of the priority levels used in the networking
    code.  For example, mbuf functions are executed at this level.


   These macros return the previous level which may then be set back with
splx(int)-macro, which sets the level tothe level given as argument.



5.3.2   Sleeping Facilities


Sleeping facility is implemented by kern/kern _synch.c.  Processes sleep
on a channel, which is the key used to identify sleepers.  Usually this
is some address which is unique to the calling process.  Socket base
structure for the sleeping task is linked in the sleep queue before the
actual sleep is started.  This is how the waking task can find the
sleeper to wake up when something happens on the channel the process is
sleeping on.
   The sleepqueue is implemented as a hash table, where the channel value

is mapped to an index of a sleep queue with the hash function4
SLEEP_HASH() (defined in kern/kern_synch.c).
   The actual sleep is implemented by sending a time out request for the
time out duration to the timer device.  The sleep completes on the time
out, a wakeup, a break signal or users specified signal.
   Note thatall critical resources (e.g.  semaphores) must be freed
before sleeping, since otherwise the whole networking code hangs.
tsleep() does this for you.
   The functions which implement the sleep system are:


BOOL sleep_init(void)

    This initializes the sleep_semaphore and the sleep queues.   Thismust
    be called before any other functions of this module.


int tsleep(struct SocketBase *p, caddr_tchan,
    char *wmesg, const struct timeval *time_out)
________________________________
   4Actually a macro.


98    Section 5.3                  AmiTCP/IP                   System Manual



    This function is the function usually called by the processes5 and
    implements the sleep by using the other functions of this module.
    The caller goes to sleep for at most the time specified in the struct
    timeval argument.  chan is the channel to sleep on.  wmesg is a
    string which is marked in the socket base (p) as the reason to sleep.
    Currently no-one ever reads it, though.


void wakeup(caddr_t chan)

    Wakes up any sleepers on channel chan.  Searches the sleep queue for
    entries with key chan and wakes them up by first clearing the key
    (p_wchan field of the socket base structure) and then signalling the
    process with the signal of the time out message.  The usage of the
    sleep queues and the p_ fields in the socket base structures are
    protected with sleep_semaphore, which must be obtained before even
    reading the sleep queues.

    Note that since a task in AmigaOS may get signals anytime, the
    sleeper checks the p_wchan field on reception of thesignal and if it
    is nonzero it goes to sleep again.


void tsleep_send_timeout(struct SocketBase *p,
    const struct timeval *time_out)

    First ensures that the message previously sent to the timer device is
    back.  Then sends timer device a time out request for duration
    specified in time_out if it is not NULL. The requestsent is
    allocated when the library is opened.


void tsleep_abort_timeout(struct SocketBase *p,
    const struct timeval *time_out)

    Aborts the time out sent by the tsleep_send_timeout().  This function
    must be used when the time out must be cancelled (when the sleeper is
    waken up).

    This function just sets the timer reply port (timerPort field of the
    socket base) to the mode in which reception of the message does not
    cause any action.


void tsleep_enter(struct SocketBase *p,caddr_t chan, char *wmesg)

    Puts the caller on to a sleep queue.


int tsleep_main(struct SocketBase *p, ULONG wakemask)

    Waits for either time out, wakeup, break or user defined action to
    happen.  The sigIntrMask field of the socket base structure defines
    which signals will cause a break.  Return value of EINTR is returned
    if any of the signals specified in that mask are received.  In
    addition the signals are set back with SetSignal() for the user
    program to be able to detect them.  The wakemask argument specifies a
    mask for signals which should cause a return from the sleep.  In such
    case the return value ERESTART is returned.
________________________________
   5Only WaitSelect() system calluses sleeping facilities without this

function.


System Manual                   AmiTCP/IP                   Section 5.4    99



    On exit the process is guaranteed not to be in the sleep queues any
    more, but the time out remains active if it is not the reason for
    return.  Return value on wakeup is 0 and on time out EWOULDBLOCK is
    returned.



5.4     Socket  Library  Creation  Procedure


Since a new socket base is created eachtime a different task opens the
AmiTCP/IP socket library, the procedureis a bit more complicated than
on libraries where the same library baseis returned (See
[RKM Libraries 1992 ]).  There is, for example, two socket library bases
in use.  All code discussed here is located in api/amiga _api.c.



5.4.1   Master Library Base

This is the library base that is made shown by api_show() (see section
4.10.2).  It is placed in Exec's librarylist.  This is of type struct
Library and contains information that anoutsider can read by scanning
through the Exec library list.  Information available is version and
revision numbers and count of tasks thathave (application) library base
open.
   Master library base has only functions ELL_Open() and ELL_Expunge().
When applications opens the socket library, the Exec calls ELL_Open().
This function creates new application socket bases and increments the
reference count of open application library bases.   Ifthe calling task
has a socket base open already, a new socket base is not created but the
reference count of task's socket base isincremented and the base pointer
is returned to the caller.  This feature has many useful possibilities,
for example in intermediate libraries which need to manipulate the
sockets of the calling task.
   ELL_Expunge() does (not) do one task.  When it is called, it checks if
there is any libraries still open or ifAmiTCP/IP lets this function
execute further (in fact, currently thissecond check is sufficient since
only AmiTCP/IP can close the library andit doesn't do it until all
bases has been closed.  The next Remove() is there forfuture reference
too).  Then, the memory of the master library base is deallocated and
NULL is returned (no AmigaDOS seglist tofree).   The SIGBREAKF _CTRL_C
signal that is sent with the global varianble SB _Expunged set to TRUE
notifies api_deinit() function about the fact that now all libraries are
closed.



5.4.2   Application Library Bases

These are the library bases that are returned to the openers of the
socket library.  In this base the Open() function is obsolete since all
OpenLibrary() calls go through the master socket base.  Exec and
AmiTCP/IP generated Expunge() calls go also through the master socket
base.
   UL_Close() is the close function for all application library bases.
First it decrements the reference countof this base and returns NULL if


100    Section 5.5                 AmiTCP/IP                  System Manual



there are still references left (again,NULL informs Exec that there is
no AmigaDOS seglist needed to be removed).
   If thereare no more references to this library base, following steps
are taken to remove it from the memory:  All socket descriptors still
open are closed.  The base is removed from the AmiTCP/IP list of open
application socket bases.  The timer request is deallocated.  Then the
library base is removed from the memoryand open count of application
socket bases is decremented in the master library base.  Finally,
ELL_Expunge() is called if the open count reached zero and the LIBF_DELEXP
flag is set (by a previous ELL_Expunge() call).



5.5     The  SocketBase  Structure


The SocketBase structure is defined in file api/amiga_api.h as follows:


struct SocketBase -
  struct Library         libNode;
/* "Global" Errno */
  WORD                   errnoSize;
/* -- now we are longword aligned -- */
  UBYTE *                errnoPtr; /* this points to errno */
  LONG                   defErrno;
/* Task pointer of owner task */
  struct Task *          thisTask;
/* task priority changes (WORDS so we keep structure longword aligned) */
  WORD                   myPri;       /* task's priority just after libcall */
  WORD                   libCallPri; /* task's priority during library call */
/* -- descriptor sets -- */
  WORD                   dTableSize;
  WORD                   nextDToSearch;
  struct socket **      dTable;
/* AmiTCP signal masks */
  ULONG                  sigIntrMask;
  ULONG                  sigIOMask;
  ULONG                  sigUrgMask;
/* -- these are used by tsleep()/wakeup() -- */
  char *                 p_wmesg;
  queue_chain_t          p_sleep_link;
  caddr_t                p_wchan;         /* event processis awaiting */
  struct timerequest *  tsleep_timer;
  struct MsgPort *      timerPort;
/* -- pointer to select buffer during Select() -- */
  struct newselbuf *    p_sb;
/* -- per process fields used by various'library' functions -- */
/* buffer for inet_ntoa */
  char inet_ntoa[20]; /* xxx.xxx.xxx.xxx"0 */
/* pointers for data buffers that MAY beused */
  struct DataBuffer  selitems;
  struct DataBuffer  hostents;
  struct DataBuffer  netents;
  struct DataBuffer  protoents;
  struct DataBuffer servents;
";


System Manual                  AmiTCP/IP                 Section 5.6    101



   libNode is a normal library base structure and is used by the system.
Since in this implementation each openergets a task specific library
base, AmiTCP/IP links all ``user librarybases'' together using Node
field of libNode.
   When socket library function encounters an error, it saves the value of
the error to the memory location addressed by errnoPtr.  errnoSize
specifies the size of the variable pointed by the errnoPtr.  By default
errnoPtr points to the defErrno but canbe changed to point any memory
location -- usually to the global errnovariable in the context of the
user task.
   In entryof each bsdsocket.library function call, value of thisTask is
compared to the task pointer of callingtask to make sure right task is
calling the function.  This variable is also used to find library base of
some executing task.
   When taskis executing system calls in bsdsocket.library, its process
priority is changed to the same as thatof the AmiTCP/IP task in order
not to hold semaphores and block the whole network system.  If some
higher priority process becomes active and a lower priority task is
holding some vital semaphore of the AmiTCP/IP then the precess cannot
continue to run.  The manipulation of the process priorities uses myPri
and libCallPri fields of the socket base.
   dTableSize is the number of current maximum limit of socket
descriptors.  dTable is the descriptor table containingpointers to
socket structures, i.e.  sockets.  nextDToSearch makes searching of free

socket descriptor faster6.
   sigIntrMask is a task specific mask of the signals which should break
the Wait() call in the tsleep_main().  Reception of such signals causes
the system calls to return -1 and the error code pointed by errnoPtr to
be set to EINTR. sigIOMask field specifies the signals to send when
asynchronous notification is requested.  Signals specified in sigUrgMask
are sent when out of band data is received.   These masks implement the
functionality of the SIGIO and SIGURG signals of the Unix systems,
respectively.  All these masks can be set with the SetSocketSignals() API
call.  The default mask for the sigIntrMask specifies the signal for the
ctrl-C, other two are zero by default.
   The nextgroup of variables are used by tsleep() and wakeup().  p_wmesg
points to a string telling the reason why task is sleeping.  p _sleep_link
is used to chain library bases in the sleep queues.   Waiting channel key
is hold in variable p_wchan and data handling time outs in variables
tsleep_timer and timerPort (more about this in section 5.3.2 on page 97).
   WaitSelect() inserts one selitem on each socket it wants event
information of.  p_sb points to a newselbuf that contains these items.
   Some APIfunctions in the original environment use static buffers to
store their output.  As a shared library cannot use static buffers (to be
re-entrant), the buffers must be allocated dynamically.  The SocketBase
structure has space for the output buffer for the Inet_Ntoa() and
pointers for other needed buffers.  These buffers are allocated only when
needed.
________________________________
   6Semantics of allocating lowestfree socket descriptor is preserved.


102    Section 5.6                 AmiTCP/IP                  System Manual



5.6     The  Application  Program  Interface



Most of API code is original NET/2 codetaken from BSDSS7. BSDSS mutexes
are replaced by Amiga semaphores and struct proc references are changed

to references to our socket library base8.
   Many functions used copyin() and copyout() to copy data around.  Those
functions copy data between system and user space (different virtual
memory mappings) in original BSD Unix system.   It is also possible that
those functions will fail e.g.  if user tries to reference illegal memory
locations.  In AmiTCP/IP system copyin() and copyout()functions are
replaced with bcopy(), arguments are thesame but the bcopy() never
fails.  Therefore some obsolete checks are removed fromthe code.



5.6.1   HowAPI Functions Are Ported


Most functions in our API are ported from BSD Unix system calls.  BSD
Unix system call interface calls the actual function with three
arguments.  First is user process structure pointer.  Second contains the
given arguments and is locally named asuap structure.  Third argument is
a pointer to the return value.  The function returns error value or 0 if
no error occurred.
   The socket() function is a good example of this:



socket(p, uap, retval)
         struct proc *p;
         registerstruct args -
                 int      domain;
                 int      type;
                 int      protocol;
         " *uap;
         int *retval;


   The system function interface maps directly to Amiga shared library.
Since every task has socket library baseof its own, Unix process pointer

matches to library base pointer given inregister A69 .  uap argumentsare
passed in registers normally.  Return value is returnedin the register
D0 (as any standard C compiler does).  So the *retval was changed to a
local variable retval and removed, whennot needed.   The returned value
is -1 on error, in which case the errnois also set to indicate the error
(see file sys/errno.h for list of errorcodes), or retval, or 0 if no
other return value is needed.
   To emulate Unix system call interface, each function first obtains the
syscall_semaphore (why,see section 4.10.2 on page 90) and while this
task is holding the semaphore, no othertask can continue to execute the
________________________________
   7BSDSS networking code is almost completely the same.

   8See 5.5.

   9All Amiga shared libraries expect them to be called relative to

register A6


System Manual                  AmiTCP/IP                 Section 5.7    103



library code10.  This means that every system call function needs to
release syscall_semaphore before returning.  To accomplish this, each
return inside the function is changed togoto Return; and at label

Return:  is code that releases the syscall_semaphore11 .
   The default modifications were:  changing file descriptor tables and
pointers to socket tables and pointers,respectively, removing usage of
struct fileops function pointers -- replacing them with direct socket
functions, changing copyin() and copyout() functions to bcopy()s -- no
more error checking here needed, and last, changing parameters on
tsleep() calls.



5.6.2   APIFunctions Which Needed More Modifications

IoctlSocket()  (Former ioctl()):  Non-socket stuff removed, and ioctl code
    from soo_ioctl() inserted.

WaitSelect()  (Former select()) usedto count remaining time out time if
    tsleep() returned accidentally too early.  AmiTCP/IP uses the timer
    device for its time outs and the time out request is aborted only
    when it is needed again, so there is no need to send new time out
    requests (and to calculate their time out durations).  tsleep() is
    broken apart into pieces so that the time out request is sent only
    once.

CloseSocket()  Decreases socket's referencecount and calls soclose() to
    kill the socket if it becomes zero.

socket() and accept()  Added initialization of so_refcnt.  fdAlloc()
    doesn't bind fd to socket.  It is done explicitly.

Resolver functions  used to allocate huge amounts of stack.  Now memory is
    allocated dynamically from the head using bsd_malloc.



5.7     Changes  in  Functions  Below  API  Level


Functions that API functions call are mostly functions that use struct
socket type arguments, possibly having some other arguments too.  In most
cases no modifications were needed.  There was some modifications, like
parameters for tsleep() call, which hadto be changed throughout the
code.



5.7.1   Other  Changes

selscan()  calls soo _select() directly, and uses socket pointer instead of
    file pointer.

soo_select() also uses socket pointer instead of file pointer.
________________________________
  10Not all functions require obtaining syscall_semaphore so those can continue
to run.
  11syscall_semaphore is also freed when library function does tsleep().


104    Section 5.8                 AmiTCP/IP                  System Manual



socreate()  allows allsockets to be privileged.  This means that user can
    obtain raw sockets and use normally privileged port numbers.

sosend() uses uioread() instead of the original uiomove().  sblock() and
    sbwait() are called with library base pointer as the second argument.

soreceive()  uses uiowrite() instead of the original uiomove().  See above
    about the modification of call sblock() and sbwait().

sorflush()  calls sblock() with base pointer argument as NULL.

sosetopt() and sogetopt()   :  type of so_linger and so_timeo fields in
    socket structure is changed from short int to struct timeval.
    Manipulation of these data is changed accordingly.

sbwait() takes socket base pointer as second argument.  It is then passed
    to tsleep() (see section 5.3.2 on page 97).

sblock() and sb_lock():  sblock() is a macro that calls sb_lock().  Both
    take socket base pointer as second argument.  sblock() forwards that
    pointer directly to sb_lock() which, again, passes it to the
    tsleep().



5.8     Agnet.device


We used the agnet.device, an SANA-II test device, to test and develop the
AmiTCP/IP network code.  The usage and features of theagnet.device are
described in the section 1.7.1, page 10.
   SANA-II is an standard network device driver interface for the Amiga
(see [SANA-II 1992 add ]).  It is an extension to the normal device
interface, which is described in the [RKM Libs & Devs 1989 ].  Device
drivers are accessed by their name fromthe system list.  Drivers may be
loaded dynamically from the disk, if they are not currently in the main
memory.  There may be several units sharing common driver code so each
(network) device is specified by an unitnumber and the device driver
name.
   We wrotethe agnet.device using the SLIP driver which Commodore has
provided as the example code for SANA-IIdrivers.   However, there was
some problems with the supplied code.  First, the SLIPdriver code
obviously follows an obsolete SANA-II draft.   There was some
modifications in the final standard e.g.  in the eventhandling and
multicast addressing.
   The provided example code was also very fragile, it did not get
compiled as such with the newer SAS C version 6.   Codedepended on some
features of the SAS C 5.10.  For example, it always expected to find
device base pointer in address registerA6.



5.8.1   IO Commands

There is a detailed description of SANA-II device commands and functions
in [SANA-II 1992 add ].  The following IO commands are implemented in
agnet.device:


System Manual                  AmiTCP/IP                 Section 5.8    105



CMD_CLEAR
    This standard command should return IOERR_NOCMD when issued to
    SANA-II device.

CMD_INVALID
    This standard command should return IOERR_NOCMD.

CMD_READ
    Get the next packet available of the requested packet type.  The data
    returned (via a call to the requester-provided CopyToBuffer()
    function) is the Data Link Layer packet data only.  Raw packets are
    not supported.

CMD_RESET
    This standard command should return IOERR_NOCMD when issued to
    SANA-II device.

CMD_START
    This standard command should return IOERR_NOCMD when issued to
    SANA-II device.

CMD_STOP
    This standard command should return IOERR_NOCMD when issued to
    SANA-II device.

CMD_UPDATE
    This standard command should return IOERR_NOCMD when issued to
    SANA-II device.

CMD_WRITE
    Send packet to the network.  Raw packets are not supported.  Sending
    packet with a broadcast hardware address is not supported.

S2_BROADCAST
    Broadcast a packet to the network.  Raw packets are not supported.

S2_CONFIGINTERFACE
    Configure the interface.  The address field will be set depending on
    the specified hardware type.

S2_DEVICEQUERY
    Report the statistical information about the device.

S2_GETGLOBALSTATS
    Report accumulated statistics as defined in struct Sana2Devicestats.

S2_GETSTATIONADDRESS
    Report the ``hardware'' address for the unit.  Before the
    configuration, the current hardware address has all bits set.  The
    default hardware address is not stored anywhere.

S2_GETTYPESTATS
    Report accumulated statistics of the tracked packets.

S2_OFFLINE
    Remove interface from service.  Flush all queued IO requests.


106    Section 5.8                 AmiTCP/IP                  System Manual



S2_ONEVENT
    Return when specified event(s) occur(s).

S2_ONLINE
    Put the interface back in service.  This command resets the unit
    statistics.

S2_READORPHAN
    If there is no pending CMD_READ request with the type of the received
    packet, the packet is given to first pending S2_READORPHAN request.
    The data returned (via a call to the requester-provided CopyToBuffer
    function) is the Data Link Layer packet data only.  Raw packets are
    not supported.

S2_TRACKTYPE
    Start tracking of the specified packet type packets.

S2_UNTRACKTYPE
    Stop tracking of the specified packet type packets.



Uninplemeted IO Commands

These SANA-II device commands are not supported.

CMD_FLUSH
    This standard command returns IOERR_NOCMD when issued to the
    agnet.device.

S2_ADDMULTICASTADDRESS
    This SANA-II command is not supported.  It returns IOERR_NOCMD.

S2_DELMULTICASTADDRESS
    This SANA-II command is not supported.  It returns IOERR_NOCMD.

S2_GETSPECIALSTATS
    This SANA-II command is not fully supported.  It returns an empty
    Sana2SpecialStat structure.

    This command should report accumulated driver specific statistics.
    This includes ethernet ``retries''.

S2_MULTICAST
    This SANA-II command is not supported.  It returns IOERR_NOCMD.



5.8.2   Initialization Procedure

agnet.device must be started as a DOS process by the Run command.  The
dynamic loading is not yet implemented.  Its own startup module, init.c,
opens needed libraries, initializes device base and calls the main()
function.  Main function opens timer.device and initializes the ARexx
port; if initialization was successful,it adds the device base to the
system list.
   In the main loop the device task waits for three different events:
user or Expunge() generated break signal(SIGF _BREAK_F), ARexx messages or
user IO request messages.


System Manual                  AmiTCP/IP                 Section 5.8    107



5.8.3   TheDevice Interface Functions

The device interface contains 6 standardlibrary calls in the device
base.  The device may be opened or closed, the IO requests may be
initiated or aborted and the system mayreclaim storage allocated by the
device driver.
   These library calls are not normally executed directly by the user code
but instead higher level convenience functions in the Exec.  The device
base library calls are made in the context of the caller, so some
synchronous IO commands may be executedlike library calls without
message passing overhead (quick IO).
   The synopsis of the functions specifies the registers where the call
parameters are passed (REG(rn)).



Opening an Unit

An IO device is opened by the Exec function call OpenDevice().  When Exec
has found the named device driver in thesystem list it calls the special
DevOpen() function from the device base.  DevOpen() function has
following synopsis:

ULONG ASM DevOpen(REG(a1) struct IOSana2Req *ios2,
                   REG(d0) ULONG unit, REG(d1) ULONG flags)



    The device open function tries to allocate and initialize various
    resources for the specified unit if the unit does not already exist.
    The initialization routine InitUnit() is called; if it returns an
    unit structure, a private buffermanagement structure is filled from
    the user provided tag list.  The user supplied IO request is filled
    with appropriate values.

    The promiscuous or exclusive modes are not supported.

struct AgnetDevUnit *InitUnit(ULONG);

    The initialization routine allocates an unit structure and then calls
    the configuration routine ReadConfig().  If the configuration file
    was read and interpreted without errors the lists and locks in the
    unit structure is initialized.  The unit is then put online and unit
    structure is added to the device base.

BOOL ReadConfig(struct AgnetDevUnit *adu)

    The configuration routine attempts to read in the configuration file
    for the given unit.  It strips the comments out of the file and
    provides the file as a single line to the parsing routine
    ParseConfig().  If there is no configuration file, the parsing
    routine is called with an empty line.



Closing an Unit

The accessed unit is closed after use with the Exec CloseDevice()
function.  It runs the DevClose() function from the device base.  The
call has the following synopsis:


108    Section 5.8                 AmiTCP/IP                  System Manual



BPTR ASM DevClose(REG(a1) struct IOSana2Req *ios2)

    The device close function calls the unit close function.  If the
    device has been asked to Expunge() itself, the close function sends
    an appropriate signal to the device task.  The device task then
    performs the postponed expunge function.

    The DevOpen() and DevClose() calls are executed while Forbid()'den
    unless the code explicitly Wait()'s.



Initiating an IO Request


The DevBeginIO function from the devicebase is called to initiate an IO
command.  This call is made in the context of the requesting task (task
calling Exec functions DoIO() or SendIO()).   The DevBeginIO() call has
the following synopsis:


VOID ASM DevBeginIO(REG(a1) struct IOSana2Req *ios2)

    The IO request is sent to the device task for dispatching and
    execution.  Currently all IO requests are executed in the context of
    the device task, i.e.  no quick IO is supported.



Aborting an IO Request


Some IO requests may be aborted before they are completed by Exec
function call AbortIO().  The aborting function has thefollowing
synopsis:


VOID ASM DevAbortIO(REG(a1) struct IOSana2Req *ios2)

    Currently only the CMD_READ, S2_READORPHAN, CMD_WRITE, S2_BROADCAST,
    and S2_ONEVENT IO commands may be aborted.  Other IO commands are
    executed in an atomic way and can not be aborted reliably.



Expunging the Device


The system may reclaim the storage allocated by the device driver by
calling the DevExpunge() function.  Memory reclaiming is normally done in
a low memory situation or after a user requested memory flush.  The
expunging function has the following synopsis:


VOID ASM DevExpunge(VOID)

    The DevExpunge() may not Wait() because it may be called from the
    Exec function AllocMem() protected by Forbid()/Permit() pair.

    The DevExpunge() function call currently signals the device task,
    which performs the actual expunging by calling the DoExpunge().  Each
    unit structure is expunged by the function ExpungeUnit().


System Manual                  AmiTCP/IP                 Section 5.8    109



5.8.4   Packet  Delivery

The packet sent to the pseudo network may be delayed or mutated randomly.
A special structure (struct DelayRequest) stores the packet type and data
during the ``transmit delay''.  The delay is implemented by sending this
structure as a the timer IO request to the timer device.  The packet
transmit functions are as follows:


VOID WritePacket(struct AgnetDevUnit *adu, struct IOSana2Req *ios2)

    The function checks that the unit is on line and checks for the legal
    data length.  Then the routine adds the given IO request (CMD_WRITE,
    S2_BROADCAST) into send queue.  If there is a free delay request the
    SendPacket() is called immediately.

VOID SendPacket(struct DelayRequest *delayed)

    The SendPacket() function takes an empty DelayRequest structure as
    its argument.  First, it gets a send IO request from the send queue.
    The request is immediately returned if the packet is ``lost'' during
    transmit.  This is repeated until a packet is found which is not to
    be lost.

    The packet data, type, length, transmission type and the address of
    the sender are then copied into the DelayRequest structure.  If
    needed, bit errors are made into packet data.

    If there is specified delay for the unit, the request is sent to the
    timer device.  After the delay the timer device returns request into
    the device port and it is dispatched by the ReceivePacket() function.
    If there is no delay, the ReceivePacket() is called immediately.

VOID ReadPacket(struct AgnetDevUnit *adu, struct IOSana2Req *ios2)

    The function checks that unit is online, then adds the read request
    into an appropriate queue.

VOID ReceivePacket(struct DelayRequest *delayed)

    The ReceivePacket() function calls the DoReceive() function on each
    unit the packet is destined.  It then handles the DelayRequest
    structure back to the SendPacket() function.

VOID DoReceive(struct AgnetDevUnit *adu,struct DelayRequest *delayed)

    The DoReceive() function tries to find a receive IO message waiting
    for this particular type packets.  If none is found, the first
    S2_READORPHAN IO request is selected.

    The CopyBack() function sets the appropriate IO request return values
    and copies the packet data to the receive buffer.



5.8.5   Arexx  Interface

The ARexx interface is implemented by using the SimpleRexx package
provided in Commodore Native Developer Update 2.0 kit.  The Arexx
commands executed by the agnet.device are described in section 1.7.1,
page 12.


110    Section .0                  AmiTCP/IP                   System Manual



LONG ParseRexx(UBYTE *arg, UBYTE **errstr, UBYTE **result)

    The ARexx command string is copied into a buffer and passed to the
    parser function ParseRexx().

    The parser allocates a DOS struct RDArgs structure for the ARexx
    command.  This structure holds the information for the DOS parsing
    functions.  The first keyword in the string is read and tokenized by
    the DOS functions ReadItem() and FindArg().

    The rest of the line is parsed according this token.  In the case of
    Query and Unit commands the unit number is read from the command line
    and the rest of the line is passed to the appropriate functions.

LONG ParseConfig(struct AgnetDevUnit *adu, struct RDArgs *rdargs,
                       STRPTR *errormessage)
    The command line stored into the RDArgs structure is parsed by the
    DOS function ReadArgs().  The parsed configuration information are
    then gathered, its legality is checked and it is stored into the unit
    structure.

LONG ParseQuery(struct AgnetDevUnit *adu, struct RDArgs *rdargs,
                      STRPTR *errstr, STRPTR *result)
    Like the ParseConfig(), ParseQuery() parses the command line by the
    ReadArgs().  It then fills the reply buffer by the requested
    configuration parameter values and then makes an ARexx string out of
    the buffer.  This string is then returned to the ARexx process.





Appendix A



Autodocs  for  Network Applications



and  Utilities



The AutoDoc file netutil.doc contains on-line manual pages for the
network utilities and applications.



Table  of  Contents


        arp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : : 112
        ifconfig : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : : 114
        inetd : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : :: : : : : : 117
        letnet  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 119
        offline : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 120
        online  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 121
        ping : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
 * : : : : : : : : : 122
        route : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : :: : : : : : 126



                                      111


112    Section A.1                 AmiTCP/IP                  System Manual



A.1     Network Utilities



A.1.1   arp


  NAME
        Arp- address resolution display and control


  SYNOPSIS
        arp hostname
        arp-a netname
        arp-d hostname
        arp-s hostname address [temp] [pub]
        arp-f filename


  DESCRIPTION
        Arpdisplays and modifies the Internet to hardware address
        translation tables used by the Address Resolution Protocol.
        Thehardware address is a hexadecimal string with each octet
        separated by a colon, for instance 0:12:ff:a. The length of
        theaddress must be same as the address of the specified
        interface.


  OPTIONS
         none  If no options arespecified (first form above), arp
              displays the current ARP entry for hostname.   The
              hostname must either appear in the hostname database
              (SEE hosts), or be a DARPA Internet address expressed in
              Internet standard "dot notation".


        -a    Display all current ARP entries by reading the address
              mapping table of the specified interface.


        -d   If an ARP entry exists for the host called hostname, delete
              it. This requires super-user privileges.


        -s    Create an ARP entry for the host called hostname with the
              hardware station address address. The hardware station address
              is given as six hexadecimal bytes separated by colons.  If an
              ARP entry already exists for hostname,the existing entry is
              updated with the new information.  The entry is permanent
              unless the word temp is given in the command. If the word pub
              is specified, the entry is published, which means that this
              system will act as an ARP server responding to requests for
              hostname even though the host address is not its own.


        -f    Read file filename and set multiple entries in the ARP tables.
              Entries in the file should be of the form:


                   hostname address [temp] [pub]


              Argument meanings are the same as for the -s option.


  AUTHOR
        Arpwas developed by the University of California, Berkeley, for the
        BSDUnix system.


System Manual                  AmiTCP/IP                 Section A.1    113



  SEE ALSO
        ifconfig, netif.protocols/arp, "net/if_arp.h"


114    Section A.1                 AmiTCP/IP                  System Manual



A.1.2   ifconfig


  NAME
        ifconfig - configure network interface parameters


  SYNOPSIS
        ifconfig interface address_family [address [dest_address]] [params]
        ifconfig interface [address_family]


  DESCRIPTION
        ifconfig is used to assign an address to a network interface and/or
        configure network interface parameters.  ifconfig must be used at
        boot time to define the network address of each interface present on
        a machine.   It can also be used at other times to redefine an
        interface's address or other operating parameters.


  PARAMETERS
        interface     A string of the unit name. The device name (e.g.
                       'a2065.device') concatenated with a slash ('/') and the
                       unit number ('11'), for example 'a2065.device/11' is a
                       legal unit name.


        address_family
                      Name of protocol on which naming scheme is based.  An
                       interface can receive transmissions in differing
                       protocols, each of which may require separate naming
                       schemes.   Therefore,it is necessary to specify the
                       address_family, which may affect interpretation of the
                       remaining parameters on the command line.  The only
                       addressfamily currently supported is inet (DARPA-
                       Internet  family).


        address       Either a host name present in the host name database,
                       (SEE hosts), or a DARPA Internet address
                       expressed in Internet standard "dot notation".  The
                       host number can be omitted on 10-Mbyte/second Ethernet
                       interfaces (which use the hardware physical address),
                       and oninterfaces other than the first.


        dest_address Address of destination system.  Consists of either a
                       host name present in the host name database, hosts(4),
                       or a DARPA Internet address expressed in Internet
                       standard "dot notation".


  SWITCHES
        Thefollowing operating parameters can be specified:


         up           Mark an interface "up". Enables interface after an
                       "ifconfig down."   Occurs automatically when setting the
                       addresson an interface.  Setting this flag has no
                       effectif the hardware is "down".


         down         Mark an interface "down".  When an interface is
                       marked"down", the system will not attempt to
                       transmit messages through that interface. If
                       possible, the interface will be reset to disable


System Manual                  AmiTCP/IP                 Section A.1    115



                       reception as well.  This action does not
                       automatically disable routes using the interface.


        arp           Enable the use of Address Resolution Protocol in
                       mappingbetween network level addresses and link-level
                       addresses  (default).


        -arp           Disable the use of Address Resolution Protocol.


         metric n     Set the routing metric of the interface to n,
                       default0.   The routing metric is used by the routing
                       protocol (see gated(1m)).  Higher metrics have the
                       effectof making a route less favorable; metrics are
                       countedas additional hops to the destination network
                       or host.


         debug         Enable driver-dependent debugging code. This usually
                       turns on extra console error logging.


        -debug         Disable driver-dependent debugging code.


         netmask mask (Inet only) Specify how much of the address to reserve
                       for subdividing networks into sub-networks.  mask
                       includes the network part of the local address, and the
                       subnetpart which is taken from the host field of the
                       address.   mask can be specified as a single hexadecimal
                       numberwith a leading 0x, with a dot-notation Internet
                       address, or with a pseudo- network name listed in the
                       networktable networks(4).  mask contains 1's for each
                       bit position in the 32-bit address that are to be used
                       for thenetwork and subnet parts, and 0's for the host
                       part.  mask should contain at least the standard
                       networkportion, and the subnet field should be
                       contiguous with the network portion.


        broadcast     (Inet only) Specify the address that represents
                       broadcasts to the network.  The default broadcast
                       addressis the address with a host part of all 1's.


        The command:


             ifconfig interface/unit


        with no optional command arguments supplied displays the current
        configuration for interface.  If address_family is specified,
        ifconfig reports only the details specific to that address family.


  DIAGNOSTICS


        Messages indicating that the specified interface does not exist, the
        requested address is unknown, or the user is not privileged and
        tried to alter an interface's configuration.


  EXAMPLES


116    Section A.1                 AmiTCP/IP                  System Manual



        ifconfig lo/0 127.0.0.1


                This command marks internal loopback device "UP", and
                attach an inet address 127.0.0.1 to it.


        ifconfig cslip.device/0 inet 193.102.4.144 193.102.4.129


                This command starts the CSLIP driver, attach an
                address 193.102.4.144 (our internet address) and a
                destination address 193.102.4.129 (the internet
                address of the host you are connecting) to it.


        ifconfig devs:network/a2065.device/0 inet 193.124.100.64 +
        netmask 255.255.255.192 -arp


                This command loads an ethernet driver for the
                Commodore A2065 Ethernet adapter unit 0, marks it
                "up", disables ARP protocol for it, attaches an inet
                address 193.124.100.65 to it and sets its netmask to
                255.255.255.192.  A bitwise logical and of netmask and
                address for the interface forms a subnet address, in
                this case 193.124.100.64.  All packets aimed to hosts
                with same subnet address (that is hosts 193.124.100.64
                - 193.124.100.127) are routed to this interface.


  SEE ALSO
        netstat, hosts, arp, "net/if.h", "net/sana2tags.h"


System Manual                  AmiTCP/IP                 Section A.1    117



A.1.3   inetd


  NAME
         inetd - internet ``super-server''


  TEMPLATE
        inetd DEBUG/S CONFIGFILE


  DESCRIPTION


        Inetd should be run when the AmiTCP/IP protocol stack is started.
        Inetd listens for connections on certain internet sockets.  When a
        connection is found on one of its sockets, it decides what service the
        socket corresponds to, and invokes a program to service the request.
        After the program is finished, it continues to listen on the socket
        (except in some cases which will be described below).  Essentially,
        inetd allows running one daemon to invoke several others, reducing
        load on the system.


  PARAMETERS
        DEBUG       Turns on debugging.


        CONFIGFILE Specifies the configuration file name.


  CONFIGURATION


        Upon execution, inetd reads its configuration information from a
        configuration file which, by default, is AmiTCP:db/inetd.conf. There
        must be an entry for each field of the configuration file, with
        entries for each field separated by a tab or a space.  Comments are
        denoted by a ``#'' at the beginning of a line or ``;'' anywhere in the
        line. There must be an entry for each field. The fields of the
        configuration file are as follows:


              service name
              socket type
              protocol
              wait/nowait
              user
              server program
              server program name
              server program arguments


        Theservice-name entry is the name of a valid service in the
        netdatabase.   For ``internal'' services (discussed below), the service
        name must be the official name of the service.


        Thesocket-type should be one of ``stream'', ``dgram'', ``raw'',
        ``rdm'', or ``seqpacket'', depending on whether the socket is a
        stream, datagram, raw, reliably delivered message, or sequenced packet
        socket. Current system supports only stream, datagram and raw
        protocols.


        Theprotocol must be a valid protocol as given in netdatabase.
        Examples might be ``tcp'' or ``udp''.


118    Section A.1                 AmiTCP/IP                  System Manual



        Thewait/nowait entry is useful for datagram sockets only (other
        sockets should have a ``nowait'' entry in this space).  If a datagram
        server connects to its peer, freeing the socket so inetd can received
        further messages on the socket, it is said to be a ``multi-threaded''
        server, and should use the ``nowait'' entry.  For datagram servers
        which process all incoming datagrams on a socket and eventually time
        out, the server is said to be ``single-threaded'' and should use a
        ``wait'' entry.  Comsat and talkd are both examples of the latter type
        ofdatagram server.


        Theuser entry should contain the user name of the user as whom the
        server should run. This field is for Unix and future compability
        only.


        Theserver-program entry should contain the pathname of the program
        which is to be executed by inetd when a request is found on its
        socket.   If theserver program is resident, the path name should be
        suppressed. If inetd provides this service internally, this entry
        should be ``internal''.


        Theserver-program-name is CLI command name for the server process. It
        isshown in the printout of ``status'' command. (Task name of the
        server process is the service and the peer address, e.g. ``echo
        [192.233.15.19]''.) This and argument entry are optional.


        Theserver program arguments should be just as arguments normally are.


        Inetd provides several ``trivial'' services internally by use of
        routines within itself.  These services are ``echo'', ``discard'',
        ``chargen'' (character generator), ``daytime'' (human readable time),
        and``time'' (machine readable time, in the form of the number of
        seconds since mid night, January 1, 1900).  All of these services are
        TCPand UDP based.  For details of these services, consult the
        appropriate RFC from the Network Information Center.


        Inetd rereads its configuration file when it receives the CTRL-F
        signal.   Services may be added, deleted or modified when the
        configuration file is reread.


  HISTORY
        Theinetd command appeared in 4.3BSD system.


  SEE ALSO


System Manual                  AmiTCP/IP                 Section A.1    119



A.1.4   letnet

  NAME
        Letnet - a simple TCP connection tool


  SYNOPSIS
        letnet  HOSTNAME/A,PORT/A


  DESCRIPTION
        Letnet connects to the specified TCP port at the specified host. The
        data read from standard input is sent to the host and data received
        from the connection is written to the standard output. Letnet
        terminates upon shutdown of the socket or receiving SIGBREAKF_CTRL_C
        signal.


  ARGUMENTS
         HOSTNAME/A
                If there is no name service available, hostname maybe given
                in the Internet dot notation.


         PORT/A
                The port identifier is searched from the standard services
                (SEE ALSO netdb/services) database. A nonstandard
                service port may be specified in the numeric form,numbers
                between 1---65535 are acceptable.


  AUTHOR
        Pekka Pessi, the AmiTCP/IP Group, Helsinki University of Technology


  SEE ALSO
        netdb/services, netdb/hosts


120    Section A.1                 AmiTCP/IP                  System Manual



A.1.5   offline

  NAME
        Offline - put a SANA-II device offline


  TEMPLATE
        Offline DEV=DEVICE devicename[/unit] [UNIT unit]


  DESCRIPTION
        Offline sends the S2_OFFLINE command to the given SANA-II device
        driver and unit. This command is normally used to disconnect SANA-II
        device driver from the network adapter hardware. Device driver does
        notaccept any more read or write requests.


  EXAMPLES
        This command puts the SLIP offline, which frees then the serial port
        toyour use.


        OFFLINE  slip.device/1


  SEE ALSO
        Online,  sana2.device/S2_OFFLINE


System Manual                  AmiTCP/IP                 Section A.1    121



A.1.6   online

  NAME
        Online - put a SANA-II device online


  TEMPLATE
        Online DEV=DEVICE devicename[/unit] [UNIT unit]


  DESCRIPTION
        Online sends the S2_ONLINE command to the given SANA-II device driver
        andunit. The device driver restarts the network adapter hardware and
        accepts read and write request again.


  EXAMPLES


        This command puts the Commodore Ethernet driver online.


        Online  a2065.device/0


  SEE ALSO
        Offline, sana2.device/S2_ONLINE


122    Section A.1                 AmiTCP/IP                  System Manual



A.1.7   ping


   NAME
        ping - send ICMP ECHO_REQUEST packets to network hosts


   SYNOPSIS
        ping [-dfnqrvR] [-c count] [-i wait] [-l preload] [-p pattern]
             [-s packetsize]


   DESCRIPTION
        Ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to
        elicit an ICMP ECHO_RESPONSE from a host or gateway.  ECHO_REQUEST
        datagrams (``pings'') have an IP and ICMP header, followed by a
        ``struct timeval'' and then an arbitrary number of ``pad'' bytes
        used to fill out the packet.  The options are as follows: Other
        options  are:


        -c count
                Stop after sending (and receiving) count ECHO_RESPONSE
                packets.


        -d      Set the SO_DEBUG option on the socketbeing used.


        -f      Flood ping.  Outputs packets as fast as they come back or
                one hundred times per second, whichever is more.  For every
                ECHO_REQUEST sent a period ``.'' is printed, whilefor ever
                ECHO_REPLY received a backspace is printed.  This provides a
                rapid display of how many packets are being dropped.   Only
                the super-user may use this option.  This can be very hard
                on a network and should be used with caution.


        -i wait
                Wait wait seconds between sending each packet. Thedefault
                is to wait for one second between each packet.  This option
                is incompatible with the -f option.


        -l preload
                If preload is specified, ping sends that many packets as
                fast as possible before falling into its normal mode of
                behavior.


        -n      Numeric output only.  No attempt will be made to lookup
                symbolic names for host addresses.


        -p pattern
                You may specify up to 16 ``pad'' bytes to fill outthe
                packet you send.  This is useful for diagnosing
                data-dependent problems in a network.  For example, ``-p
                ff'' will cause the sent packet to be filled with all ones.


        -q      Quiet output.  Nothing is displayed except the summary lines
                at startup time and when finished.


        -R      Record route.  Includes the RECORD_ROUTE option inthe
                ECHO_REQUEST packet and displays the route buffer on
                returned packets.  Note that the IP header is only large


System Manual                  AmiTCP/IP                 Section A.1    123



                enough for nine such routes.  Many hosts ignore or discard
                this option.


        -r      Bypass the normal routing tables andsend directly to a host
                on an attached network.  If the host is not on a
                directly-attached network, an error is returned.  This
                option can be used to ping a local host through aninterface
                that has no route through it.


        -s packetsize
                Specifies the number of data bytes to be sent.  The default
                is 56, which translates into 64 ICMP data bytes when
                combined with the 8 bytes of ICMP header data.


        -v      Verbose output.  ICMP packets other than ECHO_RESPONSE that
                are received are listed.


        When using ping for fault isolation, it should first be run on the
        local host, to verify that the local network interface is up and
        running.   Then,hosts and gateways further and further away should
        be``pinged''.   Round-trip times and packet loss statistics are
        computed.   If duplicate packets are received, they are not included
        inthe packet loss calculation, although the round trip time of
        these packets is used in calculating the minimum/average/maximum
        round-trip time numbers.  When the specified number of packets have
        been sent (and received) or if the program is terminated with a
        SIGINT, a brief summary is displayed.


        This program is intended for use in network testing, measurement and
        management.   Because of the load it can impose on the network, it is
        unwise to use ping during normal operations or from automated
        scripts.


   ICMP PACKET DETAILS
        AnIP header without options is 20 bytes.  An ICMP ECHO_REQUEST
        packet contains an additional 8 bytes worth of ICMP header followed
        byan arbitrary amount of data.  When a packetsize is given, this
        indicated the size of this extra piece of data (the default is 56).
        Thus the amount of data received inside of an IP packet of type ICMP
        ECHO_REPLY will always be 8 bytes more than the requested data space
        (the ICMP header).


        Ifthe data space is at least eight bytes large, ping uses the first
        eight bytes of this space to include a timestamp which it uses in
        thecomputation of round trip times.  If less than eight bytes of
        padare specified, no round trip times are given.


   DUPLICATE AND DAMAGED PACKETS
        Ping will report duplicate and damaged packets.  Duplicate packets
        should never occur, and seem to be caused by inappropriate
        link-level retransmissions.  Duplicates may occur in many situations
        andare rarely (if ever) a good sign, although the presence of low
        levels of duplicates may not always be cause for alarm.


        Damaged packets are obviously serious cause for alarm and often


124    Section A.1                 AmiTCP/IP                  System Manual



        indicate broken hardware somewhere in the ping packet's path (in the
        network or in the hosts).


   TRYING DIFFERENT DATA PATTERNS
        The(inter)network layer should never treat packets differently
        depending on the data contained in the data portion.  Unfortunately,
        data-dependent problems have been known to sneak into networks and
        remain undetected for long periods of time.  In many cases the
        particular pattern that will have problems is something that doesn't
        have sufficient ``transitions'', such as all ones or all zeros, or a
        pattern right at the edge, such as almost all zeros.  It isn't
        necessarily enough to specify a data pattern of all zeros (for
        example) on the command line because the pattern that is of interest
        isat the data link level, and the relationship between what you
        type and what the controllers transmit can be complicated.


        This means that if you have a data-dependent problem you will
        probably have to do a lot of testing to find it.  If you are lucky,
        youmay manage to find a file that either can't be sent across your
        network or that takes much longer to transfer than other similar
        length files.   You can then examine this file for repeated patterns
        that you can test using the -p option of ping.


   TTL DETAILS
        TheTTL value of an IP packet represents the maximum number of IP
        routers that the packet can go through before being thrown away.  In
        current practice you can expect each router in the Internet to
        decrement the TTL field by exactly one.


        TheTCP/IP specification states that the TTL field for TCP packets
        should be set to 60, but many systems use smaller values (4.3 BSD
        uses 30, 4.2 used 15). The AmiTCP/IP uses normally TTL value 30.


        Themaximum possible value of this field is 255, and most systems
        setthe TTL field of ICMP ECHO_REQUEST packets to 255.  This is why
        youwill find you can ``ping'' some hosts, but not reach them with
        telnet or ftp.


        Innormal operation ping prints the ttl value from the packet it re-
        ceives.   When aremote system receives a ping packet, it can do one
        ofthree things with the TTL field in its response:


           Not change it; this is what Berkeley Unix systems did before the
            4.3BSD-Tahoe release.  In this case the TTL value in the
            received packet will be 255minus the number of routers in the
            round-trip path.


           Set it to 255; this is what AmiTCP/IP and current Berkeley Unix
            systems do.  In this case the TTL value in the received packet
            will be 255 minus the number of routers in the path from the
            remote system to the pinging host.


           Set it to some othervalue.   Some machines use the same value
            for ICMP packets that theyuse for TCP packets, for example
            either 30 or 60.  Others may use completely wild values.


System Manual                  AmiTCP/IP                 Section A.1    125



   BUGS
        Many Hosts and Gateways ignore the RECORD_ROUTE option.


        Themaximum IP header length is too small for options like
        RECORD_ROUTE to be completely useful.  There's not much that that
        canbe done about this, however.


        Flood pinging is not recommended in general, and flood pinging the
        broadcast address should only be done under very controlled
        conditions.


   SEE ALSO
        netstat,   ifconfig


   AUTHOR
        Theping command originally appeared in 4.3BSD.


126    Section A.1                 AmiTCP/IP                  System Manual



A.1.8   route


   NAME
         route - manually manipulate the routing tables


   SYNOPSIS
         route [-n] [-q] [-v] command [modifiers] destination gateway


   DESCRIPTION
         Route isa program used to manually manipulate the network routing
         tables.


         Options supported by route:


         -n      Prevent attempts to print host and networknames
                 symbolically when reporting actions.


         -v      (verbose) Print additional details.


         -q      Suppress all output.


         Commandsaccepted by route:


         add         Add a route.
         delete      Delete a specific route.


         The destination is the destination host or network, gateway is the
         next-hopgateway to which packets should be addressed. Routes to a
         particular host are distinguished from those to a network by
         interpreting the Internet address associated with destination. The
         optionalmodifiers -net and -host force the destination to be
         interpreted as a network or a host, respectively.  Otherwise, if the
         destination has a ``local address part'' of INADDR_ANY, or if the
         destination is the symbolic name of a network, then the route is
         assumed to be to a network; otherwise, it is presumed to be a route
         to a host.


         For example, 128.32 is interpreted as -host 128.0.0.32; 128.32.130
         is interpreted as -host 128.32.0.130; -net 128.32 is interpreted as
         128.32.0.0; and -net 128.32.130 is interpreted as 128.32.130.0.


         To add adefault route, give the destination as 'default'.


         If the route is via an interface rather than via a gateway, the
         -interface modifier should be specified; the gateway given is the
         address of this host on the common network, indicating the interface
         to be used for transmission.


         The optional -netmask qualifier is used to specify the netmask of
         the interface. One specifies an additional ensuing address parameter
         (to be interpreted as a network mask).  The implicit network mask
         generatedcan be overridden by making sure this option follows the
         destination  parameter.


         All symbolic names specified for a destination or gateway are looked
         up firstas a host name using gethostbyname(). If this lookup fails,


System Manual                  AmiTCP/IP                 Section A.1    127



         getnetbyname() is then used to interpret the name as that of a
         network.


   DIAGNOSTICS
         add [host_ network ] %s: gateway %s flags %x
                 The specified route is being added to the tables. The values
                 printed are from the routing table entry supplied in the
                 IoctlSocket() call. If the gateway address used was not the
                 primary address of the gateway (the first one returned by
                 gethostbyname()), the gateway address is printed numerically
                 as well as symbolically.


         delete [host _ network ] %s: gateway %s flags %x
                 As above, but when deleting an entry.


         Network is unreachable
                 An attempt to add a route failed because the gateway listed
                 was not on a directly-connected network.  The next-hop
                 gateway must be given.


         not in table
                 A delete operation was attempted for an entry which wasn't
                 present in the tables.


         routing table overflow
                 An add operation was attempted, but the system was low on
                 resources and was unable to allocate memory to create the
                 new entry.


   SEE ALSO
         ifconfig, protocols/routing


   HISTORY
         The routecommand appeared in 4.2BSD.





Appendix B



API  Function  Reference



This appendix is a complete reference tothe functions and concepts
provided by the AmiTCP/IP system.



Table  of  Contents



   Standard BSD Style Socket Functions
        accept  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 130
        bind : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
 * : : : : : : : : : 132
        CloseSocket : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 133
        connect : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 134
        Dup2Socket  : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 136
        getpeername : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 137
        getsockname : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 138
        getsockopt  : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 139
        IoctlSocket : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 142
        listen  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 144
        recv : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
 * : : : : : : : : : 145
        recvfrom : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : : 145
        select  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 147
        send : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
 * : : : : : : : : : 150
        sendto  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 150
        setsockopt  : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 139
        shutdown : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : : 152
        socket  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 153
        WaitSelect  : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 147


   Other BSD Functions Related to Sockets
        getdtablesize : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : 156
        Syslog  : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 157


   Network Data and Address Manipulation
        inet_addr : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : :: 159
        Inet_LnaOf: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : : 159
        inet_lnaof: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : : 159



                                      128


System Manual                  AmiTCP/IP                 Section B.0    129



        inet_MakeAddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : :159
        inet_makeaddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : :159
        Inet_NetOf: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : : 159
        inet_netof: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : : 159
        inet_network : : : : : : : : : : : : : : : : : : : : : : :: : : : : : :*
 * : : : : : : : 159
        Inet_NtoA : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : :: 159
        inet_ntoa : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : : : : :: 159


   Network, Protocol and Service Queries
        gethostbyaddr : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : 162
        gethostbyname : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : 162
        getnetbyaddr : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : 164
        getnetbyname : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : 164
        getprotobyname  : : : : : : :: : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : 166
        getprotobynumber : : : : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : : : 166
        getservbyname : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : 167
        getservbyport : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : 167


   AmiTCP/IP Specific Extensions
        Errno : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : :: : : : : : 169
        ObtainSocket : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : 170
        ReleaseCopyOfSocket : :: : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : 171
        ReleaseSocket : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : 172
        SetDTableSize : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : 173
        SetErrnoPtr : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 174
        SetSocketSignals : : : : : : : : : : : : : : : : : :: : : : : : : : : :*
 * : : : : : : 175


130    Section B.1                 AmiTCP/IP                  System Manual



B.1     Standard  BSD  Style Socket  Functions



B.1.1   accept()


   NAME
         accept -accept a connection on a socket


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>


         ns = accept(s, addr, addrlen)
         D0          D0 A0     A1


         long accept(long, struct sockaddr *, long *);


   FUNCTION
         The  argument  s  is a  socket  that  has  been created with
         socket(),bound to an  address  with bind(), and  is listen-
         ing for connections after a listen().  accept() extracts the
         first  connection  on  the  queue  of  pending  connections,
         creates anew socket with the same properties of s and allo-
         cates a new socket descriptor for the socket.  If no pending
         connections are present on the  queue, and the socket is not
         marked  as non-blocking, accept() blocks the caller  until a
         connection is present.  If the socket is marked non-blocking
         and  no pending  connections  are  present  on  the  queue,
         accept()returns  an error as described below.  The accepted
         socket isused to read and write data to and from the socket
         which connected to  this one; it is not used to  accept more
         connections.   The original socket s remains open for accept-
         ing further connections.


         The argument addr is a result parameter that  is  filled  in
         with  the address of the connecting entity, as known to the
         communications layer.  The exact format of the addr  parame-
         ter  is determined by the domain in which the communication
         is occurring.  The addrlen is a value-result  parameter;  it
         should  initially  contain the amount of space pointed to by
         addr; onreturn it will contain the actual length (in bytes)
         of    the   address    returned.    This  call  is  used  with
         connection-based socket types, currently with SOCK_STREAM.


         It is possible to select() a socket  for  the  purposes  of
         doing anaccept() by selecting it for read.


   RETURN VALUES
         accept()returns a non-negative descriptor for the  accepted
         socket onsuccess.   Onfailure, it returns -1 and sets errno
         to indicate the error.


System Manual                  AmiTCP/IP                 Section B.1    131



   ERRORS
         EBADF         - The descriptoris invalid.


         EINTR         - The operation was interrupted by a break
                         signal.


         EOPNOTSUPP    - The referencedsocket is not of type
                         SOCK_STREAM.


         EWOULDBLOCK   - The socket is marked non-blocking and no con-
                         nections are present to be accepted.


   SEE ALSO
         bind(), connect(), listen(), select(), SetSocketSignals(),
         socket()


132    Section B.1                 AmiTCP/IP                  System Manual



B.1.2   bind()

   NAME
         bind - bind a name to a socket


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>


         success =bind(s, name, namelen)
         D0              D0 A0    D1


         long bind(long, struct sockaddr *, long);


   FUNCTION
         bind() assigns a name to an unnamed socket.  When  a  socket
         is created with socket(2) it exists in a name space (address
         family) but has no name assigned.  bind() requests that  the
         name pointed to by name be assigned to the socket.


   RETURN VALUES
         0  - on success.


         -1 - on failure and sets errno to indicate the error.


   ERRORS
         EACCES            - The requested address is protected,  and
                              the  current user has inadequate permis-
                              sion to access it.


         EADDRINUSE         - The specified address is already in use.


         EADDRNOTAVAIL      - The specified address is  not  available
                              from the local machine.


         EBADF              -s is not a valid descriptor.


         EINVAL            - namelen is  not  the  size  of  a  valid
                              address  for  the specified address fam-
                              ily.


                              The  socket  is  already  bound  to   an
                              address.


   SEE ALSO
         connect(), getsockname(), listen(), socket()


   NOTES
         The rulesused in name binding  vary  between  communication
         domains.


System Manual                  AmiTCP/IP                 Section B.1    133



B.1.3   CloseSocket()

   NAME
         CloseSocket - delete a socket descriptor


   SYNOPSIS
         success =CloseSocket(s)
         D0                     D0


         long CloseSocket(long);


   FUNCTION
         CloseSocket() deletes  a  descriptor  from the  library base
         socket reference table.    Ifs is the last reference  to the
         underlying object, then the object  will  be deactivated and
         socket  (see socket()),  associated naming  information  and
         queued data are discarded.


         All sockets are automatically closed when the socket library
         is closed, but closing sockets as soon as possible is
         recommended to save system resources.


   RETURN VALUES
          0   on success.


         -1   on failure and sets errnoto indicate the error.


   ERRORS
         EBADF              -s is not an active socket descriptor.


         EINTR              -linger on close was interrupted.
                              The socket is closed, however.


   SEE ALSO
         accept(),SetSocketSignals(), shutdown(), socket(),
         exec.library/CloseLibrary()


134    Section B.1                 AmiTCP/IP                  System Manual



B.1.4   connect()



   NAME
         connect -initiate a connection on a socket


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>


         success =connect(s, name, namelen)
         D0                 D0 A0    D1


         long connect(long, struct sockaddr *, long);


   FUNCTION
         The parameter s is a socket.  If it  is of  type SOCK_DGRAM,
         then  this call specifies the peer with which the  socket is
         to be associated;  this address  is that  to which datagrams
         are  to be sent, and  the only address from which  datagrams
         are to bereceived.   Ifit is of type SOCK_STREAM, then this
         call attempts  to make a connection  to another socket.  The
         other socket is specified by name which is an address in the
         communications space of  the  socket.   Each  communications
         space interprets the  name parameter in  its  own way.  Gen-
         erally, stream sockets may successfully connect() only once;
         datagramsockets may use connect() multiple  times to change
         their association.  Datagram sockets may dissolve the  asso-
         ciation by connecting to  an invalid address, such as a null
         address.


   RETURN VALUES
          0   on success.


         -1   on failure and sets errnoto indicate the error.


   ERRORS
         EADDRINUSE         - The address is already in use.


         EADDRNOTAVAIL      - The specified address is  not  available
                              on the remote machine.


         EAFNOSUPPORT       - Addresses in the specified address   fam-
                              ily cannot be used with this socket.


         EALREADY          - The socket is non-blocking and a  previ-
                              ous  connection attempt has not yet been
                              completed.


         EBADF              -s is not a valid descriptor.


         ECONNREFUSED       - The attempt to  connect  was forcefully


System Manual                  AmiTCP/IP                 Section B.1    135



                              rejected.   The  calling  program should
                              CloseSocket() the socket descriptor, and
                              issue another socket()  call to obtain a
                              new descriptor before attempting another
                              connect() call.


         EINPROGRESS        - The socket is non-blocking and the  con-
                              nection cannot be completed immediately.
                              It is possible to select()  for  comple-
                              tion  by  selecting the socket for writ-
                              ing.


         EINTR              -The operation was interrupted by a break
                              signal.


         EINVAL            - namelen is  not  the  size  of  a  valid
                              address  for  the specified address fam-
                              ily.


         EISCONN             The socket is already connected.


         ENETUNREACH        - The network is not reachable  from  this
                              host.


         ETIMEDOUT         - Connection    establishment    timed    out
                              without establishing a connection.


   SEE ALSO
         accept(),CloseSocket(), connect(), getsockname(), select(),
         socket()


136    Section B.1                 AmiTCP/IP                  System Manual



B.1.5   Dup2Socket()

   NAME
        Dup2Socket - duplicate a socket descriptor


   SYNOPSIS


        newfd = Dup2Socket(fd1, fd2)
        D0                  D0   D1


        long Dup2Socket(long, long);


   DESCRIPTION
        Dup2Socket() duplicates an existing socket descriptor.
        theargument fd1 is small non-negative value that indexes
        thesocket on SocketBase descriptor table. The value must
        beless than the size of the table, which is returned by
        getdtablesize(). fd2 specifies the desired value of the new
        descriptor. If descriptor fd2 is already in use, it is
        first deallocated as if it were closed by CloseSocket(). If
        thevalue if fd2 is -1, the new descriptor used and returned
        isthe lowest numbered descriptor that is not currently in
        useby the SocketBase.


   RETURN VALUES
        Dup2Socket() returns a new descriptor on  success. On failure
        -1is returned and errno is set to indicate the error.


   ERRORS
        EBADF           fd1 or fd2 is not a valid active descriptor.


        EMFILE          Too many descriptors are active.


   SEE ALSO
        accept(), CloseSocket(), getdtablesize(), SetDtableSize(),
        socket()


System Manual                  AmiTCP/IP                 Section B.1    137



B.1.6   getpeername()

   NAME
         getpeername - get name of connected peer


   SYNOPSIS
         success =  getpeername(s, name, namelen)
         D0                      D0 A0    A1


         long getpeername(long, struct sockaddr *, long *);


   FUNCTION
         getpeername() returns the name  of  the  peer  connected  to
         socket  s.    The long  pointed  to  by the namelen parameter
         should be  initialized  to  indicate  the  amount  of  space
         pointed to  by name.  On return it contains the actual size
         of the name returned (in bytes).  The name is  truncated  if
         the buffer provided is too small.


   RETURN VALUE
         A 0 is returned if the call succeeds, -1 if it fails.


   ERRORS
         EBADF         - The argument sis not a valid descriptor.


         ENOBUFS      - Insufficient resources were available in   the
                         system to perform the operation.


         ENOTCONN     - The socket is not connected.


   SEE ALSO
         accept(),bind(), getsockname(), socket()


138    Section B.1                 AmiTCP/IP                  System Manual



B.1.7   getsockname()

   NAME
         getsockname - get socket name


   SYNOPSIS


         success =getsockname(s, name, namelen)
         D0                     D0 A0    A1


         long getsockname(long, struct sockaddr *, long *);


   FUNCTION
         getsockname() returns the current  name  for  the  specified
         socket.   The  namelen  parameter  should  be initialized to
         indicatethe amount of space pointed to by name.  On  return
         it contains the actual size of the name returned (in bytes).


   DIAGNOSTICS
         A 0 is returned if the call succeeds, -1 if it fails.


   ERRORS
         The callsucceeds unless:


         EBADF          s is not a valid descriptor.


         ENOBUFS         Insufficient resources were available in  the
                         system to perform the operation.


   SEE ALSO
         bind(), getpeername(), socket()


System Manual                  AmiTCP/IP                 Section B.1    139



B.1.8   getsockopt()



   NAME
         getsockopt, setsockopt - get and set options on sockets


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>


         success =  getsockopt(s, level, optname, optval, optlen)
         D0                     D0 D1     D2        A0      A1


         long getsockopt(long, long, long, caddr_t, long *);


         success =  setsockopt(s, level, optname, optval, optlen)
         D0                     D0 D1     D2        A0      D3


         long setsockopt(long, long, long, caddr_t, long);


   FUNCTION
         getsockopt() and setsockopt() manipulate options  associated
         with  a socket.  Options may exist at multiple protocol lev-
         els; theyare always present  at  the  uppermost  ``socket''
         level.


         When manipulating socket options  the  level  at  which  the
         option resides and the name of the option must be specified.
         To manipulate options at  the  ``socket''  level,  level  is
         specifiedas SOL_SOCKET.  To manipulate options at any other
         level theprotocol number of the appropriate  protocol  con-
         trolling the  option is supplied.  For example, to indicate
         that an option is to be interpreted  by  the  TCP  protocol,
         level  should  be  set  to  the  protocol number of TCP.


         The parameters optval and optlen are used to  access  option
         values  for  setsockopt().  For getsockopt() they identify a
         buffer inwhich the value for the requested option(s) are to
         be  returned.    For  getsockopt(),  optlen is a value-result
         parameter,  initially  containing  the  size  of  the  buffer
         pointed to by optval, and modified on return to indicate the
         actual size of the value returned.  If no option value is to
         be supplied or returned, optval may be supplied as 0.


         optname and any specified options are  passed  uninterpreted
         to  the appropriate protocol module for interpretation.  The
         include file  <sys/socket.h>    contains    definitions    for
         ``socket'' level options, described below.  Options at other
         protocol levels  vary  in  format  and  name.


         Most socket-level options take an int parameter for  optval.
         For setsockopt(), the parameter should be non-zero to enable


140    Section B.1                 AmiTCP/IP                  System Manual



         a booleanoption, or zero if the option is to  be  disabled.


         SO_LINGER   uses  a  struct  linger  parameter,  defined  in
         <sys/socket.h>, which specifies the  desired  state  of  the
         option and the linger interval (see below).


         The following options are recognized at  the  socket  level.
         Except  as noted, eachmay be examined with getsockopt() and
         set withsetsockopt().


              SO_DEBUG           - toggle    recording    of    debugging
                                   information
              SO_REUSEADDR      - toggle local address reuse
              SO_KEEPALIVE      - toggle keep connections alive
              SO_DONTROUTE      - toggle routing bypass for  outgoing
                                   messages
              SO_LINGER          - linger on close if data present
              SO_BROADCAST      - toggle    permission    to    transmit
                                   broadcast messages
              SO_OOBINLINE      - toggle  reception  of   out-of-band
                                   data in band
              SO_SNDBUF          - set buffer size for output
              SO_RCVBUF          - set buffer size for input
              SO_TYPE            - get the type  of the  socket  (get
                                   only)
              SO_ERROR           - get and clear error on  the  socket
                                   (get  only)


         SO_DEBUG enables  debugging  in  the  underlying   protocol
         modules.   SO_REUSEADDR  indicates  that  the  rules used in
         validating addresses supplied in a bind() call should allow
         reuse oflocal addresses.  SO_KEEPALIVE enables the periodic
         transmission of messages on a connected socket.  Should  the
         connected  party fail to respond to these messages, the con-
         nection is considered broken. If  the  process  is
         waiting in select() when the connection is broken, select()
         returns true for any read or write events selected  for  the
         socket.    SO_DONTROUTE  indicates  that  outgoing  messages
         should bypass the  standard  routing  facilities.   Instead,
         messages are  directed to the appropriate network interface
         accordingto the network portion of the destination address.


         SO_LINGERcontrols the action taken when unsent messags  are
         queued  on  socket and a CloseSocket() is performed.  If the
         socket promises reliable delivery of data and  SO_LINGER  is
         set,  the system  will  block  the  process  on the close
         attempt until it is able to transmit the data  or  until  it
         decides it  is unable to deliver the information (a timeout
         period, in seconds, termed the linger interval, is specified
         in the set- sockopt() call when SO_LINGER is requested).  If
         SO_LINGER is  disabled and a CloseSocket()  is  issued, the


System Manual                  AmiTCP/IP                 Section B.1    141



         system will process the  close  in  a manner that allows the
         process to continue as quickly as possible.


         The option SO_BROADCAST requests permission to  send  broad-
         cast  datagrams  on  the socket.  Broadcast was a privileged
         operationin earlier versions of the system.  With protocols
         that  support  out-of-band  data,  the  SO_OOBINLINE  option
         requeststhat out-of-band data be placed in the normal  data
         input  queue  as  received;  it will then be accessible with
         recv() orread() calls without the MSG_OOB flag.   SO_SNDBUF
         and  SO_RCVBUF are options to adjust the normal buffer sizes
         allocatedfor output and input buffers,  respectively.   The
         buffer size may be increased for high-volume connections, or
         may be decreased to limit the possible backlog  of  incoming
         data.   The system places an absolute limit on these values.
         Finally,SO_TYPE and SO_ERROR are  options  used  only  with
         getsockopt().    SO_TYPE returns the type of the socket, such
         as SOCK_STREAM; it is useful for servers that inherit  sock-
         ets  on startup.  SO_ERROR returns any pending error on the
         socket and clears the error status.  It may be used to check
         for asynchronous errors on connected datagram sockets or for
         other asynchronous errors.


   RETURN VALUES
          0 - on success.


         -1 - on failure and set errno to indicate the error.


   ERRORS
         EBADF              -s is not a valid descriptor.


         ENOPROTOOPT        - The option is unknown at the level indi-
                              cated.


   SEE ALSO
         IoctlSocket(), socket()


   BUGS
         Several of the socket options should  be  handled  at  lower
         levels ofthe system.


142    Section B.1                 AmiTCP/IP                  System Manual



B.1.9   IoctlSocket()



   NAME
         IoctlSocket - control sockets


   SYNOPSIS


         #include <sys/types.h>
         #include <sys/ioctl.h>


         value = IoctlSocket(fd, request, arg)
         D0            D0   D1       A0


         long IoctlSocket(long, long, caddr_t);


   FUNCTION
         IoctlSocket() performs a special function on the object referred
         to by theopen   socketdescriptor fd. Note: the setsockopt()
         call (seegetsockopt()) is the primary  method for operating
         on sockets  as such, rather than on the underlying  protocol
         or network interface.


         For mostIoctlSocket() functions, arg is a pointer to data to
         be used by the  function  or to be filled in by the function.
         Other functions may ignore arg or may treat it directly as a
         data item; they may, for example, be passed an int value.


         The following requests are supported:



         FIOASYNC            The argument is a  pointer  to  a  long.
                              Set  or  clear asynchronous I/O.  If the
                              value of that  long is  a  1  (one)  the
                              descriptor  is set for asynchronous I/O.
                              If the value of that long is a  0 (zero)
                              the  descriptor is cleared for asynchro-
                              nous I/O.


         FIOCLEX
         FIONCLEX            Ignored, no use for close-on-exec flag
                              in Amiga.


         FIOGETOWN
         SIOCGPGRP           The argument is pointer to struct Task*.
                              Set the value of that pointer to the
                              Task that  is  receiving SIGIO or SIGURG
                              signals for  the  socket  referred to by
                              the descriptor passed to IoctlSocket().


         FIONBIO             The argument is a  pointer  to  a  long.
                              Set  or  clear non-blocking I/O.  If the


System Manual                  AmiTCP/IP                 Section B.1    143



                              value of that  long is  a  1  (one)  the
                              descriptor  is set for non-blocking I/O.
                              If the value of that long is a  0 (zero)
                              the   descriptor  is  cleared  for  non-
                              blocking I/O.


         FIONREAD            The argument is a  pointer  to  a  long.
                              Set the value of that long to the number
                              of immediately readable characters  from
                              the socket fd.


         FIOSETOWN
         SIOCSPGRP           The argument is pointer to struct Task*,
                              pointer  to  the task  that will subseq-
                              uently receive  SIGIO or  SIGURG signals
                              for   the  socket  referred  to  by  the
                              descriptor passed.


         SIOCCATMARK          The argument is a pointer to a long.
                              Set the value of that long to 1 if the
                              read pointer for the socket referred to
                              by the descriptor passed to
                              IoctlSocket() points to a mark in the
                              data stream for an out-of-band message,
                              and to 0 if it does not point to a mark.



   RETURN VALUES
         IoctlSocket() returns 0 on success for most requests.   Some
         specialized requests may return non-zero values on success; On
         failure,  IoctlSocket()returns -1 and sets errno to indicate
         the error.


   ERRORS
         EBADF          fd is not a valid descriptor.


         EINVAL         request or arg is not valid.


         IoctlSocket() will also fail if the object on which the function
         is  being performed detects an error. In this case, an error
         code specific  to  the  object  and  the  function  will  be
         returned.


   SEE ALSO
         getsockopt(), SetSocketSignals(), setsockopt()


144    Section B.1                 AmiTCP/IP                  System Manual



B.1.10   listen()

   NAME
         listen -listen for connections on a socket


   SYNOPSIS
         success =listen(s, backlog)
         D0                D0 D1


         long listen(long, long);


   FUNCTION
         To accept  connections,  a  socket  is  first  created  with
         socket(), a  backlog for incoming connections is specified
         with listen() and then the  connections  are  accepted  with
         accept().   The  listen()  call  applies only to socket of
         type SOCK_STREAM.


         The backlog parameter defines the maximum length  the  queue
         of pending connections may grow to.  If a connection request
         arrives with the queue full the client will receive an error
         with an indication of ECONNREFUSED.


   RETURN VALUES
          0    on success.


         -1    on failure and sets errno to indicate the error.


   ERRORS
         EBADF              -s is not a valid descriptor.


         EOPNOTSUPP         - The socketis not of a  type  that  sup-
                              ports listen().


   SEE ALSO
         accept(),connect(), socket()


   BUGS
         The backlog is currently limited (silently) to 5.


System Manual                  AmiTCP/IP                 Section B.1    145



B.1.11   recv()



   NAME
         recv, recvfrom, - receive a message from a socket


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>


        nbytes = recv(s, buf, len, flags)
        D0            D0 A0    D1    D2


        long recv(long, char *, long, long);


        nbytes = recvfrom(s, buf, len, flags, from, fromlen)
        D0                 D0 A0    D1    D2     A1    A2


        long recvfrom(long, char *, long, long,
                          struct sockaddr *, long *);


   FUNCTION
         s is a socket created with socket().  recv() and recvfrom(),
         are used to  receive messages from  another socket.  recv()
         may  be used  only on a connected socket  (see  connect()),
         while  recvfrom() may be used  to receive data  on a  socket
         whether it is in a connected state or not.


         If from is not a NULL pointer, the  source  address  of  the
         message is filled in.  fromlen is a value-result parameter,
         initialized to the size of the buffer associated with  from,
         and  modified  on  return to indicate the actual size of the
         address stored  there.    The  length  of  the  message    is
         returned.   If  a message is too long to fitin the supplied
         buffer, excess bytes may be discarded depending on the  type
         of socketthe message is received from (see socket()).


         If no messages are available at the socket, the receive call
         waits  for  a  message  to arrive, unless the socket is non-
         blocking(see IoctlSocket()) in which case -1  is  returned
         with theexternal variable errno set to EWOULDBLOCK.


         The select() call may be used to determine when  more  data
         arrive.


         The flagsparameter is formed by ORing one or  more  of  the
         following:


         MSG_OOB      - Read any "out-of-band" data  present on  the
                         socket,  rather  than  the  regular "in-band"
                         data.


146    Section B.1                 AmiTCP/IP                  System Manual



         MSG_PEEK     - "Peek" at the data present onthe socket; the
                         data  are returned, but not consumed, so that
                         a subsequent receive operation will  see  the
                         same data.


   RETURN VALUES
         These calls return the number of bytes received, or -1 if an
         error occurred.


   ERRORS
         EBADF              -s is an invalid descriptor.


         EINTR              -The operation was interrupted by a break
                              signal.


         EWOULDBLOCK        - The socket is  marked  non-blocking and
                              the requested operation would block.


   SEE ALSO
         connect(), getsockopt(), IoctlSocket(), select(), send(),
         SetSocketSignals(), socket()


System Manual                  AmiTCP/IP                 Section B.1    147



B.1.12   select()



   NAME
         select --synchronous I/O multiplexing (stub/inline function)
         WaitSelect -- select() with Amiga Wait() function.


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/time.h>


         n = select (nfds, readfds, writefds, exceptfds, timeout)


         long select(long, fd_set *, fd_set *, fd_set *,
                      struct timeval *);


         n = WaitSelect (nfds, readfds, writefds, exceptfds, timeout,
         D0               D0    A0        A1         A2         A3
                      sigmp)
                      D1


         long WaitSelect(long, fd_set *, fd_set *, fd_set *,
                          struct timeval *, long *);


         FD_SET (fd, &fdset)
         FD_CLR (fd, &fdset)
         FD_ISSET(fd, &fdset)
         FD_ZERO (&fdset)
         long fd;
         fd_set fdset;


   DESCRIPTION
         select()examines the socket descriptor sets whose addresses
         are passed in readfds,  writefds,  and exceptfds  to  see if
         some of their descriptors are ready  for reading,  ready for
         writing, or have an exceptional condition pending.  nfds is
         the  number  of bits to be checked in  each  bit  mask  that
         representa file descriptor; the descriptors from 0  through
         (nfds - 1) in the descriptor sets  are examined.  On return,
         select() replaces  the  given descriptor sets  with subsets
         consisting of  those descriptors  that  are  ready  for  the
         requestedoperation.  The total number  of ready descriptors
         in all the sets is returned.


         WaitSelect() also takes a signal mask which is waited during
         normal select() operation. If one of these singals is recei-
         ved,  WaitSelect() returns  and has  re-set  the signal mask
         to returnthose signals that  have arrived.  Normal select()
         return values are returned.


         The descriptor sets are stored as bit fields  in  arrays  of
         integers.   The following macros are provided for manipulat-


148    Section B.1                 AmiTCP/IP                  System Manual



         ing suchdescriptor sets:  FD_ZERO  (&fdset)  initializes  a
         descriptor  set  fdset to the null set.  FD_SET(fd, &fdset )
         includesa particular descriptor fd  in  fdset.   FD_CLR(fd,
         &fdset) removes  fd  from  fdset.   FD_ISSET(fd, &fdset) is
         nonzero if fd is a member of  fdset,  zero  otherwise.   The
         behavior  of these macros is undefined if a descriptor value
         is less than zero or greater than or  equal  to  FD_SETSIZE,
         which  is normally  at least equal to the maximum number of
         descriptors supported by the system.


         If timeout is not a NULL pointer,  it  specifies  a  maximum
         interval to wait for the selection to complete.  If timeout
         is a NULL pointer,  the  select  blocks  indefinitely.   To
         effect  a poll,  the  timeout argument should be a non-NULL
         pointer,pointing to a zero-valued timeval structure.


         Any of readfds, writefds, and exceptfds may be given as NULL
         pointersif no descriptors are of interest.


         Selectingtrue for reading on a socket descriptor upon which
         a  listen() call has been performed indicates that a subse-
         quent accept() call on that descriptor will not block.


   RETURN VALUES
         select()returns a non-negative value on success. A positive
         value indicates the number of ready descriptors in the
         descriptor sets. 0 indicates that the time limit referred to
         by timeout expired or that the operation was interrupted
         either bya break signal or by arrival of a signal specified
         in *sigmp. On failure, select() returns -1, sets errno to
         indicatethe error, and the descriptor sets are not changed.


   ERRORS
         EBADF         - One  of  the  descriptor  sets  specified  an
                         invalid descriptor.


         EINTR         - one of the signals in SIGINTR  mask (see Set-
                         SocketSignals())   is  set  and  it  was not
                         requested in WaitSelect() call.


         EINVAL       - A component of the pointed-to time  limit is
                         outside  the  acceptable range: t_sec must be
                         between 0 and 10^8,inclusive. t_usec must be
                         greater  than  or equal  to 0, and less than
                         10^6.


   SEE ALSO
         accept(),  connect(), getdtablesize(), listen(), recv(),
         send(), SetDTableSize(), SetSocketSignals()


   NOTES


System Manual                  AmiTCP/IP                 Section B.1    149



         Under rare  circumstances,  select()  may  indicate  that  a
         descriptor  is  ready for writing when in fact an attempt to
         write would block.  This  can  happen  if  system  resources
         necessary for  a  write are exhausted or otherwise unavail-
         able.  Ifan application deems it critical that writes to  a
         file  descriptor not block, it should set the descriptor for
         non-blocking I/O using the FIOASYNC request to IoctlSocket().


         Default   system    limit  for  open  socket  descriptors  is
         currently 64. However,  in  order  to accommodate  programs
         which might  potentially  use  a larger number of open files
         with select, it is possible  to  increase this size within a
         program by  providing  a  larger definition  of  FD_SETSIZE
         before    the    inclusion     of    <sys/types.h>     and    use
         SetDTableSize(FD_SETSIZE) call directly after OpenLibrary().


   BUGS
         select()should probably return the time remaining from  the
         original timeout,  if  any,  by modifying the time value in
         place.  This may be implemented in future  versions  of  the
         system.   Thus,  it  is  unwise  to  assume that the timeout
         pointer will be unmodified by the select() call.


150    Section B.1                 AmiTCP/IP                  System Manual



B.1.13   send()



   NAME
         send, sendto - send a message from a socket


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>


         nbytes =send(s, msg, len, flags)
         D0            D0  A0   D1    D2


         int send(int, char *, int, int);


         nbytes =sendto(s, msg, len, flags, to, tolen)
         D0               D0 A0    D1    D2     A1  D3


         int send(int, char *, int, int, struct sockaddr *, int);


   FUNCTION
         s is a socket created with socket().  send() and sendto() are
         used  totransmit a message to  another socket. send() may be
         used  only when the socket  is  in a connected  state,  while
         sendto()may be used at any time.


         The address of the target  is given by to with tolen specify-
         ing its size.  The length of the message is given by len.  If
         the  message is  too  long  to  pass  atomically  through the
         underlying protocol, then the error EMSGSIZE is returned, and
         the message is not transmitted.


         No indication of failure to deliver is implicit  in a send().
         Return values of -1 indicate some locally detected errors.


         If no buffer space is  available at the socket  to  hold  the
         message to  be  transmitted,  then  send() normally  blocks,
         unless the  socket  has been placed in non-blocking I/O mode.
         The select() call may be used to determine when  it  is  pos-
         sible tosend more data.


         The flagsparameter is formed  by ORing  one  or  more of the
         following:


         MSG_OOB           - Send  ``out-of-band''  data  on  sockets
                              that  support this notion.  The underly-
                              ing protocol must  also  support  ``out-
                              of-band''    data.      Currently,   only
                              SOCK_STREAM  sockets  created    in    the
                              AF_INET  address  family support out-of-
                              band data.


System Manual                  AmiTCP/IP                 Section B.1    151



         MSG_DONTROUTE      - The SO_DONTROUTE optionis turned on for
                              the  duration of the operation.  This is
                              usually used only by diagnostic or rout-
                              ing programs.


   RETURN VALUES
         On success, these functions return the number of bytes sent.
         On  failure,  they  return  -1 and set errno to indicate the
         error.


   ERRORS
         EBADF              -s is an invalid descriptor.


         EINTR              -The operation was interrupted by a break
                               signal.


         EINVAL            - len is not the size of a  valid  address
                              for the specified address family.


         EMSGSIZE          - The socket requires that message be sent
                              atomically,  and the size of the message
                              to be sent made this impossible.


         ENOBUFS           - The system was  unable  to  allocate  an
                              internal    buffer.    The  operation  may
                              succeed when buffers become available.


         ENOBUFS           - The output queue for a network interface
                              was full.  This generally indicates that
                              the interface has stopped  sending,  but
                              may be caused by transient congestion.


         EWOULDBLOCK        - The socket is  marked  non-blocking and
                              the requested operation would block.


   SEE ALSO
         connect(), getsockopt(), recv(), select(), socket()


152    Section B.1                 AmiTCP/IP                  System Manual



B.1.14   shutdown()

   NAME
         shutdown- shut down part of a full-duplex connection


   SYNOPSIS
         success =shutdown(s, how)
         D0                  D0 D1


         long shutdown(long, long);


   DESCRIPTION
         The shutdown() call causes all or part of a full-duplex con-
         nection on the socket associated with s to be shut down.  If
         how is 0,then further receives will be disallowed.  If  how
         is  1,  then further sends will be disallowed.  If how is 2,
         then further sends and receives will be disallowed.


   RETURN VALUES
          0 - on success.


         -1 - on failure and sets errno to indicate the error.


   ERRORS
         EBADF         - s is not a valid descriptor.


         ENOTCONN     - The specified socket is not connected.


   SEE ALSO
         connect(),  socket()


   BUGS
         The how values should be defined constants.


System Manual                  AmiTCP/IP                 Section B.1    153



B.1.15   socket()



   NAME
         socket -create an endpoint for communication


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>


         s = socket(domain, type, protocol)
         D0          D0      D1    D2


         long socket(long, long, long);


   FUNCTION
         socket()creates an endpoint for communication and returns a
         descriptor.


         The  domain  parameter  specifies  a  communications  domain
         within which communication will take place; this selects the
         protocol family  which should be used.  The protocol family
         generally is  the  same  as  the  address  family  for  the
         addressessupplied in later operations on the socket.  These
         families are defined  in the  include file  <sys/socket.h>.
         The currently understood formats are


                 PF_INET - (ARPA Internet protocols)


         The socket has the indicated type, which specifies the
         semanticsof communication.  Currently defined types are:


                 SOCK_STREAM
                 SOCK_DGRAM
                 SOCK_RAW


         A  SOCK_STREAM type  provides  sequenced,  reliable, two-way
         connection  based    byte  streams.    An    out-of-band  data
         transmission  mechanism  may  be  supported.   A  SOCK_DGRAM
         socket supports datagrams  (connectionless, unreliable  mes-
         sages  of a  fixed    (typically    small)  maximum  length).
         SOCK_RAW   sockets    provide  access  to   internal  network
         interfaces.


         The protocol specifies a particular protocol to be used with
         the socket.  Normally  only a single protocol exists to sup-
         port a particular socket type  within a given  protocol fam-
         ily.  However, it is possible that many protocols may exist,
         in whichcase a  particular protocol  must be  specified  in
         this manner.  The  protocol number to use  is  particular to
         the "communication domain" in which communication is to take
         place.


154    Section B.1                 AmiTCP/IP                  System Manual



         Sockets of type SOCK_STREAM  are  full-duplex byte  streams,
         similar to pipes.    A  streamsocket must be in  a connected
         state before any data may be sent or received on it.  A con-
         nection  to another socket is created with a connect() call.
         Once  connected, data  may be  transferred using send()  and
         recv()  or their variant calls.   When  a  session  has been
         completeda CloseSocket()  may  be  performed.   Out-of-band
         data mayalso  be transmitted  as  described  in  send() and
         receivedas described in recv().


         The communications protocols used to implement a SOCK_STREAM
         insure that data is  not lost or  duplicated.  If a piece of
         data for  which the peer protocol has buffer space cannot be
         successfully transmitted within a reasonable length of time,
         then the connection  is  considered broken  and  calls will
         indicatean error with -1 returns and with ETIMEDOUT  as the
         specificerror code (see Errno()).  The protocols optionally
         keep sockets "warm" by  forcing transmissions roughly  every
         minute inthe absence of other activity.


         SOCK_DGRAM  and SOCK_RAW sockets allow sending of  datagrams
         to  correspondents  named in send()  calls.   Datagrams  are
         generally received  with  recv(), which  returns  the  next
         datagramwith its return address.


         The operation of  sockets  is  controlled  by  socket  level
         options.   These  options  aredefined in the file socket.h.
         getsockopt()  and  setsockopt()  are  used  to  get  and  set
         options, respectively.


   RETURN VALUES
         socket()returns a non-negative descriptor on  success.   On
         failure,it returns -1 and sets errno to indicate the error.


   ERRORS
         EACCES          - Permission to create  a  socket  of  the
                            specified    type    and/or    protocol   is
                            denied.


         EMFILE          - The per-process descriptor table is
                            full.


         ENOBUFS         - Insufficient buffer space is available.
                            The socket cannot be created until suf-
                            ficient resources are freed.


         EPROTONOSUPPORT - The protocol type or the specified  pro-
                            tocol is not supported within this
                            domain.


System Manual                  AmiTCP/IP                 Section B.1    155



         EPROTOTYPE       - The protocol is the wrong type for the
                            socket.


   SEE ALSO
         accept(),bind(), CloseSocket(), connect(), getsockname(),
         getsockopt(), IoctlSocket(), listen(), recv(), select(),
         send(), shutdown(), WaitSelect()


156    Section B.2                 AmiTCP/IP                  System Manual



B.2     Other  BSD  Functions  Related  to  Sockets


B.2.1   getdtablesize()

   NAME
         getdtablesize - get socket descriptor table size


   SYNOPSIS


         nfds = getdtablesize()
         D0


         long getdtablesize(void);


   FUNCTION
         Return value of maximum  number of open socket  descriptors.
         Larger  socket  descriptor  table  can   be  allocated  with
         SetDTableSize() call.


   SEE ALSO
         SetDTableSize()


System Manual                  AmiTCP/IP                 Section B.2    157



B.2.2   Syslog()



   NAME
         syslog -write message to AmiTCP/IP log.


   SYNOPSIS
         #include <syslog.h>


         void syslog(unsigned long level, char * format, ...);


         Syslog(level, format, ap)
               D0     A0       A1


         VOID Syslog(unsigned long, const char *, va_list);



   FUNCTION
         Writes the message given as format string and arguments
         (printf-style) both to the log file and to the console,
         execpt ifthe level is LOG_EMERG, which is used by panic(),
         in whichcase only the log file is used since panic()
         generatesa User Request.


         The levelis selected from an ordered list:


              LOG_EMERG            A panic condition.


              LOG_ALERT            A condition thatshould be
                                   corrected immediately, such as a
                                   corrupted system database.


              LOG_CRIT             Critical conditions, such  as  hard
                                   device errors.


              LOG_ERR              Errors.


              LOG_WARNING          Warning messages.


              LOG_NOTICE           Conditions that are not error  con-
                                   ditions,   butthat may require spe-
                                   cial  handling.


              LOG_INFO             Informational messages.


              LOG_DEBUG            Messages that  contain information
                                   normally of use only when debugging
                                   a  program.


   INPUTS
         Level     - indicates the type of the message. The levels
                      are defined in sys/syslog.h and listed above.


158    Section B.2                 AmiTCP/IP                  System Manual



         format    - This is a printf-style format string as defined
                      in  exec.library/RawDoFmt().


         arguments- as in printf().


         ap         - pointer to an array of arguments.


   RESULT
         Returns no value.


   EXAMPLES
         To  log a message at priority  LOG_INFO, it would  make the
         followingcall to syslog:


              syslog(LOG_INFO,  "Connection from host %s",
                      CallingHost);


   NOTES
         As Exec RawDoFmt() used to do formatting expects by default
         short (16bit long) integers you should use the `l'-modifier
         when appopriate. See your compiler documentation about how
         it passesarguments on a vararg list.


         This function is callable from interrupts.


   BUGS
         Because there is a limited number of internal messages used
         by the logging system, some log messages may get lost if a
         high priority task or interrupt handler sends many messages
         in succession. If this happens, the next log message tells
         the fact.


   SEE ALSO
        exec.library/RawDoFmt()


System Manual                  AmiTCP/IP                 Section B.3    159



B.3     Network  Data  and Address  Manipulation



B.3.1   inet _addr()


   NAME
         inet_addr,  inet_network,  Inet_MakeAddr,  Inet_LnaOf,
         Inet_NetOf, Inet_NtoA - Internet address manipulation


         inet_makeaddr, inet_lnaof, inet_netof,
         inet_ntoa-- inline/stub functions to handle structure arguments


   SYNOPSIS
         #include <netinet/in.h>


         addr = inet_addr(cp)
         D0                A0


         unsignedlong inet_addr(char *);


         net = inet_network(cp)
         D0                  A0


         unsignedlong inet_network(char *);


         in_addr =Inet_MakeAddr(net, lna)
         D0                       D0   D1


         unsignedlong Inet_MakeAddr(long, long);


         lna = Inet_LnaOf(in)
         D0                D0


         long Inet_LnaOf(unsigned long);


         net = Inet_NetOf(in)
         D0                D0


         long Inet_NetOf(unsigned long);


         addr = Inet_NtoA(in)
         DO                D0


         char * Inet_NtoA(unsigned long);



         in_addr =inet_makeaddr(net, lna)


         struct in_addr inet_makeaddr(long, long);


         lna = inet_lnaof(in)


160    Section B.3                 AmiTCP/IP                  System Manual



         int inet_lnaof(struct in_addr);


         net = inet_netof(in)


         int inet_netof(struct in_addr);


         addr = inet_ntoa(in)


         char * inet_ntoa(struct in_addr);


   IMPLEMENTATION NOTE
         Return  value  of  Inet_MakeAddr()  and  argument  types  of
         Inet_LnaOf(), Inet_NetOf() and Inet_NtoA() are longs instead
         of  struct  in_addr.  The original behaviour  is achieved by
         using  included  stub  functions (lower case function names)
         which handle structure arguments.


   DESCRIPTION
         The routines inet_addr() and inet_network()  each  interpret
         character strings  representing  numbers  expressed  in the
         Internetstandard `.' notation, returning  numbers  suitable
         for  use as Internet addresses and Internet network numbers,
         respectively.   The routine inet_makeaddr() takes an Internet
         network number and a local network address and constructs an
         Internetaddress from it.    The  routines  inet_netof()  and
         inet_lnaof()   break apart Internet host addresses, returning
         the network number and local network address  part,  respec-
         tively.


         The routine inet_ntoa() returns a pointer to a string in the
         base 256notation ``d.d.d.d'' described below.


         All Internet address are returned in  network  order  (bytes
         ordered from left to right).  All network numbers and local
         address parts are returned as machine format integer values.


   INTERNET ADDRESSES
         Values specified using the `.'  notation  take  one  of  the


         following forms:


              a.b.c.d
              a.b.c
              a.b
              a


         When fourparts are specified, each is interpreted as a byte
         of data and assigned, from left to right, to  the four bytes
         of  an Internet address.  Note: when  an Internet address is
         viewed  as  a  32-bit  integer  quantity  on  little  endian
         systems, the  bytes referred to  above appear  as  d.c.b.a.


System Manual                  AmiTCP/IP                 Section B.3    161



         bytes areordered from right to left.


         When a three part address is specified,  the  last  part  is
         interpreted  as  a  16-bit  quantity and placed in the right
         most twobytes of the network address.  This makes the three
         part  address  format convenient for specifying Class B net-
         work addresses as "128.net.host".


         When a two part address is supplied, the last part is inter-
         preted  as  a  24-bit  quantity and placed in the right most
         three bytes of the network address.  This makes the two part
         address format  convenient  for  specifying Class A network
         addressesas "net.host".


         When onlyone part is given, the value is stored directly in
         the network address without any byte rearrangement.


         All numbers supplied as ``parts'' in a `.' notation  may  be
         decimal, octal,  or  hexadecimal,  as  specified  in  the C
         language(that is, a leading 0x or 0X  implies  hexadecimal;
         otherwise,   a leading0 implies octal; otherwise, the number
         is interpreted as decimal).


   RETURN VALUE
         The value-1 is returned by inet_addr()  and  inet_network()
         for malformed requests.


   BUGS
         The problem of host byte ordering versus network byte order-
         ing  is confusing.  A simple way to specify Class C network
         addressesin a manner similar to that for Class B and  Class
         A is needed.


         The return value from inet_ntoa() points to static buffer
         which  is overwritten  in  each inet_ntoa() call.


162    Section B.4                 AmiTCP/IP                  System Manual



B.4     Network,  Protocol and  Service  Queries



B.4.1   gethostbyname()


   NAME
         gethostbyname, gethostbyaddr  - get network host entry


   SYNOPSIS
         #include <sys/types.h>
         #include <sys/socket.h>
         #include <netdb.h>


         hostent =gethostbyname(name)
         D0                       A0


         struct hostent *gethostbyname(char *);


         hostent =gethostbyaddr(addr, len, type)
         D0                       A0     D0   D1


         struct hostent *gethostbyaddr(caddr_t, LONG, LONG);



   DESCRIPTION
         gethostbyname() and gethostbyaddr() both return a pointer
         to an object with the following structure containing the
         data received from a name server or the broken-out fields
         of a linein netdb configuration file.  In the case of
         gethostbyaddr(), addr is a pointer to the binary format
         address of length len (not a character string) and type is
         an address family as defined in <sys/socket.h>.


           struct hostent -
             char *h_name;       /* official name of host */
             char **h_aliases;   /* alias list */
             int  h_addrtype;    /* address type */
             int  h_length;      /* length of address */
             char **h_addr_list; /* list of addresses from name server */
           ";


         The members of this structure are:


         h_name               Official name of the host.


         h_aliases           A zero  terminated  array  of  alternate
                              names for the host.


         h_addrtype           The  type  of  address  being  returned;
                              currently always AF_INET.


         h_length            The length, in bytes, of the address.


System Manual                  AmiTCP/IP                 Section B.4    163



         h_addr_list          A pointer to a list of network addresses
                              for  the named host.  Host addresses are
                              returned in network byte order.


   DIAGNOSTICS
         A NULL pointer is returned if no matching entry was found or
         error occured.


   BUGS
         All information is contained in a static area so it must  be
         copied ifit is to be saved.  Only the Internet address for-
         mat is currently understood.


   SEE ALSO
         AmiTCP/IP configuration


164    Section B.4                 AmiTCP/IP                  System Manual



B.4.2   getnetbyname()



   NAME
         getnetbyname, getnetbyaddr - get network entry


   SYNOPSIS
         #include <netdb.h>


         netent =getnetbyname(name)
         D0                     A0


         struct netent *getnetbyname(char *);


         netent =getnetbyaddr(net, type)
         D0                     D0   D1


         struct netent *getnetbyaddr(long, long);


   DESCRIPTION
         getnetbyname(), and getnetbyaddr() both return  a  pointer to
         an  object  with  the  following  structure  containing   the
         broken-out fields of a line in netdb configuration file.


           struct netent -
             char *n_name;       /* official name of net */
             char **n_aliases;   /* alias list */
             int  n_addrtype;    /* net number type */
             long n_net;         /* net number */
           ";


         The members of this structure are:


         n_name               The official name of the network.


         n_aliases           A  zero  terminated  list  of  alternate
                              names for the network.


         n_addrtype           The type of the network number returned;
                              currently only AF_INET.


         n_net                The network number.   Network numbers are
                              returned in machine byte order.


         Network numbers are supplied in host order.


         Type specifies the address type to use, currently only
         AF_INET is supported.


   DIAGNOSTICS
         A NULL pointer is returned if no matching entry was found or
         error occured.


System Manual                  AmiTCP/IP                 Section B.4    165



   BUGS
         All information is contained in a static area so it must  be
         copied ifit is to be saved.


         Only Internet network numbers are currently understood.


   SEE ALSO
         AmiTCP/IP configuration


166    Section B.4                 AmiTCP/IP                  System Manual



B.4.3   getprotobyname()

   NAME
         getprotobyname, getprotobynumber - get protocol entry


   SYNOPSIS
         #include <netdb.h>


         protoent= getprotobyname(name)
         D0                         A0


         struct protoent *getprotobyname(char *);


         protoent= getprotobynumber(proto)
         D0                            D0


         struct protoent *getprotobynumber(long);


   DESCRIPTION
         getprotobyname() and getprotobynumber() both return a pointer
         to  an  object with the  following structure  containing  the
         broken-out fields of a line in netdb configuration file


           struct    protoent -
             char *p_name;       /* official name of protocol */
             char **p_aliases;   /* alias list */
             int  p_proto;       /* protocol number */
          ";


         The members of this structure are:


         p_name               The official name of the protocol.
         p_aliases           A  zero  terminated  list  of  alternate
                              names for the protocol.
         p_proto             The protocol number.



   DIAGNOSTICS
         A NULL pointer is returned if no matching entry was found or
         error occured.


   BUGS
         All information is contained in a static area so it must  be
         copied  if  it  is to be saved.  Only the Internet protocols
         are currently understood.


   SEE ALSO
         AmiTCP/IP configuration


System Manual                  AmiTCP/IP                 Section B.4    167



B.4.4   getservbyname()



   NAME
         getservbyname, getservbyport - get service entry


   SYNOPSIS
         #include <netdb.h>


         servent =getservbyname(name, proto)
         D0                       A0     A1


         struct servent *getservbyname(char *, char *)


         servent =getservbyport(port, proto)
         D0                       D0     A0


         struct servent *getservbyport(long, char *);


   DESCRIPTION
         getservbyname() and getservbyport() both return a pointer  to
         an   object  with  the  following  structure  containing  the
         broken-out fields of a line in netdb configuration file.


           struct    servent -
             char *s_name;       /* official name of service */
             char **s_aliases;   /* alias list */
             int  s_port;         /*port service resides at */
             char *s_proto;      /* protocol to use */
           ";


         The members of this structure are:
              s_name               The official name of the service.
              s_aliases            A zero terminated list of alternate
                                   names for the service.
              s_port               The port number at which  the  ser-
                                   vice  resides.    Port numbers  are
                                   returned  in  network  short   byte
                                   order.
              s_proto              The name of  the  protocol  to  use
                                   when contacting the service.


         The protoargument specifies the protocol for which to the
         sercive is to use. It is a normal C string, e.g. "tcp" or
         "udp".


   DIAGNOSTICS
         A NULL pointer is returned if no matching entry was found or
         error occured.


   BUGS
         All information is contained in a static area so it must  be


168    Section B.4                 AmiTCP/IP                  System Manual



         copied  if it is to be saved.  Expecting port numbers to fit
         in a 32 bit quantity is probably naive.


   SEE ALSO
         AmiTCP/IP configuration


System Manual                  AmiTCP/IP                 Section B.5    169



B.5     AmiTCP/IP  Specific Extensions


B.5.1   Errno()

   NAME
         Errno - get error value after unsuccessful function call


   SYNOPSIS
         errno = Errno()
         D0


         LONG Errno(VOID);


   FUNCTION
         When  some  function  in  socket  library  return  an  error
         conditionvalue, they also set a specific error value.  This
         error value can be extracted by this function.


   RESULT
         Error value  indicating  the error on  last failure  of some
         socket function call.


   NOTES
         Return  value  of  Errno()  is not changed  after successful
         functionso so it cannot be used to determine success of any
         functioncall  of this library.  Also, another function call
         to this library may change  the return value of  Errno() so
         use it right after error occurred.


   SEE ALSO
         SetErrnoPtr()


170    Section B.5                 AmiTCP/IP                  System Manual



B.5.2   ObtainSocket()

   NAME
         ObtainSocket - get a socket from AmiTCP/IP socket list


   SYNOPSIS
         s = ObtainSocket(id, domain, type, protocol)
         D0                D0  D1      D2     D3


         LONG ObtainSocket(LONG, LONG, LONG, LONG);


   FUNCTION
         When onetask wants to give  a socket to  an another one, it
         releasesit (with a key value) to a special socket list held
         by  AmiTCP/IP.    This  function  requests  that  socket  and
         receivesit if id and other parameters match.


   INPUTS
         id       - a key value given by the socket donator.
         domain   - see documentation of socket().
         type     - see documentation of socket().
         protocol- see documentation of socket().


   RESULT
         Non negative socket descriptor on success. On failure, -1 is
         returnedand the errno is set to indicate the error.


   ERRORS
         EMFILE          - The per-process descriptor table is
                            full.


         EPROTONOSUPPORT - The protocol type or the specified  pro-
                            tocol is not supported within this
                            domain.


         EPROTOTYPE       - The protocol is the wrong type for the
                            socket.


         EWOULDBLOCK      - Matching socket is not found.


   SEE ALSO
         ReleaseCopyOfSocket(), ReleaseSocket(), socket()


System Manual                  AmiTCP/IP                 Section B.5    171



B.5.3   ReleaseCopyOfSocket()

   NAME
         ReleaseCopyOfSocket - copy given socket to AmiTCP/IP socket list.


   SYNOPSIS
         id = ReleaseCopyOfSocket(fd, id)
         D0                        D0  D1


         LONG ReleaseCopyOfSocket(LONG, LONG);


   FUNCTION
         Make a new reference to a given socket (pointed by its descriptor)
         and release it to the socket list held by AmiTCP/IP.


   INPUTS
         fd - descriptor of the socket to release.


         id - thekey value to identify use of this socket. It can be
              unique or not, depending on its  value. If id value is
              between 0  and  65535,  inclusively,  it is  considered
              nonunique  and it can  be  used as a port  number,  for
              example.   If  id is greater  than  65535 and less than
              2^31) it  must be unique in currently held sockets  in
              AmiTCP/IP socket  list,  Otherwise  an  error will  be
              returned  and  socket  is  not  released.     If  id  ==
              UNIQUE_ID (defined in <sys/socket.h>) an unique id will
              be generated.


   RESULT
         id - -1 in case of error and the key value of the socket put
              in the list. Most useful when an uniqueid is generated
              by this routine.


   ERRORS
         EINVAL -Requested unique id is already used.


         ENOMEM -Needed memory couldn't be allocated.


   NOTE
         The socket descriptor is not deallocated.


   SEE ALSO
         ObtainSocket(), ReleaseSocket()


172    Section B.5                 AmiTCP/IP                  System Manual



B.5.4   ReleaseSocket()

   NAME
         ReleaseSocket - release given socket to AmiTCP/IP socket list.


   SYNOPSIS
         id = ReleaseSocket(fd, id)
         D0                  D0  D1


         LONG ReleaseSocket(LONG, LONG);


   FUNCTION
         Release the reference of given socket (via  its  descriptor)
         and movethe socket to the  socket  list held by  AmiTCP/IP.
         The socket descriptor is deallocated in this procedure.


   INPUTS
         fd - descriptor of the socket to release.


         id - thekey value to identify use of this socket. It can be
              unique or not, depending on its  value. If id value is
              between 0  and  65535,  inclusively,  it is  considered
              nonunique  and it can  be  used as a port  number,  for
              example.   If  id is greater  than  65535 and less than
              2^31) it  must be unique in currently held sockets  in
              AmiTCP/IP socket  list,  Otherwise  an  error will  be
              returned  and  socket  is  not  released.     If  id  ==
              UNIQUE_ID (defined in <sys/socket.h>) an unique id will
              be generated.


   RESULT
         id - -1 in case of error and the key value of the socket put
              in the list. Most useful when an uniqueid is generated
              by this routine.


   ERRORS
         EINVAL -Requested unique id is already used.


         ENOMEM -Needed memory couldn't be allocated.


   SEE ALSO
         ObtainSocket(), ReleaseCopyOfSocket()


System Manual                  AmiTCP/IP                 Section B.5    173



B.5.5   SetDTableSize()

   NAME
         SetDTableSize - set socket descriptor table size of the base


   SYNOPSIS
         newsize =SetDTableSize(size)
         D0                       D0


         LONG SetDTableSize(UWORD);


   FUNCTION
         This  function increases  the  descriptor table size  inside
         library base so more sockets can be open at the same time.


   INPUT
         size - the new size of the desctiptor table.


   RESULT
         newsize -the new size of the descriptor table. Note that
         this canbe less than requested if an error occured.


   WARNING
         If the size of fd_set is not adjusted to store the increased
         space needed for  new  socket descriptors some other  memory
         will  bespilled.  Change  the  value of  FD_SETSIZE  before
         including any  socket  include  files  and  don't  increase
         descriptor  table    to    greater  than  the  new    value  of
         FD_SETSIZE.


   SEE ALSO
         getdtablesize(), select()


174    Section B.5                 AmiTCP/IP                  System Manual



B.5.6   SetErrnoPtr()

   NAME
         SetErrnoPtr - set new place where the error value will be written


   SYNOPSIS
         SetErrnoPtr(ptr, size)
                      A0    D0


         VOID SetErrnoPtr(VOID *, UBYTE);


   FUNCTION
         This functions allows caller to redirect error variable inside
         scope of caller task.    Usually this is  used to make  task's
         global variable errno as error variable.


   INPUTS
         ptr     - pointer to error variable that isto be modified on
                   every error condition on this library function.
         size    - size of the error variable.


   EXAMPLE
         #include <errno.h>


         struct Library;
         struct Library * SocketBase = NULL;


         int main(void)
         -
            ...
           if ((SocketBase = OpenLibrary("bsdsocket.library", 2))
               != NULL) -
             SetErrnoPtr(&errno, sizeof(errno));
            ...
           "
         "


   NOTES
         Be sure that this new error variable exists until library base
         is finally closed or SetErrnoPtr() is called again for another
         variable.


   SEE ALSO
         Errno()


System Manual                  AmiTCP/IP                 Section B.5    175



B.5.7   SetSocketSignals()

   NAME
         SetSocketSignals - inform AmiTCP/IP of INTR, IO and URG signals


   SYNOPSIS
         SetSocketSignals(sigintrmask, sigiomask, sigurgmask)
                           D0            D1         D2


         VOID SetSocketSignals(ULONG, ULONG, ULONG);


   FUNCTION
         SetSocketSignals()  tells the AmiTCP/IP which  signal  masks
         corresponds UNIX SIGINT, SIGIO and SIGURG signals to be used
         in  this implementation.    sigintrmask  mask    is  used  to
         determine which  Amiga signals  interrupt  blocking library
         calls.   sigio-  and sigurgmasks  are sent when asynchronous
         notification of socket events is done and  when  out-of-band
         data arrives, respectively.


         Note that the supplied  values write over old ones. If this
         functionis used and CTRL-C is still wanted to interrupt the
         calls (the   default behaviour), the value BREAKF_CTRL_C must
         be explicitly given.


   SEE ALSO
         IoctlSocket(), recv(), send(), WaitSelect()





Appendix C



AmiTCP/IP  Network Link  Library



This appendix describes the functions located in the net.lib.



Table  of  Contents


        autoinit : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : : 177
        autoinitd : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 * : : : :: : : : 178
        charRead : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : : 179
        gethostname : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : 181
        lineRead : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : :*
 * : : : : : : : : 182



                                      176


System Manual                  AmiTCP/IP                 Section C.1    177



C.1     net.lib Functions


C.1.1   autoinit

   NAME
        autoinit - SAS C Autoinitialization Functions


   SYNOPSIS
        _STIopenSockets()


        void  _STIopenSockets(void)


        _STDcloseSockets()


        void  _STDcloseSockets(void)


   FUNCTION
        These functions open and close the bsdsocket.library at the
        startup and exit of the program, respectively. For a
        program to use these functions, it must be linked with
        netlib:net.lib.


        Ifthe library can be opened, the _STIopenSockets() calls
        bsdsocket.library function SetErrnoPtr() to tell the
        library the address and the size of the errno variable of
        thecalling program.


   NOTES
        _STIopenSockets() also checks that the system version is at
        least 37. It puts up a requester if the bsdsocket.library
        isnot found or is of wrong version.


        Theautoinitialization and autotermination functions are
        features specific to the SAS C6. However, these functions
        canbe used with other (ANSI) C compilers, too. Example
        follows:


        "*at start of main() *"


        atexit(_STDcloseSockets);
        _STDopenSockets();


   BUGS


   SEE ALSO
        bsdsocket.library/SetErrnoPtr(),
        SAS/C 6 User's Guide p. 145 for details of
        autoinitialization and autotermination functions.


178    Section C.1                 AmiTCP/IP                  System Manual



C.1.2   autoinitd

   NAME
        autoinitd - SAS C Autoinitialization Functions for Daemons


   SYNOPSIS
        void  _STIopenSockets(void);
        void  _STDcloseSockets(void);
        long  server_socket;


   DESCRIPTION
        These are SASC autoinitialization functions for internet daemons
        started by inetd, Internet super-server. Upon startup, the server
        socket is obtained with ObtainSocket() library call. If successful,
        thesocket id is stored to the global variable server_socket. If the
        socket is not obtainable, the server_socket contains value -1.
        Ifthe server_socket is not valid, the server may try to accept() a
        newconnection and act as a stand-alone server.


   RESULT
        server_socket - positive socket id for success or -1 for failure.


   NOTES
        _STIopenSockets() also checks that the system version is at
        least 37. It puts up a requester if the bsdsocket.library
        isnot found or is of wrong version.


        Theautoinitialization and autotermination functions are
        features specific to the SAS C6. However, these functions
        canbe used with other (ANSI) C compilers, too. Example
        follows:


        "*at start of main() *"


        atexit(_STDcloseSockets);
        _STDopenSockets();


   AUTHOR
        Jarno Rajahalme, Pekka Pessi,
        theAmiTCP/IP Group <amitcp-group@hut.fi>,
        Helsinki University of Technology, Finland.


   SEE ALSO
        serveraccept(), netutil/inetd


System Manual                  AmiTCP/IP                 Section C.1    179



C.1.3   charRead


   NAME
        charRead -- read characters from socket one by one.


   SYNOPSIS
        initCharRead(rc, fd)


        void initCharRead(struct CharRead *, int);



        character = charRead(rc)


        intcharRead(struct CharRead *);



   DESCRIPTION
        charRead is a macro package which return characters one by one
        from given socket input stream. The socket where data is to be read
        isset by calling initCharRead(): rc is the pointer to charread
        structure previously allocated. fd is the (socket) descriptor where
        reading is to be done.


        charRead() returns the next character from input stream or one of
        the following:


        RC_DO_SELECT     (-3)     - read input buffer is returned. Do select
                                   before next call if you don't want charread
                                   to  block.


        RC_EOF           (-2)    - end-of-file condition has occurred.


        RC_ERROR         (-1)    - there has been an error while filling new
                                   charread buffer. Check the value of Errno()


   NOTE
        Always use variable of type int to store return value from charRead()
        since the numeric value of characters returned may vary between
        0 -255 (or even greater). As you may know, -3 equals 253 if of type
        unsigned char.


   EXAMPLE
        /*
         * This piece of code shows how to use charread with select()
         */
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <charread.h>


        main_loop(int sock)
        -
          struct CharReadrc;
          fd_set readfds;
          int c;


          initCharRead(&rc,  sock);


180    Section C.1                 AmiTCP/IP                  System Manual



          FD_ZERO(&readfds);


          while(1) -
            FD_SET(sock, &readfds);


            if (select(sock + 1. &readfds, NULL, NULL, NULL)) < 0) -
              perror("select");
              break;
            "
            if (FD_ISSET(sock, &readfds)) -
              while((c = charRead(&rc)) >= 0)
                handle_next_input_character(c);
              if (c == RC_EOF)
                break;
              if (c == RC_ERROR) -
                perror("charRead");
                break;
              "
            "
          "
        "


    PORTABILITY
        Thesource file charread.h should be able to be used in
        UNIX programs as is.


    AUTHORS
        Tomi  Ollila,
        theAmiTCP/IP Group <amitcp-group@hut.fi>,


    SEE ALSO
        lineRead(), bsdsocket.library/recv()


System Manual                  AmiTCP/IP                 Section C.1    181



C.1.4   gethostname

   NAME
        gethostname -- get the name of the host


   SYNOPSIS
        error = gethostname(name, namelen);


        intgethostname(char *, int);


   FUNCTION
        Getthe name of the host to the buffer name of length namelen.
        Thename is taken from the environment variable "HOSTNAME"
        where it SHOULD reside.


   INPUTS
        name     - Pointer to the buffer where the name should be
                  stored.
        namelen - Length of the buffer name.


   RESULT
        error    - 0 on success,-1 in case of an error. The global
                  variable errno will be set to indicate the error as
                  follows:


                  ENOENT - The environment variable "HOSTNAME" is not
                            found.


   EXAMPLE
        char  hostname[MAXHOSTNAMELEN];
        int error;


        error = gethostname(hostname, sizeof(hostname));
        if(error < 0)
          exit(10);


        printf("My name is ""%s""."n", hostname);


   NOTES
        This function is included for source compatibility with Unix
        systems.
        TheENOENT errno value is AmiTCP/IP addition.


   BUGS
        Unlike the Unix version, this version assures that the
        resulting string is always NULL-terminated.


   SEE ALSO
        getenv()


182    Section C.1                 AmiTCP/IP                  System Manual



C.1.5   lineRead


   NAME
        lineRead -- read newline terminated strings from socket


   SYNOPSIS
        initLineRead(rl, fd, lftype, bufsize)


        void initLineRead(struct LineRead *, int, int, int);



        length = lineRead(rl)


        intlineread(struct LineRead *);



   DESCRIPTION
        lineRead() reads newline terminated strings from given descriptor
        very efficiently. All the options needed are set by calling
        initLineRead(): rl is the pointer to lineread structure previously
        allocated. fd is the (socket) descriptor where reading is to be
        done. lftype can have following 3 values:


            RL_LFNOTREQ - Newline terminated strings are returned unless
                           there is no newlines left in currently buffered
                           input. In this case remaining buffer is returned.


            RL_LFREQLF  - If there is no newlines left in currently buffered
                           input the remaining input datais copied at the
                           start of buffer. Caller is informed that next
                           call will fill the buffer (andit may block).
                           Lines are always returned withnewline at the end
                           unless the string is longer than whole buffer.


            RL_LFREQNUL  - Like LF_REQLF, but remaining newline is removed.
                           Note here that lenght is one longer that actual
                           string length since line that has only one
                           newline at the end would returnlength as 0
                           which indigate string incomplete condition.


        bufsize is used to tell lineread how big the receive buffer is.
        always put RL_BUFSIZE here since that value is used to determine
        thememory allocated for the buffer. This option is given to you
        soyou may decide to use different buffer size than the default
        1024.


        lineRead() returns the newline terminated string in rl_line field
        oflineread structure. Return values of lineRead() are:


             1 - RL_BUFSIZE     - normal length of returned string.


             0                   - If zero is returned just after select(),
                                   end-of-file condition has occurred.
                                   Otherwise string is not completed yet.
                                   Make sure you call select() (or use non-
                                   blocking IO) if you don't want next call


System Manual                  AmiTCP/IP                 Section C.1    183



                                   to  block.


            -1                   - if rl_Line field of lineread structure
                                   is NULL, it indicates error condition.
                                   If rl_Line points to start of string
                                   buffer, input string has been longer
                                   than buffer. In this case rl_Line points
                                   to zero terminated string of length
                                   RL_BUFSIZE.


        Youmay modify the zero terminated string returned by lineRead() in
        anyway, but memory around the string is private lineread memory.


   EXAMPLE
        /*
         * The following code shows how to use lineread with select()
         */
        #ifdef  USE_LOW_MEMORY_BUFFER
        #define RL_BUFSIZE 256
        #endif


        #include <sys/types.h>
        #ifdef  AMIGA
        #include <bsdsocket.h>
        #endif
        #include <lineread.h>


        #define NULL 0


        ...


        main_loop(int sock)
        -
          struct LineRead* rl;
          int length;
          fd_set reafdfs;


          if (rl = (struct LineRead *)AllocMem(sizeof (*rl), 0)) -


            initLineRead(rl, sock, LF_REQLF, RL_BUFSIZE);


            FD_ZERO(&readfds);


            while(1) -
              FD_SET(sock, &readfds);


              if (select(sock + 1, &readfds, NULL, NULL, NULL)) < 0) -
                perror("select");
                break;
              "
              if (FD_ISSET(sock, &readfds))
                if ((length = lineRead(rl)) == 0) /* EOF */
                  break;
                do -
                  if (length > 0)


184    Section C.1                 AmiTCP/IP                  System Manual



                    write(1, rl->rl_Line, length); /* stdout. write() for */
                                                      /* speed demonstration*/
                  else - /* length == -1 */
                    if (rl->rl_Line == NULL); -
                       perror("lineRead");
                       break;
                    "
                    else -
                       fprintf(stderr, "lineread input buffer overflow!"n");
                       write(1, rl->rl_Line, RL_BUFSIZE);
                       write(1, ""n", 1);
                    "
                  "
                " while ((length = lineRead(rl)) != 0); /* 0 -> doselect() */
            "
          FreeMem(rl, sizeof (*rl);
          "
          else
            fprintf("AllocMem: Out Of memory"n");
        "


    PORTABILITY
        Thesource modules lineread.c and lineread.h should compile
        inUNIX machines as is.


    AUTHORS
        Tomi  Ollila,
        theAmiTCP/IP Group <amitcp-group@hut.fi>,


    SEE ALSO
        readChar(), bsdsocket.library/recv()





Appendix D



Protocols  and  Network Interfaces



The AutoDoc file protocol.doc contains on-line manual pages for protocols
and network interfaces.



Table  of  Contents


        arp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : : 186
        icmp : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
 * : : : : : : : : : 189
        if  : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : : 190
        inet : : : : : : : : : : : : : : : : : : : : : :: : : : : : : : : : : :*
 * : : : : : : : : : 193
        ip  : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : : 196
        lo  : : : : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : : 198
        routing : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : 199
        tcp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : : 201
        udp : : : : : : : :: : : : : : : : : : : : : : : : : : : : : : : : : : *
 *: : : : : : : : : : 203



                                      185


186    Section D.1                 AmiTCP/IP                  System Manual



D.1     Protocols  and  Network  Interfaces



D.1.1   arp


   NAME
        arp- Address Resolution Protocol


   CONFIG
        AnySANA-II device driver using ARP


   SYNOPSIS
        #include <sys/socket.h>
        #include <net/if_arp.h>
        #include <netinet/in.h>


        s =socket(AF_INET, SOCK_DGRAM, 0);


   DESCRIPTION
        ARPis a protocol used to dynamically map between Internet
        Protocol (IP) and hardware addresses. It can be used by most
        theSANA-II network interface drivers. The current
        implementation supports only Internet Protocol (and is tested
        only with Ethernet).  However, ARP is not limited to only that
        combination.


        ARPcaches IP-to-hardware address mappings. When an interface
        requests a mapping for an address not in the cache, ARP queues
        themessage which requires the mapping and broadcasts a
        message on the associated network requesting the address
        mapping. If a response is provided, the new mapping is cached
        andany pending message is transmitted. ARP will queue at most
        onepacket while waiting for a mapping request to be responded
        to;only the most recently transmitted packet is kept.


        Theaddress mapping caches are separate for each interface. The
        amount of mappings in the cache may be specified with an
        IoctlSocket() request.


        Tofacilitate communications with systems which do not use ARP,
        IoctlSocket() requests are provided to enter and delete entries
        inthe IP-to-Ethernet tables.


   USAGE
        #include <sys/ioctl.h>
        #include <sys/socket.h>
        #include <net/if.h>
        #include <net/if_arp.h>


        struct arpreq arpreq;


        IoctlSocket(s, SIOCSARP, (caddr_t)&arpreq);
        IoctlSocket(s, SIOCGARP, (caddr_t)&arpreq);
        IoctlSocket(s, SIOCDARP, (caddr_t)&arpreq);


        These three IoctlSocket()s take the same structure as an argument.


System Manual                  AmiTCP/IP                 Section D.1    187



        SIOCSARP sets an ARP entry, SIOCGARP gets an ARP entry, and SIOCDARP
        deletes an ARP entry. These IoctlSocket() requests may be applied to
        anysocket descriptor (s). The arpreq structure contains:


        /*Maximum number of octets in protocol/hw address */
        #define  MAXADDRARP   16


        /*
         * ARP ioctl request.
         */
        struct arpreq -
                struct  sockaddr arp_pa;  /* protocol address */
                struct  -                  /* hardware address */
                  u_char sa_len;          /* actual length + 2 */
                  u_char sa_family;
                  char   sa_data[MAXADDRARP];
                "  arp_ha;
                int     arp_flags;                     /* flags */
        ";


        /*  arp_flags andat_flags field values */
        #define ATF_INUSE        0x01          /* entry in use */
        #define ATF_COM         0x02        /* completed entry */
        #define ATF_PERM        0x04        /* permanent entry */
        #define ATF_PUBL         0x08          /* publish entry */



        Theinterface whose ARP table is manipulated is specified by
        arp_pa sockaddr. The address family for the arp_pa sockaddr
        must be AF_INET; for the arp_ha sockaddr it must be AF_UNSPEC.
        Thelength of arp_ha must match the length of used hardware
        address. Maximum length for the hardware address is MAXADDRARP
        bytes. The only flag bits which may be written are ATF_PERM
        andATF_PUBL. ATF_PERM makes the entry permanent if the
        IoctlSocket() call succeeds. ATF_PUBL specifies that the ARP
        code should respond to ARP requests for the indicated host
        coming from other machines.  This allows a host to act as an
        ARPserver which may be useful in convincing an ARP-only
        machine to talk to a non-ARP machine.


   UNSUPPORTED IN AmiTCP/IP


   AmiTCP/IP EXTENSIONS
        There is an extension to the standard BSD4.4 ARP ioctl interface to
        access the contents of the whole ARP mapping cache. (In the BSD4.4
        thestatic ARP table is accessed via the /dev/kmem.) The SIOCGARPT
        ioctl takes the following arptabreq structure as an argument:


        /*
         * An AmiTCP/IP specific ARP table ioctl request
         */
        struct arptabreq -
                struct arpreq atr_arpreq;  /* To identify the interface */
                long   atr_size;           /* # of elements in atr_table */
                 long   atr_inuse;                 /* # of elements in use */


188    Section D.1                 AmiTCP/IP                  System Manual



                struct arpreq *atr_table;
        ";


        Theatr_arpreq specifies the used interface. The hardware address
        forthe interface is returned in the arp_ha field of atr_arpreq
        structure.


        TheSIOCGARPT ioctl reads at most atr_size entries from the cache
        into the user supplied buffer atr_table, if it is not NULL. Actual
        amount of returned entries is returned in atr_size. The current
        amount of cached mappings is returned in the atr_inuse.


        TheSIOCGARPT ioctl has following usage:


        struct arpreq cache[N];
        struct arptabreq arptab = - N, 0, cache ";


        IoctlSocket(s, SIOCGARPT, (caddr_t)&arptabreq);


   DIAGNOSTICS
        ARPwatches passively for hosts impersonating the local host
        (that  is,  a  host which responds to an ARP mapping request
        forthe local host's address).


        "duplicate IP address a.b.c.d!!"
        "sent from hardware address: %x:%x:...:%x:%x"


        ARP has  discovered  another host on the local network
        which responds to mapping requests for its own Internet
        address.


   BUGS
        TheARP is tested only with Ethernet. Other network hardware may
        require special ifconfig configuration.


   SEE ALSO
        inet, netutil/arp, netutil/ifconfig, <net/if_arp.h>


        Plummer, Dave, ``An  Ethernet  Address  Resolution  Protocol
        -or-   ConvertingNetwork Protocol Addresses to 48.bit Ether-
        netAddresses for Transmission on Ethernet  Hardware,''  RFC
        826,  Network  Information  Center, SRI International, Menlo
        Park, Calif., November 1982. (Sun 800-1059-10)


System Manual                  AmiTCP/IP                 Section D.1    189



D.1.2   icmp

   NAME
        icmp - Internet Control Message Protocol


   SYNOPSIS
        #include <sys/socket.h>
        #include <netinet/in.h>


        int
        socket(AF_INET, SOCK_RAW, proto)


   DESCRIPTION
        ICMP is the error and control message protocol used by IP and the
        Internet protocol family.  It may be accessed through a ``raw
        socket'' for network monitoring and diagnostic functions.  The proto
        parameter to the socket call to create an ICMP socket is obtained
        from getprotobyname().  ICMP sockets are connectionless, and are
        normally used with the sendto() and recvfrom() calls, though the
        connect() call may also be used to fix the destination for future
        packets (in which case the recv() and send() socket library calls
        maybe used).


        Outgoing packets automatically have an IP header prepended to them
        (based on the destination address).  Incoming packets are received
        with the IP header and options intact.


   DIAGNOSTICS
        A socket operation may fail with one of the following errors
        returned:


        [EISCONN]         when trying to establish a connection ona socket
                          which already has one, orwhen trying to send a
                          datagram with the destination address specified and
                          the socket is already connected;


        [ENOTCONN]        when trying tosend a datagram, but no destination
                          address is specified, andthe socket hasn't been
                          connected;


        [ENOBUFS]         when the system runs out of memory for aninternal
                          data structure;


        [EADDRNOTAVAIL]  when an attempt is made to create a socket with a
                          network address for whichno network interface
                          exists.


   SEE ALSO
        bsdsocket.library/send(),  bsdsocket.library/recv(), inet,  ip


   HISTORY
        Theicmp protocol is originally from 4.3BSD.


190    Section D.1                 AmiTCP/IP                  System Manual



D.1.3   if


   NAME
        if- Network Interface to SANA-II devices


   DESCRIPTION
        Each network interface in the AmiTCP/IP corresponds to a path
        through which messages may be sent and received.  A network
        interface usually has a SANA-II device driver associated with it,
        though the loopback interface, "lo", do not. The network interface
        inthe AmiTCP/IP (sana_softc) is superset of the BSD Unix network
        interface.


        When the network interface is first time referenced, AmiTCP/IP tries
        toopen the corresponding SANA-II device driver. If successful, a
        software interface to the SANA-II device is created. The "network/"
        prefix is added to the SANA-II device name, if needed. Once the
        interface has acquired its address, it is expected to install a
        routing table entry so that messages can be routed through it.


        TheSANA-II interfaces must be configured before they will allow
        traffic to flow through them. It is done after the interface is
        assigned a protocol address with a SIOCSIFADDR ioctl. Some
        interfaces may use the protocol address or a part of it as their
        hardware address. On interfaces where the network-link layer address
        mapping is static, only the network number is taken from the ioctl;
        theremainder is found in a hardware specific manner. On interfaces
        which provide dynamic network-link layer address mapping facilities
        (for example, Ethernets or Arcnets using ARP), the entire address
        specified in the ioctl is used.


        Thefollowing ioctl calls may be used to manipulate network
        interfaces. Unless specified otherwise, the request takes an ifreq
        structure as its parameter. This structure has the form


        struct ifreq -
          char ifr_name[IFNAMSIZ]; /* interface name (eg. "slip.device/0")*/
          union -
            struct sockaddr ifru_addr;
            struct sockaddr ifru_dstaddr;
            short            ifru_flags;
          " ifr_ifru;
        #define ifr_addr     ifr_ifru.ifru_addr                   /* address */
        #define ifr_dstaddr ifr_ifru.ifru_dstaddr   /* end of p-to-p link */
        #define ifr_flags    ifr_ifru.ifru_flags                    /* flags */
        ";


        SIOCSIFADDR       Set interface address. Following the address
                          assignment, the ``initialization'' routine for
                          the interface is called.


        SIOCGIFADDR       Get interface address.


        SIOCSIFDSTADDR    Set point to point address for interface.


        SIOCGIFDSTADDR    Get point to point address for interface.


System Manual                  AmiTCP/IP                 Section D.1    191



        SIOCSIFFLAGS      Set interface flagsfield. If the interface is
                          marked down, any processes currently routing
                          packets through the interface are notified.


        SIOCGIFFLAGS      Get interface flags.


        SIOCGIFCONF       Get interface configurationlist. This request
                          takes an ifconf structure(see below) as a
                          value-result parameter. The ifc_len field should be
                          initially set to the sizeof the buffer pointed to
                          by ifc_buf. On return itwill contain the length,
                          in bytes, of the configuration list.


        /*
         * Structure used in SIOCGIFCONF request.
         * Used toretrieve interface configuration
         * for machine (useful for programs which
         * must know all networks accessible).
         */
        struct ifconf -
          int  ifc_len;                       /* size of associated buffer */
          union -
            caddr_t       ifcu_buf;
            struct ifreq *ifcu_req;
          " ifc_ifcu;
        #define ifc_buf ifc_ifcu.ifcu_buf                /* buffer address */
        #define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
        ";



   UNSUPPORTED IN AmiTCP/IP
        These standard BSD ioctl codes are not currently supported:


        SIOCADDMULTI      Enable a multicast address for the interface.


        SIOCDELMULTI      Disable a previouslyset multicast address.


        SIOCSPROMISC      Toggle promiscuous mode.


   AmiTCP/IP EXTENSIONS
        Thefollowing ioctls are used to configure protocol and hardware
        specific properties of a sana_softc interface. They are used in the
        AmiTCP/IP only.


        SIOCSSANATAGS     Set SANA-II specific properties with a tag list.


        SIOCGSANATAGS     Get SANA-II specific properties into a
                          wiretype_parameters structure and a user tag list.


        struct  wiretype_parameters
        -
          ULONG  wiretype;                /* the wiretype of theinterface */
          WORD   flags;                                         /* iff_flags*/
          struct TagItem*tags;                   /* tag list userprovides */


192    Section D.1                 AmiTCP/IP                  System Manual



        ";


   SEE ALSO
        arp, lo, netutil/arp, netutil/ifconfig, <sys/ioctl.h>, <net/if.h>,
        <net/sana2tags.h>


System Manual                  AmiTCP/IP                 Section D.1    193



D.1.4   inet


   NAME
        inet - Internet protocol family


   SYNOPSIS
        #include <sys/types.h>
        #include <netinet/in.h>


   DESCRIPTION
        TheInternet protocol family implements a collection of protocols
        which are centered around the Internet Protocol (IP) and which share
        a common address format.  The Internet family provides protocol
        support for the SOCK_STREAM, SOCK_DGRAM, and SOCK_RAW socket types.


   PROTOCOLS
        TheInternet protocol family is comprised of the Internet Protocol
        (IP), the Address Resolution Protocol (ARP), the Internet Control
        Message Protocol (ICMP), the Transmission Control Protocol (TCP),
        andthe User Datagram Protocol (UDP).


        TCPis used to support the SOCK_STREAM abstraction while UDP is used
        tosupport the SOCK_DGRAM abstraction; (SEE ALSO tcp, SEE ALSO udp).
        A raw interface to IP is available by creating an Internet socket of
        type SOCK_RAW; (SEE ALSO ip).  ICMP is used by the kernel to handle
        andreport errors in protocol processing.  It is also accessible to
        user programs; (SEE ALSO icmp).  ARP is used to translate 32-bit IP
        addresses into varying length hardware addresses; (SEE ALSO arp).


        The32-bit IP address is divided into network number and host number
        parts.   It is frequency-encoded; the most significant bit is zero in
        Class A addresses, in which the high-order 8 bits are the network
        number.   Class Baddresses have their high order two bits set to 10
        anduse the highorder 16 bits as the network number field.  Class C
        addresses have a 24-bit network number part of which the high order
        three bits are 110.  Sites with a cluster of local networks may
        chose to use a single network number for the cluster; this is done
        byusing subnet addressing.  The local (host) portion of the address
        isfurther subdivided into subnet number and host number parts.
        Within a subnet, each subnet appears to be an individual network;
        externally, the entire cluster appears to be a single, uniform
        network requiring only a single routing entry.  Subnet addressing is
        enabled and examined by the following ioctl commands on a datagram
        socket in the Internet domain; they have the same form as the
        SIOCIFADDR (SEE ALSO if) command.


        SIOCSIFNETMASK       Set interface network mask.   The network mask
                             defines the network part of the address; ifit
                             contains more of the address than the address
                             type would indicate, then subnets are in use.


        SIOCGIFNETMASK       Get interface network mask.


   ADDRESSING
        IPaddresses are four byte quantities, stored in network byte order
        (the native Amiga byte order)


194    Section D.1                 AmiTCP/IP                  System Manual



        Sockets in the Internet protocol family  use  the  following
        addressing structure:
             struct sockaddr_in -
                  short      sin_family;
                  u_short   sin_port;
                  struct     in_addr sin_addr;
                  char sin_zero[8];
             ";


        Functions in bsdsocket.library are provided to manipulate structures
        ofthis form.


        Thesin_addr field of the sockaddr_in structure specifies a local or
        remote IP address.  Each network interface has its own unique IP
        address.   The special value INADDR_ANY may be used in this field to
        effect "wildcard" matching.  Given in a bind() call, this value
        leaves the local IP address of the socket unspecified, so that the
        socket will receive connections or messages directed at any of the
        valid IP addresses of the system.  This can prove useful when a
        process neither knows nor cares what the local IP address is or when
        a process wishes to receive requests using all of its network
        interfaces.   Thesockaddr_in structure given in the bind() call must
        specify an in_addr value of either IPADDR_ANY or one of the system's
        valid IP addresses.  Requests to bind any other address will elicit
        theerror EADDRNOTAVAIL. When a connect() call is made for a socket
        that has a wildcard local address, the system sets the sin_addr
        field of the socket to the IP address of the network interface that
        thepackets for that connection are routed via.


        Thesin_port field of the sockaddr_in structure specifies a port
        number used by TCP or UDP. The local port address specified in a
        bind() call is restricted to be greater than IPPORT_RESERVED
        (defined in <netinet/in.h>) unless the creating process is running
        asthe super-user, providing a space of protected port numbers.  In
        addition, the local port address must not be in use by any socket of
        same address family and type.  Requests to bind sockets to port
        numbers being used by other sockets return the error EADDRINUSE.  If
        thelocal port address is specified as 0, then the system picks a
        unique port address greater than IPPORT_RESERVED.  A unique local
        port address is also picked when a socket which is not bound is used
        ina connect() or send() call.  This allows programs which do not
        care which local port number is used to set up TCP connections by
        sim- ply calling socket() and then connect(), and to send UDP
        datagrams with a socket() call followed by a send() call.


        Although this implementation restricts sockets to unique local port
        numbers, TCP allows multiple simultaneous connections involving the
        same local port number so long as the remote IP addresses or port
        numbers are different for each connection.  Programs may explicitly
        override the socket restriction by setting the SO_REUSEADDR socket
        option with setsockopt (see getsockopt()).


   SEE ALSO
        bsdsocket.library/bind(), bsdsocket.library/connect(),


System Manual                  AmiTCP/IP                 Section D.1    195



        bsdsocket.library/getsockopt(), bsdsocket.library/IoctlSocket(),
        bsdsocket.library/send(), bsdsocket.library/socket(),
        bsdsocket.library/gethostent(), bsdsocket.library/getnetent(),
        bsdsocket.library/getprotoent(), bsdsocket.library/getservent(),
        bsdsocket.library/inet_addr(), arp, icmp, ip, tcp, udp


        Network Information Center, DDN Protocol Handbook (3 vols.),
        Network  Information  Center, SRI International, Menlo Park,
        Calif.,  1985.
        A AmiTCP/IP Interprocess Communication Primer


   WARNING
        TheInternet protocol support is subject to change as the Internet
        protocols develop.  Users should not depend on details of the
        current implementation, but rather the services exported.


196    Section D.1                 AmiTCP/IP                  System Manual



D.1.5   ip


   NAME
        ip- Internet Protocol


   SYNOPSIS
        #include <sys/socket.h>
        #include <netinet/in.h>


        int
        socket(AF_INET, SOCK_RAW, proto)


   DESCRIPTION
        IPis the transport layer protocol used by the Internet protocol
        family.   Optionsmay be set at the IP level when using higher-level
        protocols that are based on IP (such as TCP and UDP). It may also be
        accessed through a ``raw socket'' when developing new protocols, or
        special purpose applica- tions.


        A single generic option is supported at the IP level, IP_OPTIONS,
        that may be used to provide IP options to be transmitted in the IP
        header of each outgoing packet.  Options are set with setsockopt()
        andexamined with getsockopt().  The format of IP options to be sent
        isthat specified by the IP protocol specification, with one
        exception: the list of addresses for Source Route options must
        include the first-hop gateway at the beginning of the list of
        gateways.   The first-hop gateway address will be extracted from the
        option list and the size adjusted accordingly before use.  IP
        options may be used with any socket type in the Internet family.


        RawIP sockets are connectionless, and are normally used with the
        sendto and recvfrom calls, though the connect() call may also be
        used to fix the destination for future packets (in which case the
        recv() and send() system calls may be used).


        Ifproto is 0, the default protocol IPPROTO_RAW is used for outgoing
        packets, and only incoming packets destined for that protocol are
        received.   If proto is non-zero, that protocol number will be used
        onoutgoing packets and to filter incoming packets.


        Outgoing packets automatically have an IP header prepended to them
        (based on the destination address and the protocol number the socket
        iscreated with).  Incoming packets are received with IP header and
        options  intact.


   DIAGNOSTICS
        A socket operation may fail with one of the following errors
        returned:


        [EISCONN]         when trying to establish a connection ona socket
                          which already has one, orwhen trying to send a
                          datagram with the destination address specified and
                          the socket is already connected;


        [ENOTCONN]        when trying tosend a datagram, but no destination
                          address is specified, andthe socket hasn't been


System Manual                  AmiTCP/IP                 Section D.1    197



                          connected;


        [ENOBUFS]         when the system runs out of memory for aninternal
                          data structure;


        [EADDRNOTAVAIL]  when an attempt is made to create a socket with a
                          network address for whichno network interface
                          exists.


        Thefollowing errors specific to IP may occur when setting or
        getting IP options:


        [EINVAL]          An unknown socket option name was given.


        [EINVAL]          The IP option field was improperly formed; an
                          option field was shorterthan the minimum value or
                          longer than the option buffer provided.


   SEE ALSO
        bsdsocket.library/getsockopt(), bsdsocket.library/send(),
        bsdsocket.library/recv(), icmp, inet


   HISTORY
        Theip protocol appeared in 4.2BSD.


198    Section D.1                 AmiTCP/IP                  System Manual



D.1.6   lo

   NAME
        lo- Software Loopback Network Interface


   SYNOPSIS
        pseudo-device
        loop


   DESCRIPTION
        Theloop interface is a software loopback mechanism which may be
        used for performance analysis, software testing, and/or local
        communication.  There is no SANA-II interface associated with lo.
        Aswith other network interfaces, the loopback interface must have
        network addresses assigned for each address family with which it is
        tobe used.   These addresses may be set or changed with the
        SIOCSIFADDR ioctl. The loopback interface should be the last
        interface configured, as protocols may use the order of
        configuration as an indication of priority.  The loopback should
        never be configured first unless no hardware interfaces exist.


   DIAGNOSTICS
        "lo%d: can't handle af%d."
        Theinterface was handed a message with ad- dresses formatted in an
        unsuitable address family; the packet was dropped.


   SEE ALSO
        inet, if, netutil/ifconfig


   BUGS
        Older BSD Unix systems enabled the loopback interface
        automatically, using a nonstandard Internet address (127.1).  Use
        ofthat address is now discouraged; a reserved host address for the
        local network should be used instead.


System Manual                  AmiTCP/IP                 Section D.1    199



D.1.7   routing


   NAME
        routing - system supporting for local network packet routing


   DESCRIPTION
        Thenetwork facilities provided general packet routing,
        leaving routing table maintenance to applications processes.


        A simple set of data structures comprise a ``routing table''
        used in selecting the appropriate network interface when
        transmitting packets.  This table contains a single entry for
        each route to a specific network or host.  A user process, the
        routing daemon, maintains this data base with the aid of two
        socket specific ioctl commands, SIOCADDRT and SIOCDELRT.
        Thecommands allow the addition and deletion of a single
        routing table entry, respectively.  Routing table
        manipulations may only be carried out by super-user.


        A routing table entry has the following form, as defined  in
        <net/route.h>:
             struct rtentry -
                  u_long     rt_hash;
                  struct     sockaddr rt_dst;
                  struct     sockaddr rt_gateway;
                  short      rt_flags;
                  short      rt_refcnt;
                  u_long     rt_use;
                  struct     ifnet  *rt_ifp;
             ";
        with rt_flags defined from:
          #define   RTF_UP          0x1               /* route usable */
          #define   RTF_GATEWAY    0x2  /* destination is a gateway */
          #define   RTF_HOST  0x4     /* host entry (net otherwise) */


        Routing table entries come in three flavors: for a specific
        host, for all hosts on a specific network, for any destination
        notmatched by entries of the first two types (a wildcard
        route).   When the system is booted, each network interface
        autoconfigured installs a routing table entry when it wishes
        tohave packets sent through it.  Normally the interface
        specifies the route through it is a ``direct'' connection to
        thedestination host or network.  If the route is direct, the
        transport layer of a protocol family usually requests the
        packet be sent to the same host specified in the packet.
        Otherwise, the interface may be requested to address the
        packet to an entity different from the eventual recipient
        (that is, the packet is forwarded).


        Routing table entries installed by a user process may not
        specify the hash, reference count, use, or interface fields;
        these are filled in by the routing routines.  If a route is in
        usewhen it is deleted (rt_refcnt is non-zero), the resources
        associated with it will not be reclaimed until all references
        toit are removed.


200    Section D.1                 AmiTCP/IP                  System Manual



        Therouting code returns EEXIST if requested to duplicate an
        existing entry, ESRCH if requested to delete a non-existent
        entry, or ENOBUFS if insufficient resources were available to
        install a new route.


        Thert_use field contains the number of packets sent along the
        route.   This value is used to select among multiple routes to
        thesame destination.  When multiple routes to the same
        destination exist, the least used route is selected.


        A wildcard routing entry is specified with a zero destination
        address value.  Wildcard routes are used only when the system
        fails to find a route to the destination host and network.
        Thecombination of wildcard routes and routing redirects can
        provide an economical mechanism for routing traffic.


   SEE ALSO
        bsdsocket.library/IoctlSocket(), netutil/route


System Manual                  AmiTCP/IP                 Section D.1    201



D.1.8   tcp


   NAME
        tcp- Internet Transmission Control Protocol


   SYNOPSIS
        #include <sys/socket.h>
        #include <netinet/in.h>


        int
        socket(AF_INET, SOCK_STREAM, 0)


   DESCRIPTION
        TheTCP protocol provides reliable, flow-controlled, two-way
        transmission of data.  It is a byte-stream protocol used to support
        theSOCK_STREAM abstraction.  TCP uses the standard Internet address
        format and, in addition, provides a per-host collection of ``port
        addresses''. Thus, each address is composed of an Internet address
        specifying the host and network, with a specific TCP port on the
        host identifying the peer entity.


        Sockets utilizing the tcp protocol are either ``active'' or
        ``passive''.   Active sockets initiate connections to passive
        sockets.   By default TCP sockets are created active; to create a
        passive socket the listen() bsdsocket.library function call must be
        used after binding the socket with the bind() bsdsocket.library
        function call.  Only passive sockets may use the accept() call to
        accept incoming connections.  Only active sockets may use the
        connect() call to initiate connections.


        Passive sockets may ``underspecify'' their location to match
        incoming connection requests from multiple networks.  This
        technique, termed ``wildcard addressing'', allows a single server to
        provide service to clients on multiple networks.  To create a socket
        which listens on all networks, the Internet address INADDR_ANY must
        bebound.   The TCP port may still be specified at this time; if the
        port is not specified the bsdsocket.library function will assign
        one.   Once a connection has been established the socket's address is
        fixed by the peer entity's location.  The address assigned the
        socket is the address associated with the network interface through
        which packets are being transmitted and received.  Normally this
        address corresponds to the peer entity's network.


        TCPsupports one socket option which is set with setsockopt() and
        tested with getsockopt().  Under most circumstances, TCP sends data
        when it is presented; when outstanding data has not yet been
        acknowledged, it gathers small amounts of output to be sent in a
        single packet once an acknowledgement is received.  For a small
        number of clients, such as X Window System functions that
        send a stream of mouse events which receive no replies, this
        packetization may cause significant delays.  Therefore, TCP provides
        a boolean option, TCP_NODELAY (from <netinet/tcp.h>, to defeat this
        algorithm.   Theoption level for the setsockopt call is the protocol
        number for TCP, available from getprotobyname().


        Options at the IP transport level may be used with TCP; SEE ALSO ip.


202    Section D.1                 AmiTCP/IP                  System Manual



        Incoming connection requests that are source-routed are noted, and
        thereverse source route is used in responding.


   DIAGNOSTICS
        A socket operation may fail with one of the following errors
        returned:


        [EISCONN]         when trying to establish a connection ona socket
                          which already has one;


        [ENOBUFS]         when the AmiTCP/IP runs out of memory foran internal
                          data structure;


        [ETIMEDOUT]       when a connection was dropped due to excessive
                          retransmissions;


        [ECONNRESET]      when the remote peerforces the connection to be
                          closed;


        [ECONNREFUSED]    when the remote peer actively refuses connection
                          establishment (usually because no process is
                          listening to the port);


        [EADDRINUSE]      when an attempt is made to create a socket with a
                          port which has already been allocated;


        [EADDRNOTAVAIL]  when an attempt is made to create a socket with a
                          network address for whichno network interface
                          exists.


   SEE ALSO
        bsdsocket.library/getsockopt(), bsdsocket.library/socket(),
        bsdsocket.library/bind(), bsdsocket.library/listen(),
        bsdsocket.library/accept(), bsdsocket.library/connect(), inet,
        ip,<sys/socket.h>, <netinet/tcp.h>, <netinet/in.h>


   HISTORY
        Thetcp protocol stack appeared in 4.2BSD.


System Manual                  AmiTCP/IP                 Section D.1    203



D.1.9   udp


   NAME
        udp- Internet User Datagram Protocol


   SYNOPSIS
        #include <sys/socket.h>
        #include <netinet/in.h>


        int
        socket(AF_INET, SOCK_DGRAM, 0)


   DESCRIPTION
        UDPis a simple, unreliable datagram protocol which is used to
        support the SOCK_DGRAM abstraction for the Internet protocol family.
        UDPsockets are connectionless, and are normally used with the
        sendto() and recvfrom() calls, though the connect() call may also be
        used to fix the destination for future packets (in which case the
        recv() and send() function calls may be used).


        UDPaddress formats are identical to those used by TCP. In
        particular UDP provides a port identifier in addition to the normal
        Internet address format.  Note that the UDP port space is separate
        from the TCP port space (i.e. a UDP port may not be ``connected'' to
        a TCP port). In addition broadcast packets may be sent (assuming the
        underlying network supports this) by using a reserved ``broadcast
        address''; this address is network interface dependent.


        Options at the IP transport level may be used with UDP; SEE ALSO ip.


   DIAGNOSTICS
        A socket operation may fail with one of the following errors
        returned:


        [EISCONN]         when trying to establish a connection ona socket
                          which already has one, orwhen trying to send a
                          datagram with the destination address specified and
                          the socket is already connected;


        [ENOTCONN]        when trying tosend a datagram, but no destination
                          address is specified, andthe socket hasn't been
                          connected;


        [ENOBUFS]         when the system runs out of memory for an
                          internal data structure;


        [EADDRINUSE]      when an attempt is made to create a socket with a
                          port which has already been allocated;


        [EADDRNOTAVAIL]  when an attempt is made to create a socket with a
                          network address for whichno network interface
                          exists.


   SEE ALSO
        bsdsocket.library/getsockopt(), bsdsocket.library/recv(),
        bsdsocket.library/send(), bsdsocket.library/socket(), inet, ip


204    Section D.1                 AmiTCP/IP                  System Manual



   HISTORY
        Theudp protocol appeared in 4.2BSD.





Glossary



API Application Program Interface.  Standard function calls, messages and
    devices used in application level programs.


Arcnet Yet another network type, transfer rate 5Mbits/sec.


ARexx ARexx is a specific implementation of the Rexx language forthe
    Amiga.  Rexx itself is a script language with superb power/simplicity
    ratio, originally developed for some IBM mainframe systems.


ARP Address Resolution Protocol.  A communication protocol used tomap
    protocol address to network address dynamically.  For example, ARP is
    used to map DARPA Internet addresses into Ethernet addresses.


AutoDoc Document generated automagically from comments included in
    program source code.  Mainly used to describe shared library
    functions in AmigaOS. See [RKM Inc & ADoc 1992 ].


BSD Berkeley Software Distribution.  Family of UNIX versions for the DEC
    (VAX) and PDP-11 developed by Bill Joy and others at Berzerkeley
    starting around 1980, incorporating paged virtual memory, TCP/IP
    networking enhancements, and many other features.  The BSD versions
    (4.1, 4.2, and 4.3) and the commercial versions derived from them
    (SunOS, ULTRIX, and Mt.  Xinu) held the technical lead in the UNIX
    world until AT&T's successful standardization efforts after about
    1986, and are still widely popular.


BSDSS BSD Single Server is operating system server in Mach operating
    system where all UNIX services are in single binary.


(D)ARPA Internet  The collection of networks using internet protocols.
    (D)ARPA Internet originated from a research project sponsored by the
    (Defense) Advanced Research Project Agency.


Daemon 'A deified being', program that lives forever on system, or
    reincarnates every time it is needed.  Performs its requested task
    promptly and goes back to sleep.


Data link layer  Protocol layer providing data transfer between machines
    in same physical network.


DIS First stage in ISO's standardization.  (Discussion)



                                      205


206    Section D.1                 AmiTCP/IP                  System Manual



Ethernet 10Mbit/sec physical network interface.  Developed by Xerox in
    Palo Alto late 70s.  In 1982 published with Digital and Intel as
    ESPEC1.  ESPEC2 was approved as basic specification for LANs which
    employed the carrier sense multiple access with collision detection
    by IEEE 802.3 committee.  Heavily derived version was later published
    by ISO as DIS 8802/3.  Original has only version for 50  coaxial
    cable, 10BASE5 ``Thick Ether'', but nowadays has also for thinner
    coaxial cable, 10BASE2 ``Thin Ether'', twisted pair, 10BASET and
    fibre, 10BASEF. There are also broadband, 10BROAD36, and slower,
    1Mbit/s 1BASE5, versions.


EXEC AmigaOS EXECutive.  Provides the basic kernel functions, such as
    task scheduling, memory management, concurrency control, message
    ports, public library lists etc.


Frame Data unit transferred between data link layer protocol entities.


ICMP Internet Message Control Protocol.  A host-to-host communication
    protocol used in the DARPA Internet for reporting errors and
    controlling the operation of IP.


IEEE the Institute of Electrical and Electronics Engineers


Inetd the Internet super server.  A server that listens to the network
    and launches other server processes when needed.


IO request  An Amiga standard message format to discuss with devices.  IO
    requests are sent by Exec function BeginIO() to the device driver.
    Completed IO requests are sent back to the reply port specified in IO
    request.


IP Internet Protocol.  The network-layer communication protocol used in
    the DARPA Internet.  IP is responsible for host-to-host addressing
    and routing, packet forwarding, and packet fragmentation and
    reassembly.


ISO International Organization for Standardization


Jargon A formal technical vocabulary of various subjects.  Also hackish
    slang or mumbo jumbo is referred as jargon [Raymond 1992 ].


Library base  In AmigaOS shared library is accessed via a library base
    pointer.  On the negative side (relative to the base pointer) there
    is jump table to the library functions and on the positive side --
    library data the functions can use.


Log It is usually useful to record information.  If something hasgone
    wrong, one may found information to remove cause of failure.  A log
    is usually a file, where information is written.


Mbuf Memory BUFfer.  Data storage unit inside BSD networking
    implementation.


Message Data unit transferred between applications using network
    services.


System Manual                  AmiTCP/IP                 Section D.1    207



MTU Maximum Transfer Unit.  The amount of data that underlying network
    can transfer in one block.

NET/2 Latest (by now) BSD Unix release.

Network File System  A filesystem share protocol which enables other
    computers use disks on other host over network.  Usually uses UDP
    protocol for transfering files, but also TCP-based version exists.
    Developed by Sun Microsystems Inc., and developed to ``Industrial
    Standard'' in *IX environment.  Described in detail ``Networking on
    the Sun Workstation''

Octet A unit of eigth bits.  Used in communication to overcome problem
    that byte is not allways eigth bits (althoug this is nowadays very
    rare situation.)

Packet Data unit transferred between network layer protocol entities.

panic() Function executed after lethal failure in Unix kernel.

PPP Point-to-Point Protocol which allows multiple protocols to be
    transferred on the same line.  It is also more flexible than SLIP.

Protocol stack  A network protocol stack is a layerof software that
    network applications use to address particular processes on remote
    machines.  The AmiTCP/IP is such a protocol stack using TCP/IP
    protocols.

RARP Reverse Address Resolution Protocol maps network addresses to
    protocol addresses dynamically.

RFC Request For Comments.  Freely available standards for networking.
    They are mostly available online from nic.ddn.mil with FTP or Kermit.

RKM Rom Kernel reference Manuals are the most authoritative AmigaOS
    references, see [RKM Libraries 1992 ] for example.

SANA-II A standard for an Amiga software interface between networking
    hardware and network protocol stacks (or for software tools such as
    network monitors).

SLIP Serial Line Internet Protocol.  Data encapsulation protocol used to
    transmit IP packets over point-to-point serial lines.

Socket An abstraction for endpoint of communication.

TLA Three Letter Acronym, a mnemonic and mystic abbreviation which is
    coined to confuse acolytes.

TCP Transmission Control Protocol.  A connection-oriented transport
    protocol used in the DARPA Internet.  TCP provides for the reliable
    transfer of data, as well as the out-of-band indication of urgent
    data.

TCP/IP The whole protocol stack, which implements at least the Internet
    protocols required is often expressed as the two most commonly used,
    TCP/IP


208    Section D.1                 AmiTCP/IP                  System Manual



UDP User Datagram Protocol.  A simple unreliable datagram protocolused
    in the DARPA Internet.  UDP provides only peer-to-peer addressing and
    optional data checksum.

Wire type  is the physical layer protocol type.  Different wire types are
    for instance Arcnet, Ethernet, IEEE 802.3, PPP and SLIP.





Bibliography



[Comer 1988]               Comer, D. E., Internetworking With TCP/IP Vol I:
                           Principles, Protocols and Architecture,
                           Prentice--HallInternational, 382 p.


[Comer and Stevens 1991]   Comer, D. E. and Stevens, D. L., Internetworking
                           With TCP/IP VolII: Design, Implementation, and
                           Internals, Prentice--Hall International, 524 p.


[Finlayson et al 1984]     Finlayson, R.,Mann, T., Mogul, J. and Theimer,
                           M., ``A ReverseAddress Resolution Protocol,''
                           RFC 903, 4 p.


[Holloway 1991]            Holloway, T., ``Object Oriented Amiga EXEC,''
                           BYTE, vol. 16,issue 1, pp. 329--334, January
                           1991.


[Jacobson 1990]            Jacobson, V., ``Compressing TCP/IP Headers for
                           Low-speed Serial Links,'' RFC 1144, 43 p.


[Leffler et al 1989]       Leffler, S. J.,McKusick, M. K., Karels, M. J.
                           and Quarterman,J. S., The Design and
                           Implementationof the 4.3BSD UNIX Operating
                           System, Addison--Wesley 471 p.


[Leffler et al 1991a]      Leffler, S. J.,Fabry, R. S., Joy, W. N.,
                           Lapsley, P., Miller, S., Torek, C., ``An
                           Advanced 4.3BSDInterprocess Communication
                           Tutorial'' UNIXProgrammer's Supplementary
                           Documents (PS1), net/2 Berkeley Software
                           Distribution, Computer Systems Research Group,
                           Univ. of California, Berkeley, 53 p.


[Leffler et al 1991b]      Leffler, S. J.,Joy, W. N., Fabry, R. S. and
                           Karels, M. J.,``Networking Implementation
                           Notes, 4.3BSD Edition,'' UNIX System Manager's
                           Manual (SMM), net/2 Berkeley Software
                           Distribution, Computer Systems Research Group,
                           Computer Science Division, Univ. of California,
                           Berkeley, 26 p.


[Plummer 1982]             Plummer, D. C.,``An Ethernet Address Resolution
                           Protocol,'' RFC826, 10 p.



                                      209


210    Section D.1                 AmiTCP/IP                  System Manual



[Postel 1980]              Postel, J., ``User Datagram Protocol,'' RFC 768,
                           3 p.

[Postel 1981a]             Postel, J. ed.,``Internet Protocol,'' RFC 791,
                           45 p.

[Postel 1981b]             Postel, J., ``Internet Control Message
                           Protocol,'' RFC792, 21 p.

[Postel 1981c]             Postel, J. ed.,``Transmission Control
                           Protocol,'' RFC793, 85 p.

[Raymond 1992]             Raymond, Eric ed., ``The Jargon File 2.9.9'',
                           the on-line hacker Jargon File, version 2.9.9,
                           01 APR 1992.

[Reynolds 1990]            Reynolds, JoyceK., ``Assigned Numbers'', RFC
                           1060, 86 p.

[RKM Libs & Devs 1989]     Commodore--Amiga Inc., Amiga ROM Kernel
                           Reference Manual:   Librariesand Devices,
                           Addison Wesley,956 p.

[RKM Libraries 1992]       Commodore--Amiga Inc., Amiga ROM Kernel
                           Reference Manual:   Libraries, 3rd ed., Addison
                           Wesley, 967 p.

[RKM Inc & ADoc 1992]      Commodore--Amiga Inc., Amiga ROM Kernel
                           Reference Manual:   Includes& AutoDocs, 3rd ed.,
                           Addison Wesley,471 p.

[SANA-II 1992]             Amiga Networking Group, ``SANA-II Network Device
                           Driver Specification - Rev 1.0 23-Apr-92,''
                           published at Fred Fish-collection disk#673.

[SANA-II 1992 add]         Amiga Networking Group, ``Addenda to SANA-II
                           Network DeviceDriver Specification,'' published
                           at SANA-II Developer Support Package, May 21,
                           1992.

[Stevens 1990]             Stevens, W., R., UNIX network programming,
                           Prentice Hall,772 p.

[Winsock 1992]             Hall, M., Towfiq, M., Arnold, G., Trendwell, D.,
                           Sanders, H., ``Windows Sockets An Open Interface
                           for Network Programming under Microsoft Windows
                           Version 1.0 Rev.A'' 11 June, 1992, 124 p.


   The RFC documents are stored online on nic.ddn.mil, from where they can
be downloaded with anonymous FTP. The file /rfc/rfc-index.txt contains
index to all published RFCs.
   The BSD documents are carried by many FTP sites, for example
nic.funet.fi.
