home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 483.TECHREF.DOC < prev    next >
Text File  |  1987-06-12  |  26KB  |  533 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 (*send)();        /* Routine to call to send datagram */
  150.     int (*output)();    /* Routine to call to send raw packet */
  151.     int (*recv)();        /* Routine to kick to process input */
  152.     int (*stop)();        /* Routine to call before detaching */
  153.     int16 dev;        /* Subdevice number to pass to send */
  154.     int16 flags;        /* State of interface */
  155. #define    IF_ACTIVE    0x01
  156. #define    IF_BROADCAST    0x04    /* Interface is capable of broadcasting */
  157. };
  158.  
  159. Part of the interface structure is for the private use of the device driver.
  160. "dev" is used to distinguish between one of several identical devices (e.g.,
  161. serial links or radio channels) that might share the same send routine.
  162.  
  163. A pointer to this structure kept in the routing table. Two fields in the
  164. interface structure are examined by ip_route: "mtu" and "send". The maximum
  165. transmission unit size represents the largest datagram that this device can
  166. handle; ip_route will do IP-level fragmentation as required to meet this
  167. limit before calling "send", the function to queue datagrams on this
  168. interface. "send" is called as follows:
  169.  
  170. (*send)(bp,interface,gateway,precedence,delay,throughput,reliability)
  171. struct mbuf *bp;        /* Pointer to datagram */
  172. struct interface *interface;    /* Interface structure */
  173. int32 gateway;            /* IP address of gateway */
  174. char precedence;        /* TOS bits from IP header */
  175. char delay;
  176. char throughput;
  177. char reliability;
  178.  
  179. The "interface" and "gateway" arguments are kept in the routing table and
  180. passed on each call to the send routine. The interface pointer is passed
  181. again because several interfaces might share the same output driver (e.g.,
  182. several identical physical channels).  "gateway" is the IP address of the
  183. neighboring IP gateway on the other end of the link; if a link-level address
  184. is required, the send routine must map this address either dynamically (e.g.,
  185. with the Address Resolution Protocol, ARP) or with a static lookup table.
  186. If the link is point-to-point, link-level addresses are unnecessary, and the
  187. send routine can therefore ignore the gateway address.
  188.  
  189. The Internet Type-of-Service (TOS) bits are passed to the interface driver
  190. as separate arguments. If tradeoffs exist within the subnet between these
  191. various classes of service, the driver may use these arguments to control
  192. them (e.g., optional use of link level acknowledgments, priority queuing,
  193. etc.)
  194.  
  195. It is expected that the send routine will put a link level header on the front
  196. of the packet, add it an internal output queue, start output (if not already
  197. active) and return. It must NOT busy-wait for completion (unless it is a very
  198. fast device, e.g., Ethernet) since that blocks the entire system.
  199.  
  200. Any interface that uses ARP must also provide an "output" routine. It is a
  201. lower level entry point that allows the caller to specify the fields in the
  202. link header. ARP uses it to broadcast a request for a given IP address. It may
  203. be the same routine used internally by the driver to send IP datagrams
  204. once the link level fields have been determined. It is called as follows:
  205.  
  206. (*output)(interface,dest,src,type,bp)
  207. struct interface *interface;    /* Pointer to interface structure */
  208. char dest[];            /* Link level destination address */
  209. char src[];            /* Link level source address */
  210. int16 type;            /* Protocol type field for link level */
  211. struct mbuf *bp;        /* Data field (IP datagram) */
  212.  
  213. IP Host Support
  214.  
  215. All of the modules described thus far are required in all systems. However,
  216. the routines that follow are necessary only if the system is to support
  217. higher-level applications. In a standalone IP gateway (packet switch)
  218. without servers or clients, the following modules (IP user level, TCP and
  219. UDP) may be omitted to allow additional space for buffering; define the
  220. flag GWONLY when compiling iproute.c to avoid referencing the user level
  221. half of IP.
  222.  
  223. The following function is called by iproute() whenever a datagram arrives
  224. that is addressed to the local system.  
  225.  
  226. void
  227. ip_recv(bp,rxbroadcast)
  228. struct mbuf *bp;        /* Datagram */
  229. char rxbroadcast;        /* Incoming broadcast */
  230.  
  231. ip_recv reassembles IP datagram fragments, if necessary, and calls the input
  232. function of the next layer protocol (e.g., tcp_input, udp_input) with the
  233. appropriate arguments, as follows:
  234.  
  235. (*protrecv)(bp,protocol,source,dest,tos,length,rxbroadcast);
  236. struct mbuf *bp;    /* Pointer to packet minus IP header */
  237. char protocol;        /* IP protocol ID */
  238. int32 source;        /* IP address of sender */
  239. int32 dest;        /* IP address of destination (i.e,. us) */
  240. char tos;        /* IP type-of-service field in datagram */
  241. int16 length;        /* Length of datagram minus IP header */
  242. char rxbroadcast;    /* Incoming broadcast */
  243.  
  244. The list of protocols is contained in a switch() statement in the ip_recv
  245. function. If the protocol is unsupported, an ICMP Protocol Unreachable
  246. message is returned to the sender unless the packet came in as a broadcast.
  247.  
  248. Higher level protocols such as TCP and UDP use the ip_send routine to generate
  249. IP datagrams. The arguments to ip_send correspond directly to fields in the IP
  250. header, which is generated and put in front of the user's data before being
  251. handed to ip_route:
  252.  
  253. ip_send(source,dest,protocol,tos,ttl,bp,length,id,df)
  254. int32 source;        /* source address */
  255. int32 dest;        /* Destination address */
  256. char protocol;        /* Protocol */
  257. char tos;        /* Type of service */
  258. char ttl;        /* Time-to-live */
  259. struct mbuf *bp;    /* Data portion of datagram */
  260. int16 length;        /* Optional length of data portion */
  261. int16 id;        /* Optional identification */
  262. char df;        /* Don't-fragment flag */
  263.  
  264. This interface is modeled very closely after the example given on page 32
  265. of RFC-791. Zeros may be passed for id or ttl, and system defaults will
  266. be provided. If zero is passed for length, it will be calculated automatically.
  267.  
  268. The Transmission Control Protocol (TCP)
  269.  
  270. A TCP connection is uniquely identified by the concatenation of local and
  271. remote "sockets". In turn, a socket consists of a host address (a 32-bit
  272. integer) and a TCP port (a 16-bit integer), defined by the C structure
  273.  
  274. struct socket {
  275.     long address;    /* 32-bit IP address */
  276.     short port;    /*16-bit TCP port */
  277. };
  278.  
  279. It is therefore possible to have several simultaneous but distinct connections
  280. to the same port on a given machine, as long as the remote sockets are
  281. distinct. Port numbers are assigned either through mutual agreement, or more
  282. commonly when a "standard" service is involved, as a "well known port" number.
  283. For example, to obtain standard remote login service using the TELNET
  284. presentation-layer protocol, by convention you initiate a connection to TCP
  285. port 23; to send mail using the Simple Mail Transfer Protocol (SMTP) you
  286. connect to port 25. ARPA maintains port number lists and periodically
  287. publishes them; the latest revision is RFC-960, "Assigned Numbers".
  288. They will also assign port numbers to a new application on request if it
  289. appears to be of general interest.
  290.  
  291. TCP connections are best modeled as a pair of one-way paths (one in each
  292. direction) rather than single full-duplex paths. A TCP "close" really
  293. means "I have no more data to send". Station A may close its path to station
  294. B leaving the reverse path from B to A unaffected; B may continue to send data
  295. to A indefinitely until it too closes its half of the connection.  Even after
  296. a user initiates a close, TCP continues to retransmit any unacknowledged
  297. data if necessary to ensure that it reaches the other end. This is known as
  298. "graceful close" and greatly simplifies certain applications such as FTP.
  299.  
  300. TCP Module Overview
  301.  
  302. This package is written as a "module" intended to be compiled and linked with
  303. the application(s) so that they can be run as one program on the same machine.
  304. This greatly simplifies the user/TCP interface, which becomes just a set of
  305. internal subroutine calls on a single machine. The internal TCP state (e.g.,
  306. the address of the remote station) is easily accessed. Reliability is
  307. improved, since any hardware failure that kills TCP will likely take its
  308. applications with it anyway. Only IP datagrams flow out of the machine across
  309. hardware interfaces (such as asynch RS-232 ports or whatever else is available)
  310. so hardware flow control or complicated host/front-end protocols are
  311. unnecessary.
  312.  
  313. The TCP supports five basic operations on a connection: open_tcp, send_tcp,
  314. receive_tcp, close_tcp and del_tcp. A sixth, state_tcp, is provided
  315. mainly for debugging. Since this TCP module cannot assume the presence of
  316. a sleep/wakeup facility from the underlying operating system, functions
  317. that would ordinarily block (e.g., recv_tcp when no data is available)
  318. instead set net_error to the constant EWOULDBLK and immediately return -1.
  319. Asynchronous notification of events such as data arrival can be obtained
  320. through the upcall facility described earlier.
  321.  
  322. Each TCP function is summarized in the following section in the form of C
  323. declarations and descriptions of each argument.
  324.  
  325. int net_error;
  326.  
  327. This global variable stores the specific cause of an error from one of the
  328. TCP or UDP functions. All functions returning integers (i.e., all except
  329. open_tcp) return -1 in the event of an error, and net_error should be
  330. examined to determine the cause. The possible errors are defined as constants
  331. in the header file netuser.h.
  332.  
  333. /* Open a TCP connection */
  334. struct tcb *
  335. open_tcp(lsocket,fsocket,mode,window,r_upcall,t_upcall,s_upcall,tos,user)
  336. struct socket *lsocket;    /* Local socket */
  337. struct socket *fsocket;    /* Remote socket */
  338. int mode;        /* Active/passive/server */
  339. int16 window;        /* Receive window (and send buffer) sizes */
  340. void (*r_upcall)();    /* Function to call when data arrives */
  341. void (*t_upcall)();    /* Function to call when ok to send more data */
  342. void (*s_upcall)();    /* Function to call when connection state changes */
  343. char tos;        /* Internet Type-of-Service */
  344. int *user;        /* Pointer for convenience of user */
  345.  
  346. "lsocket" and "fsocket" are pointers to the local and foreign sockets,
  347. respectively.
  348.  
  349. "mode" may take on three values, all defined in net.user.h. If mode is
  350. TCP_PASSIVE, no packets are sent, but a TCP control block is created that will
  351. accept a subsequent active open from another TCP. If a specific foreign socket
  352. is passed to a passive open, then connect requests from any other foreign socket
  353. will be rejected. If the foreign socket fields are set to zero, or if fsocket
  354. is NULLSOCK, then connect requests from any foreign socket will be accepted.
  355. If mode is TCP_ACTIVE, TCP will initiate a connection to a remote socket that
  356. must already have been created in the LISTEN state by its client. The foreign
  357. socket must be completely specified in an active open.  When mode is TCP_SERVER,
  358. open_tcp behaves as though TCP_PASSIVE was given except that an internal "clone"
  359. flag is set. When a connection request comes in, a fresh copy of the TCP control
  360. block is created and the original is left intact. This allows multiple
  361. sessions to exist simultaneously; if TCP_PASSIVE were used instead only the
  362. first connect request would be accepted.
  363.  
  364. "r_upcall", "t_upcall" and "s_upcall" provide optional upcall or pseudo-
  365. interrupt mechanisms useful when running in a non operating system environment.
  366. Each of the three arguments, if non-NULL, is taken as the address of a
  367. user-supplied function to call when receive data arrives, transmit queue space
  368. becomes available, or the connection state changes. The three functions are
  369. called with the following arguments:
  370.  
  371. (*r_upcall)(tcb,count);    /* count == number of bytes in receive queue */
  372. (*t_upcall)(tcb,avail);    /* avail == space available in send queue */
  373. (*s_upcall)(tcb,oldstate,newstate);
  374.  
  375. Note: whenever a single event invokes more than one upcall the order in
  376. which the upcalls are made is not strictly defined. In general, though,
  377. the Principle of Least Astonishment is followed.  E.g., when entering the
  378. ESTABLISHED state, the state change upcall is invoked first, followed by
  379. the transmit upcall. When an incoming segment contains both data and FIN,
  380. the receive upcall is invoked first, followed by the state change to
  381. CLOSE_WAIT state.  In this case, the user may interpret this state change
  382. as a "end of file" indicator.
  383.  
  384. "tos" is the Internet type-of-service field. This parameter is passed along
  385. to IP and is included in every datagram. The actual precedence value used is
  386. the higher of the two specified in the corresponding pair of open_tcp calls.
  387.  
  388. open_tcp returns a pointer to an internal Transmission Control Block
  389. (tcb). This "magic cookie" must be passed back as the first argument
  390. to all other TCP calls. In event of error, the NULL pointer (0) is
  391. returned and net_error is set to the reason for the error.
  392.  
  393. The only limit on the number of TCBs that may exist at any time (i.e., the
  394. number of simultaneous connections) is the amount of free memory on the
  395. machine. Each TCB on a 16-bit processor currently takes up 111 bytes;
  396. additional memory is consumed and freed dynamically as needed to buffer send
  397. and receive data. Deleting a TCB (see the del_tcp() call) reclaims its space.
  398.  
  399. /* Send data on a TCP connection */
  400. int
  401. send_tcp(tcb,bp)
  402. struct tcb *tcb;    /* TCB pointer */
  403. struct mbuf *bp;    /* Pointer to user's data mbufs */
  404.  
  405. "tcb" is the pointer returned by the open_tcp() call. "bp" points to the
  406. user's mbuf with data to be sent. After being passed to send_tcp, the user
  407. must no longer access the data buffer. TCP uses positive acknowledgments with
  408. retransmission to ensure in-order delivery, but this is largely invisible to
  409. the user. Once the remote TCP has acknowledged the data, the buffer will
  410. be freed automatically.
  411.  
  412. TCP does not enforce a limit in the number of bytes that may be queued
  413. for transmission, but it is recommended that the application not send any
  414. more than the amount passed as "cnt" in the transmitter upcall.  The package
  415. uses shared, dynamically allocated buffers, and it is entirely possible
  416. for a misbehaving user task to run the system out of buffers.
  417.  
  418. /* Receive data on a TCP connection */
  419. int
  420. recv_tcp(tcb,bp,cnt)
  421. struct tcb *tcb;
  422. struct mbuf **bp;
  423. int16 cnt;
  424.  
  425. recv_tcp() passes back through bp a pointer to an mbuf chain containing any
  426. available receive data, up to a maximum of "cnt" bytes. The actual number of
  427. bytes received (the lesser of "cnt" and the number pending on the receive
  428. queue) is returned. If no data is available, net_error is set to EWOULDBLK
  429. and -1 is returned; the r_upcall mechanism may be used to determine when data
  430. arrives. (Technical note: "r_upcall" is called whenever a PUSH or FIN bit is
  431. seen in an incoming segment, or if the receive window fills. It is called
  432. before an ACK is sent back to the remote TCP, in order to give the user an
  433. opportunity to piggyback any data in response.)
  434.  
  435. When the remote TCP closes its half of the connection and all prior incoming
  436. data has been read by the local user, subsequent calls to recv_tcp return 0
  437. rather than -1 as an "end of transmission" indicator. Note that the local
  438. application is notified of a remote close (i.e., end-of-file) by a state-change
  439. upcall with the new state being CLOSE_WAIT; if the local application
  440. has closed first, a remote close is indicated by a state-change upcall to
  441. either CLOSING or TIME_WAIT state. (CLOSING state is used only when the
  442. two ends close simultaneously and their FINs cross in the mail).
  443.  
  444. /* Close a TCP connection */
  445. close_tcp(tcb)
  446. struct tcb *tcb;
  447.  
  448. This tells TCP that the local user has no more data to send. However, the
  449. remote TCP may continue to send data indefinitely to the local user, until
  450. the remote user also does a close_tcp.  An attempt to send data after a
  451. close_tcp is an error.
  452.  
  453. /* Delete a TCP connection */
  454. del_tcp(tcb)
  455. struct tcb *tcb;
  456.  
  457. When the connection has been closed in both connections and all incoming
  458. data has been read, this call is made to cause TCP to reclaim the space
  459. taken up by the TCP control block. Any incoming data remaining unread is lost.
  460.  
  461. /* Dump a TCP connection state */
  462. state_tcp(tcb)
  463. struct tcb *tcb;
  464.  
  465. This debugging call prints an ASCII-formatted dump of the TCP connection
  466. state on the terminal. You need a copy of the TCP specification (ARPA RFC
  467. 793 or MIL-STD-1778) to interpret most of the numbers.
  468.  
  469. The User Datagram Protocol (UDP)
  470.  
  471. UDP is available for simple applications not needing the services of a
  472. reliable protocol like TCP.  A minimum of overhead is placed on top of the
  473. "raw" IP datagram service, consisting only of port numbers and a checksum
  474. covering the UDP header and user data. Four functions are available to the
  475. UDP user.
  476.  
  477. /* Create a UDP control block for lsocket, so that we can queue
  478.  * incoming datagrams.
  479.  */
  480. int
  481. open_udp(lsocket,r_upcall)
  482. struct socket *lsocket;
  483. void (*r_upcall)();
  484.  
  485. open_udp creates a queue to accept incoming datagrams (regardless of
  486. source) addressed to "lsocket". "r_upcall" is an optional upcall mechanism
  487. to provide the address of a function to be called as follows whenever
  488. a datagram arrives:
  489.  
  490. (*r_upcall)(lsocket,rcvcnt);
  491. struct socket *lsocket;        /* Pointer to local socket */
  492. int rcvcnt;            /* Count of datagrams pending on queue */
  493.  
  494. /* Send a UDP datagram */
  495. int
  496. send_udp(lsocket,fsocket,tos,ttl,bp,length,id,df)
  497. struct socket *lsocket;        /* Source socket */
  498. struct socket *fsocket;        /* Destination socket */
  499. char tos;            /* Type-of-service for IP */
  500. char ttl;            /* Time-to-live for IP */
  501. struct mbuf *bp;        /* Data field, if any */
  502. int16 length;            /* Length of data field */
  503. int16 id;            /* Optional ID field for IP */
  504. char df;            /* Don't Fragment flag for IP */
  505.  
  506. The parameters passed to send_udp are simply stuffed in the UDP and IP
  507. headers, and the datagram is sent on its way.
  508.  
  509. /* Accept a waiting datagram, if available. Returns length of datagram */
  510. int
  511. recv_udp(lsocket,fsocket,bp)
  512. struct socket *lsocket;        /* Local socket to receive on */
  513. struct socket *fsocket;        /* Place to stash incoming socket */
  514. struct mbuf **bp;        /* Place to stash data packet */
  515.  
  516. The "lsocket" pointer indicates the socket the user wishes to receive a
  517. datagram on (a queue must have been created previously with the open_udp
  518. routine). "fsocket" is taken as the address of a socket structure to be
  519. overwritten with the foreign socket associated with the datagram being
  520. read; bp is overwritten with a pointer to the data portion (if any)
  521. of the datagram being received.
  522.  
  523. /* Delete a UDP control block */
  524. int
  525. del_udp(lsocket)
  526. struct socket *lsocket;
  527.  
  528. This function destroys any unread datagrams on a queue, and reclaims the
  529. space taken by the queue descriptor.
  530.  
  531. Phil Karn, KA9Q
  532. 12 June 1987
  533.