home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / lan / netx / doc / techref.doc < prev    next >
Text File  |  1987-09-10  |  27KB  |  568 lines

  1. Amateur Radio Internet Technical Reference
  2.  
  3. This file describes the "guts" of the Internet package for the benefit
  4. of programmers who wish to write their own applications, or adapt the
  5. code to different hardware environments.
  6.  
  7. The code as distributed includes both the functions of an IP packet switch
  8. and an end-host system, including several servers. The implementation is highly
  9. modular, however. For example, if one wants to build a dedicated packet switch
  10. without any local applications, the various applications and the TCP and UDP
  11. modules may easily be omitted to save space.
  12.  
  13. The package allows multiple simultaneous applications, each supporting
  14. multiple simultaneous users, each using TCP and/or UDP. The only limit is
  15. memory space, which is getting quite tight on the 820; the C compiler for the
  16. IBM PC seems to generate much more compact code (typically 1/2 as large as for
  17. the Z-80) so the PC seems more promising as a large-scale server.
  18.  
  19. Data Structures
  20.  
  21. To increase portability, the pseudo-types "int16" and "int32" are used to mean
  22. an unsigned 16-bit integer and a signed 32-bit integer, respectively.
  23. Ordinarily these types are defined in machdep.h to be "unsigned int"
  24. and "long".
  25.  
  26. The various modules pass data in chained structures called mbufs, with the
  27. following format:
  28.  
  29. struct mbuf {
  30.     struct mbuf *next;    /* Links mbufs belonging to single packets */
  31.     struct mbuf *anext;    /* Links packets on queues */
  32.     char *data;        /* Pointer to start of actual data in buffer */
  33.     int16 cnt;        /* Length of data in buffer */
  34. };
  35.  
  36. Although somewhat cumbersome to work with, mbufs make it possible to avoid
  37. memory-to-memory copies that limit performance. For example, when user data
  38. is transmitted it must first traverse several protocol layers before
  39. reaching the transmitter hardware. With mbufs, each layer adds its
  40. protocol header by allocating an mbuf and linking it to the head of the
  41. mbuf "chain" given it by the higher layer, thus avoiding several copy
  42. operations.
  43.  
  44. A number of primitives operating on mbufs are available in mbuf.c.
  45. The user may create, fill, empty and free mbufs himself with the alloc_mbuf
  46. and free_mbuf primitives, or at the cost of a single memory-to-memory copy he
  47. he may use the more convenient qdata() and dqdata() primitives.
  48.  
  49. Timer Services
  50.  
  51. TCP and IP require timers. A timer package is included, so the user must
  52. arrange to call the single entry point "tick" on a regular basis. The constant
  53. MSPTICK in timer.h should be defined as the interval between ticks in
  54. milliseconds. One second resolution is adequate. Since it can trigger a
  55. considerable amount of activity, including upcalls to user level, "tick"
  56. should not be called from an interrupt handler. A clock interrupt should
  57. set a flag which will then cause "tick" to be called at user level.
  58.  
  59. Internet Type-of-Service
  60.  
  61. One of the features of the Internet is the ability to specify precedence
  62. (i.e., priority) on a per-datagram basis. There are 8 levels of precedence,
  63. with the bottom 6 defined by the DoD as Routine, Priority, Immediate,
  64. Flash, Flash Override and CRITICAL. (Two more are available for internal
  65. network functions). For amateur use we can use the lower four as
  66. Routine, Welfare, Priority and Emergency. Three more bits specify class
  67. of service, indicating that especially high reliability, high throughput
  68. or low delay is needed for this connection. Constants for this field
  69. are defined in internet.h.
  70.  
  71. The Internet Protocol Implementation
  72.  
  73. While the user does not ordinarily see this level directly, it is described
  74. here for sake of completeness. Readers interested only in the interfaces seen
  75. by the applications programmer should skip to the TCP and UDP sections.
  76.  
  77. The IP implementation consists of three major functions: ip_route, ip_send
  78. and ip_recv.
  79.  
  80. IP Gateway (Packet Router) Support
  81.  
  82. The first, ip_route, is the IP packet switch. It takes a single argument,
  83. a pointer to the mbuf containing the IP datagram:
  84.  
  85. void
  86. ip_route(bp,rxbroadcast)
  87. struct mbuf *bp;    /* Datagram pointer */
  88. int rxbroadcast;    /* Don't forward */
  89.  
  90. All IP datagrams, coming or going, pass through this function. After option
  91. processing, if any, the datagram's destination address is extracted. If it
  92. corresponds to the local host, it is "kicked upstairs" to the upper half of
  93. IP and thence to the appropriate protocol module. Otherwise, an internal
  94. routing table consulted to determine where the datagram should be forwarded.
  95. The routing table uses hashing keyed on IP destination addresses, called
  96. "targets". If the target address is not found, a special "default" entry,
  97. if available, is used. If a default entry is not available either, an ICMP
  98. "Destination Unreachable" message containing the offending IP header is
  99. returned to the sender.
  100.  
  101. The "rxbroadcast" flag is used to prevent forwarding of broadcast packets,
  102. a practice which might otherwise result in spectacular routing loops. Any
  103. subnet interface driver receiving a packet addressed to the broadcast address
  104. within that subnet MUST set this flag.  All other packets (including locally
  105. originated packets) should have "rxbroadcast" set to zero. 
  106.  
  107. ip_route ignores the IP destination address in broadcast packets, passing them
  108. up to the appropriate higher level protocol which is also made aware of their
  109. broadcast nature. (TCP and ICMP ignore them; only UDP can accept them).
  110.  
  111. Entries are added to the IP routing table with the rt_add function:
  112.  
  113. int
  114. rt_add(target,gateway,metric,interface)
  115. int32 target;            /* IP address of target */
  116. int32 gateway;            /* IP address of neighbor gateway to reach this target */
  117. int metric;            /* "cost" measurement, available for routing decisions */
  118. struct interface *interface;    /* device interface structure */
  119.  
  120. "target" is the IP address of the destination; it becomes the hash index key
  121. for subsequent packet destination address lookups. If target == 0, the
  122. default entry is modified. "metric" is simply stored in the table; it is
  123. available for routing cost calculations when an automatic routing protocol
  124. is written. "interface" is the address of a control structure for the
  125. particular device to which the datagram should be sent; it is defined
  126. in the section "IP Interfaces".
  127.  
  128. rt_add returns 0 on success, -1 on failure (e.g., out of memory).
  129.  
  130. To remove an entry from the routing table, only the target address need
  131. be specified to the rt_drop call:
  132.  
  133. int
  134. rt_drop(target)
  135. int32 target;
  136.  
  137. rt_drop returns 0 on success, -1 if the target could not be found.
  138.  
  139. IP Interfaces
  140.  
  141. Every lower level interface used to transmit IP datagrams must have an
  142. "interface" structure, defined as follows:
  143.  
  144. /* Interface control structure */
  145. struct interface {
  146.     struct interface *next;    /* Linked list pointer */
  147.     char *name;        /* Ascii string with interface name */
  148.     int16 mtu;        /* Maximum transmission unit size */
  149.     int (*ioctl)();        /* Function to handle device control */
  150.     int (*send)();        /* Routine to call to send datagram */
  151.     int (*output)();    /* Routine to send link packet */
  152.     int (*raw)();        /* Routine to call to send raw packet */
  153.     int (*recv)();        /* Routine to kick to process input */
  154.     int (*stop)();        /* Routine to call before detaching */
  155.     int16 dev;        /* Subdevice number to pass to send */
  156.     int16 flags;        /* State of interface */
  157. #define    IF_ACTIVE    0x01
  158. #define    IF_BROADCAST    0x04    /* Interface is capable of broadcasting */
  159. };
  160.  
  161. Part of the interface structure is for the private use of the device driver.
  162. "dev" is used to distinguish between one of several identical devices (e.g.,
  163. serial links or radio channels) that might share the same send routine.
  164.  
  165. A pointer to this structure kept in the routing table. Two fields in the
  166. interface structure are examined by ip_route: "mtu" and "send". The maximum
  167. transmission unit size represents the largest datagram that this device can
  168. handle; ip_route will do IP-level fragmentation as required to meet this
  169. limit before calling "send", the function to queue datagrams on this
  170. interface. "send" is called as follows:
  171.  
  172. (*send)(bp,interface,gateway,precedence,delay,throughput,reliability)
  173. struct mbuf *bp;        /* Pointer to datagram */
  174. struct interface *interface;    /* Interface structure */
  175. int32 gateway;            /* IP address of gateway */
  176. char precedence;        /* TOS bits from IP header */
  177. char delay;
  178. char throughput;
  179. char reliability;
  180.  
  181. The "interface" and "gateway" arguments are kept in the routing table and
  182. passed on each call to the send routine. The interface pointer is passed
  183. again because several interfaces might share the same output driver (e.g.,
  184. several identical physical channels).  "gateway" is the IP address of the
  185. neighboring IP gateway on the other end of the link; if a link-level address
  186. is required, the send routine must map this address either dynamically (e.g.,
  187. with the Address Resolution Protocol, ARP) or with a static lookup table.
  188. If the link is point-to-point, link-level addresses are unnecessary, and the
  189. send routine can therefore ignore the gateway address.
  190.  
  191. The Internet Type-of-Service (TOS) bits are passed to the interface driver
  192. as separate arguments. If tradeoffs exist within the subnet between these
  193. various classes of service, the driver may use these arguments to control
  194. them (e.g., optional use of link level acknowledgments, priority queuing,
  195. etc.)
  196.  
  197. It is expected that the send routine will put a link level header on the front
  198. of the packet, add it an internal output queue, start output (if not already
  199. active) and return. It must NOT busy-wait for completion (unless it is a very
  200. fast device, e.g., Ethernet) since that blocks the entire system.
  201.  
  202. Any interface that uses ARP must also provide an "output" routine. It is a
  203. lower level entry point that allows the caller to specify the fields in the
  204. link header. ARP uses it to broadcast a request for a given IP address. It may
  205. be the same routine used internally by the driver to send IP datagrams
  206. once the link level fields have been determined. It is called as follows:
  207.  
  208. (*output)(interface,dest,src,type,bp)
  209. struct interface *interface;    /* Pointer to interface structure */
  210. char dest[];            /* Link level destination address */
  211. char src[];            /* Link level source address */
  212. int16 type;            /* Protocol type field for link level */
  213. struct mbuf *bp;        /* Data field (IP datagram) */
  214.  
  215. An even lower entry into the device driver is the "raw" entry. It accepts
  216. a complete packet and sends it EXACTLY as submitted:
  217.  
  218. (*raw)(interface,bp)
  219. struct interface *interface;    /* Pointer to interface structure */
  220. struct mbuf *bp;        /* Packet ready for transmission */
  221.  
  222. The usual procedure is for the "send" routine to call the "output"
  223. routine, which in turn finally calls the "raw" routine.  Each call
  224. should be made indirectly through the pointers in the associated
  225. interface structure.  This allows arbitrary layering of encapsulation
  226. schemes and link drivers (e.g., vanilla IP/SLIP/ASYNC plus
  227. AX.25/KISS/SLIP/ASYNC plus AX.25/HDLC), as well as special link level
  228. relay functions (e.g., AX.25 digipeating or Ethernet bridging). 
  229.  
  230. The "ioctl" pointer is called by the top-level "param" command. This allows
  231. for a driver routine to set parameters in a device-dependent way. The ioctl
  232. routine is optional; if it is present, it is called as follows:
  233.  
  234. (*ioctl)(ifp,argc,argv)
  235. struct interface *ifp;        /* Pointer to interface structure */
  236. int argc;            /* Count of arguments */
  237. char *argv[];            /* Array of parsed argument tokens */
  238.  
  239. The ioctl routine is passed the command line tokens starting with the
  240. first token after the interface name. The interpretation of these tokens
  241. and the responses are up to the ioctl routine. It should return 0 if the
  242. operation was successful, 1 if the operation failed and no further error
  243. messages should be generated by the command interpreter, and -1 if the
  244. operation failed and a default error message should be printed by the
  245. command interpreter. If the ioctl field is left null by the driver at
  246. initialization, any attempt to invoke it yields an error message.
  247.  
  248. IP Host Support
  249.  
  250. All of the modules described thus far are required in all systems. However,
  251. the routines that follow are necessary only if the system is to support
  252. higher-level applications. In a standalone IP gateway (packet switch)
  253. without servers or clients, the following modules (IP user level, TCP and
  254. UDP) may be omitted to allow additional space for buffering; define the
  255. flag GWONLY when compiling iproute.c to avoid referencing the user level
  256. half of IP.
  257.  
  258. The following function is called by iproute() whenever a datagram arrives
  259. that is addressed to the local system.  
  260.  
  261. void
  262. ip_recv(bp,rxbroadcast)
  263. struct mbuf *bp;        /* Datagram */
  264. char rxbroadcast;        /* Incoming broadcast */
  265.  
  266. ip_recv reassembles IP datagram fragments, if necessary, and calls the input
  267. function of the next layer protocol (e.g., tcp_input, udp_input) with the
  268. appropriate arguments, as follows:
  269.  
  270. (*protrecv)(bp,protocol,source,dest,tos,length,rxbroadcast);
  271. struct mbuf *bp;    /* Pointer to packet minus IP header */
  272. char protocol;        /* IP protocol ID */
  273. int32 source;        /* IP address of sender */
  274. int32 dest;        /* IP address of destination (i.e,. us) */
  275. char tos;        /* IP type-of-service field in datagram */
  276. int16 length;        /* Length of datagram minus IP header */
  277. char rxbroadcast;    /* Incoming broadcast */
  278.  
  279. The list of protocols is contained in a switch() statement in the ip_recv
  280. function. If the protocol is unsupported, an ICMP Protocol Unreachable
  281. message is returned to the sender unless the packet came in as a broadcast.
  282.  
  283. Higher level protocols such as TCP and UDP use the ip_send routine to generate
  284. IP datagrams. The arguments to ip_send correspond directly to fields in the IP
  285. header, which is generated and put in front of the user's data before being
  286. handed to ip_route:
  287.  
  288. ip_send(source,dest,protocol,tos,ttl,bp,length,id,df)
  289. int32 source;        /* source address */
  290. int32 dest;        /* Destination address */
  291. char protocol;        /* Protocol */
  292. char tos;        /* Type of service */
  293. char ttl;        /* Time-to-live */
  294. struct mbuf *bp;    /* Data portion of datagram */
  295. int16 length;        /* Optional length of data portion */
  296. int16 id;        /* Optional identification */
  297. char df;        /* Don't-fragment flag */
  298.  
  299. This interface is modeled very closely after the example given on page 32
  300. of RFC-791. Zeros may be passed for id or ttl, and system defaults will
  301. be provided. If zero is passed for length, it will be calculated automatically.
  302.  
  303. The Transmission Control Protocol (TCP)
  304.  
  305. A TCP connection is uniquely identified by the concatenation of local and
  306. remote "sockets". In turn, a socket consists of a host address (a 32-bit
  307. integer) and a TCP port (a 16-bit integer), defined by the C structure
  308.  
  309. struct socket {
  310.     long address;    /* 32-bit IP address */
  311.     short port;    /*16-bit TCP port */
  312. };
  313.  
  314. It is therefore possible to have several simultaneous but distinct connections
  315. to the same port on a given machine, as long as the remote sockets are
  316. distinct. Port numbers are assigned either through mutual agreement, or more
  317. commonly when a "standard" service is involved, as a "well known port" number.
  318. For example, to obtain standard remote login service using the TELNET
  319. presentation-layer protocol, by convention you initiate a connection to TCP
  320. port 23; to send mail using the Simple Mail Transfer Protocol (SMTP) you
  321. connect to port 25. ARPA maintains port number lists and periodically
  322. publishes them; the latest revision is RFC-960, "Assigned Numbers".
  323. They will also assign port numbers to a new application on request if it
  324. appears to be of general interest.
  325.  
  326. TCP connections are best modeled as a pair of one-way paths (one in each
  327. direction) rather than single full-duplex paths. A TCP "close" really
  328. means "I have no more data to send". Station A may close its path to station
  329. B leaving the reverse path from B to A unaffected; B may continue to send data
  330. to A indefinitely until it too closes its half of the connection.  Even after
  331. a user initiates a close, TCP continues to retransmit any unacknowledged
  332. data if necessary to ensure that it reaches the other end. This is known as
  333. "graceful close" and greatly simplifies certain applications such as FTP.
  334.  
  335. TCP Module Overview
  336.  
  337. This package is written as a "module" intended to be compiled and linked with
  338. the application(s) so that they can be run as one program on the same machine.
  339. This greatly simplifies the user/TCP interface, which becomes just a set of
  340. internal subroutine calls on a single machine. The internal TCP state (e.g.,
  341. the address of the remote station) is easily accessed. Reliability is
  342. improved, since any hardware failure that kills TCP will likely take its
  343. applications with it anyway. Only IP datagrams flow out of the machine across
  344. hardware interfaces (such as asynch RS-232 ports or whatever else is available)
  345. so hardware flow control or complicated host/front-end protocols are
  346. unnecessary.
  347.  
  348. The TCP supports five basic operations on a connection: open_tcp, send_tcp,
  349. receive_tcp, close_tcp and del_tcp. A sixth, state_tcp, is provided
  350. mainly for debugging. Since this TCP module cannot assume the presence of
  351. a sleep/wakeup facility from the underlying operating system, functions
  352. that would ordinarily block (e.g., recv_tcp when no data is available)
  353. instead set net_error to the constant EWOULDBLK and immediately return -1.
  354. Asynchronous notification of events such as data arrival can be obtained
  355. through the upcall facility described earlier.
  356.  
  357. Each TCP function is summarized in the following section in the form of C
  358. declarations and descriptions of each argument.
  359.  
  360. int net_error;
  361.  
  362. This global variable stores the specific cause of an error from one of the
  363. TCP or UDP functions. All functions returning integers (i.e., all except
  364. open_tcp) return -1 in the event of an error, and net_error should be
  365. examined to determine the cause. The possible errors are defined as constants
  366. in the header file netuser.h.
  367.  
  368. /* Open a TCP connection */
  369. struct tcb *
  370. open_tcp(lsocket,fsocket,mode,window,r_upcall,t_upcall,s_upcall,tos,user)
  371. struct socket *lsocket;    /* Local socket */
  372. struct socket *fsocket;    /* Remote socket */
  373. int mode;        /* Active/passive/server */
  374. int16 window;        /* Receive window (and send buffer) sizes */
  375. void (*r_upcall)();    /* Function to call when data arrives */
  376. void (*t_upcall)();    /* Function to call when ok to send more data */
  377. void (*s_upcall)();    /* Function to call when connection state changes */
  378. char tos;        /* Internet Type-of-Service */
  379. int *user;        /* Pointer for convenience of user */
  380.  
  381. "lsocket" and "fsocket" are pointers to the local and foreign sockets,
  382. respectively.
  383.  
  384. "mode" may take on three values, all defined in net.user.h. If mode is
  385. TCP_PASSIVE, no packets are sent, but a TCP control block is created that will
  386. accept a subsequent active open from another TCP. If a specific foreign socket
  387. is passed to a passive open, then connect requests from any other foreign socket
  388. will be rejected. If the foreign socket fields are set to zero, or if fsocket
  389. is NULLSOCK, then connect requests from any foreign socket will be accepted.
  390. If mode is TCP_ACTIVE, TCP will initiate a connection to a remote socket that
  391. must already have been created in the LISTEN state by its client. The foreign
  392. socket must be completely specified in an active open.  When mode is TCP_SERVER,
  393. open_tcp behaves as though TCP_PASSIVE was given except that an internal "clone"
  394. flag is set. When a connection request comes in, a fresh copy of the TCP control
  395. block is created and the original is left intact. This allows multiple
  396. sessions to exist simultaneously; if TCP_PASSIVE were used instead only the
  397. first connect request would be accepted.
  398.  
  399. "r_upcall", "t_upcall" and "s_upcall" provide optional upcall or pseudo-
  400. interrupt mechanisms useful when running in a non operating system environment.
  401. Each of the three arguments, if non-NULL, is taken as the address of a
  402. user-supplied function to call when receive data arrives, transmit queue space
  403. becomes available, or the connection state changes. The three functions are
  404. called with the following arguments:
  405.  
  406. (*r_upcall)(tcb,count);    /* count == number of bytes in receive queue */
  407. (*t_upcall)(tcb,avail);    /* avail == space available in send queue */
  408. (*s_upcall)(tcb,oldstate,newstate);
  409.  
  410. Note: whenever a single event invokes more than one upcall the order in
  411. which the upcalls are made is not strictly defined. In general, though,
  412. the Principle of Least Astonishment is followed.  E.g., when entering the
  413. ESTABLISHED state, the state change upcall is invoked first, followed by
  414. the transmit upcall. When an incoming segment contains both data and FIN,
  415. the receive upcall is invoked first, followed by the state change to
  416. CLOSE_WAIT state.  In this case, the user may interpret this state change
  417. as a "end of file" indicator.
  418.  
  419. "tos" is the Internet type-of-service field. This parameter is passed along
  420. to IP and is included in every datagram. The actual precedence value used is
  421. the higher of the two specified in the corresponding pair of open_tcp calls.
  422.  
  423. open_tcp returns a pointer to an internal Transmission Control Block
  424. (tcb). This "magic cookie" must be passed back as the first argument
  425. to all other TCP calls. In event of error, the NULL pointer (0) is
  426. returned and net_error is set to the reason for the error.
  427.  
  428. The only limit on the number of TCBs that may exist at any time (i.e., the
  429. number of simultaneous connections) is the amount of free memory on the
  430. machine. Each TCB on a 16-bit processor currently takes up 111 bytes;
  431. additional memory is consumed and freed dynamically as needed to buffer send
  432. and receive data. Deleting a TCB (see the del_tcp() call) reclaims its space.
  433.  
  434. /* Send data on a TCP connection */
  435. int
  436. send_tcp(tcb,bp)
  437. struct tcb *tcb;    /* TCB pointer */
  438. struct mbuf *bp;    /* Pointer to user's data mbufs */
  439.  
  440. "tcb" is the pointer returned by the open_tcp() call. "bp" points to the
  441. user's mbuf with data to be sent. After being passed to send_tcp, the user
  442. must no longer access the data buffer. TCP uses positive acknowledgments with
  443. retransmission to ensure in-order delivery, but this is largely invisible to
  444. the user. Once the remote TCP has acknowledged the data, the buffer will
  445. be freed automatically.
  446.  
  447. TCP does not enforce a limit in the number of bytes that may be queued
  448. for transmission, but it is recommended that the application not send any
  449. more than the amount passed as "cnt" in the transmitter upcall.  The package
  450. uses shared, dynamically allocated buffers, and it is entirely possible
  451. for a misbehaving user task to run the system out of buffers.
  452.  
  453. /* Receive data on a TCP connection */
  454. int
  455. recv_tcp(tcb,bp,cnt)
  456. struct tcb *tcb;
  457. struct mbuf **bp;
  458. int16 cnt;
  459.  
  460. recv_tcp() passes back through bp a pointer to an mbuf chain containing any
  461. available receive data, up to a maximum of "cnt" bytes. The actual number of
  462. bytes received (the lesser of "cnt" and the number pending on the receive
  463. queue) is returned. If no data is available, net_error is set to EWOULDBLK
  464. and -1 is returned; the r_upcall mechanism may be used to determine when data
  465. arrives. (Technical note: "r_upcall" is called whenever a PUSH or FIN bit is
  466. seen in an incoming segment, or if the receive window fills. It is called
  467. before an ACK is sent back to the remote TCP, in order to give the user an
  468. opportunity to piggyback any data in response.)
  469.  
  470. When the remote TCP closes its half of the connection and all prior incoming
  471. data has been read by the local user, subsequent calls to recv_tcp return 0
  472. rather than -1 as an "end of transmission" indicator. Note that the local
  473. application is notified of a remote close (i.e., end-of-file) by a state-change
  474. upcall with the new state being CLOSE_WAIT; if the local application
  475. has closed first, a remote close is indicated by a state-change upcall to
  476. either CLOSING or TIME_WAIT state. (CLOSING state is used only when the
  477. two ends close simultaneously and their FINs cross in the mail).
  478.  
  479. /* Close a TCP connection */
  480. close_tcp(tcb)
  481. struct tcb *tcb;
  482.  
  483. This tells TCP that the local user has no more data to send. However, the
  484. remote TCP may continue to send data indefinitely to the local user, until
  485. the remote user also does a close_tcp.  An attempt to send data after a
  486. close_tcp is an error.
  487.  
  488. /* Delete a TCP connection */
  489. del_tcp(tcb)
  490. struct tcb *tcb;
  491.  
  492. When the connection has been closed in both connections and all incoming
  493. data has been read, this call is made to cause TCP to reclaim the space
  494. taken up by the TCP control block. Any incoming data remaining unread is lost.
  495.  
  496. /* Dump a TCP connection state */
  497. state_tcp(tcb)
  498. struct tcb *tcb;
  499.  
  500. This debugging call prints an ASCII-formatted dump of the TCP connection
  501. state on the terminal. You need a copy of the TCP specification (ARPA RFC
  502. 793 or MIL-STD-1778) to interpret most of the numbers.
  503.  
  504. The User Datagram Protocol (UDP)
  505.  
  506. UDP is available for simple applications not needing the services of a
  507. reliable protocol like TCP.  A minimum of overhead is placed on top of the
  508. "raw" IP datagram service, consisting only of port numbers and a checksum
  509. covering the UDP header and user data. Four functions are available to the
  510. UDP user.
  511.  
  512. /* Create a UDP control block for lsocket, so that we can queue
  513.  * incoming datagrams.
  514.  */
  515. int
  516. open_udp(lsocket,r_upcall)
  517. struct socket *lsocket;
  518. void (*r_upcall)();
  519.  
  520. open_udp creates a queue to accept incoming datagrams (regardless of
  521. source) addressed to "lsocket". "r_upcall" is an optional upcall mechanism
  522. to provide the address of a function to be called as follows whenever
  523. a datagram arrives:
  524.  
  525. (*r_upcall)(lsocket,rcvcnt);
  526. struct socket *lsocket;        /* Pointer to local socket */
  527. int rcvcnt;            /* Count of datagrams pending on queue */
  528.  
  529. /* Send a UDP datagram */
  530. int
  531. send_udp(lsocket,fsocket,tos,ttl,bp,length,id,df)
  532. struct socket *lsocket;        /* Source socket */
  533. struct socket *fsocket;        /* Destination socket */
  534. char tos;            /* Type-of-service for IP */
  535. char ttl;            /* Time-to-live for IP */
  536. struct mbuf *bp;        /* Data field, if any */
  537. int16 length;            /* Length of data field */
  538. int16 id;            /* Optional ID field for IP */
  539. char df;            /* Don't Fragment flag for IP */
  540.  
  541. The parameters passed to send_udp are simply stuffed in the UDP and IP
  542. headers, and the datagram is sent on its way.
  543.  
  544. /* Accept a waiting datagram, if available. Returns length of datagram */
  545. int
  546. recv_udp(lsocket,fsocket,bp)
  547. struct socket *lsocket;        /* Local socket to receive on */
  548. struct socket *fsocket;        /* Place to stash incoming socket */
  549. struct mbuf **bp;        /* Place to stash data packet */
  550.  
  551. The "lsocket" pointer indicates the socket the user wishes to receive a
  552. datagram on (a queue must have been created previously with the open_udp
  553. routine). "fsocket" is taken as the address of a socket structure to be
  554. overwritten with the foreign socket associated with the datagram being
  555. read; bp is overwritten with a pointer to the data portion (if any)
  556. of the datagram being received.
  557.  
  558. /* Delete a UDP control block */
  559. int
  560. del_udp(lsocket)
  561. struct socket *lsocket;
  562.  
  563. This function destroys any unread datagrams on a queue, and reclaims the
  564. space taken by the queue descriptor.
  565.  
  566. Phil Karn, KA9Q
  567. 10 Sep 1987
  568.