home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / iso9660 / ip / manage / nnstat / userdoc.ms < prev    next >
Encoding:
Text File  |  1989-03-20  |  74.7 KB  |  2,667 lines

  1. .ND
  2. .de B1
  3. .cm define away boxes
  4. ..
  5. .de B2
  6. .cm define away boxes
  7. ..
  8. .cm .nr PS 11
  9. .pl 10i
  10. .nr LL 6.3i
  11. .nr LT 6.3i
  12. .nr PO .8i
  13. .ds LH NNStat--Internet Statistics Package 
  14. .ds CH 
  15. .ds RH Braden & DeSchon
  16. .ds CF Page %
  17. .LP
  18. .nh
  19.  
  20.  
  21.  
  22. .ce 10
  23. .LG
  24. .LG
  25. NNStat:
  26.  
  27. Internet Statistics Collection Package
  28.  
  29. -- Introduction and User Guide *
  30.  
  31.  
  32.  
  33. .NL
  34. Robert T. Braden
  35. Annette L. DeSchon
  36.  
  37. USC / Information Sciences Institute
  38. Marina del Rey, California
  39.  
  40. November 28, 1988
  41.  
  42.  
  43.  
  44. .in +0.4i
  45. .nr LL 5.9i
  46. .ll 5.9i
  47. .SM
  48. .ce 
  49. .mc |
  50. RELEASE 2.2
  51. .ce 0
  52.  
  53. This document describes the installation and operation of Release 2.2 of
  54. NNStat, a package of programs for the distributed collection of Internet
  55. traffic statistics.
  56.  
  57. Release 2.2 differs from 2.1 in the following important ways:
  58. .IP *
  59. Adds new filter object eqf (EQ), equivalent to setf with one element but much
  60. more efficient.
  61. .IP *
  62. Supports either the SunOS 4.0 NIT interface (with appropriate bug fixes)
  63. or the original SunOS 3.x NIT interface.
  64. .IP *
  65. When the same object is attached with a new list of parameters, verifies that
  66. the new parameters are identical to the original set.  In Release 2.1, the
  67. user could accidentally reuse the same object name with a different
  68. set of parameters; the original object would be used and the later parameters
  69. ignored, without any diagnostic message.
  70. .IP *
  71. Contains a number of internal efficiency improvements and some minor
  72. cleanups.
  73. .IP *
  74. Fixes a serious bug in the distributed Release 2.1, that caused 
  75. matrix-sym objects to perform incorrectly.
  76. .IP *
  77. Fixes a bug in the display of percentages for working-set objects.
  78. .IP *
  79. Fixes a bug that allowed excessively long enumeration labels to
  80. clobber the stack.
  81. .LP
  82. .mc
  83.  
  84. .FS *
  85. This work was supported by the National Science Foundation
  86. under Contract NCR-8718217.
  87. .FE
  88.  
  89.  
  90. .LP
  91. .nr LL 6.3i
  92. .ll 6.3i
  93. .in 0
  94. .bp
  95.  
  96.  
  97. .NH
  98. Introduction
  99. .LP
  100. NNStat is a set of programs that comprise a facility for the
  101. distributed collection of Internet traffic statistics. This facility
  102. is designed to support the requirements of a network administrator for
  103. gathering long-term usage statistics simultaneously
  104. at many network entry points.
  105. Although it is primarily intended for collecting
  106. long-term traffic statistics for administration,
  107. management, and topology engineering, NNStat is sufficiently
  108. general to be useful for operational problem solving.
  109.  
  110. Distributed statistics collection has two aspects: acquisition of the
  111. primary data at multiple locations, and collection of all the acquired
  112. data into a single location.
  113.  
  114. .IP (1)
  115. Distributed Data Acquisition
  116.  
  117. The raw data must be acquired at a number of network/Internet points
  118. simultanously.  
  119. In the NNStat model, there will be a
  120. .I 
  121. statistics acquisition agent
  122. .R
  123. (SAA) process
  124. executing in a computer system 
  125. attached to each network/Internet node for which data is required.
  126. The SAA machines could be packet switches, gateways,
  127. general-purpose hosts, or hosts dedicated to the
  128. acquisition function.
  129.  
  130. .IP (2)
  131. Centralized Data Collection
  132.  
  133. Data (or summaries of data)
  134. acquired by the SAA processes must
  135. be transmitted to a central site for analysis, reporting, and
  136. long-term storage.  This central site, the 
  137. .I
  138. statistics collection host
  139. .R
  140. (SCH), will run a data collection
  141. program to gather the data from the SAA processes.
  142. In many cases, a single locus for data collection is sufficient;
  143. however, it should be possible to have multiple SCH's simultaneously
  144. gathering data from the same set of acquisition agents.
  145. We may think of a primary SCH that serves as a
  146. central repository for usage data by a particular administration,
  147. with perhaps secondary collection hosts being used intermittently
  148. for short-term statistical studies.
  149. .LP
  150.  
  151. The principal components of the NNStat package are an SAA program
  152. and an SCH program.  The NNStat design
  153. is based upon the common use of Ethernets for interconnection of
  154. networks and Internet regions.  NSFnet provides an example:
  155.  
  156. .IP o
  157. Each component of NSFnet above the campus level (i.e.,
  158. the NSFnet Backbone and each of the middle-level networks)
  159. consists of a set of IP gateways connected by serial lines.
  160.  
  161. .IP o
  162. Each gateway is also connected to an Ethernet that is used as the
  163. interconnect medium to one or more lower-level networks.
  164. We refer to this as an \fIinterconnect Ethernet\fP.
  165. .LP
  166.  
  167. Figure 1 shows a typical configuration at one of the network nodes.
  168. The gateway G is a packet switch that forms part of the network
  169. under consideration.  G1 and G2 are entrance gateways to the same
  170. or different lower-level networks.
  171.  
  172. .cs R 18 
  173. .ss 18
  174. .nf
  175. .in +0.8i
  176.  
  177. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Lower-level Network(s)
  178. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ |
  179. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ |
  180. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ G1\ \ \ \ \ \ \ G2
  181. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ |
  182. \ \ \ \ \ \ \ \ \ Interconnect\ |\ \ \ Ether|net
  183. \ \ \ \ \ \ \ \ |======.======.========.========.====|
  184. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |
  185. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ __|__
  186. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ G\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | SAA |
  187. \ \ \ \ \ \ \ \ \ \ \ \ \ \ /\ \\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ |_____|
  188. \ \ \ \ \ \ \ \ \ \ \ \ \ /\ \ \ \\
  189. \ \ \ \ \ \ \ \ \ \ \ \ /\ \ \ \ \ \\
  190. \ \ \ \ \ \ \ Serial lines to other
  191. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ network nodes
  192.  
  193.  
  194.      Figure 1.  Typical Network Node Configuration
  195.  
  196.  
  197. .cs R
  198. .fi
  199. .in 0
  200.  
  201. Interconnect Ethernets provide convenient and appropriate
  202. points for gathering NSFnet statistics.  They are convenient because 
  203. an SAA executing on a host connected to one to these Ethernets 
  204. can monitor the traffic in promiscous mode (see Figure 1). 
  205. Thus, we can monitor the entrance and exit traffic
  206. without changing any gateway code.
  207. The interconnect
  208. Ethernets are also appropriate
  209. points for administrative statistics-gathering.  
  210. Administrators and traffic planners are concerned mainly with 
  211. packets entering and leaving the network; the fact that traffic
  212. between individual network routers cannot be monitored from the
  213. Ethernets is not a serious drawback. 
  214.  
  215. Implementing NNStat in an SAA host rather than in a
  216. gateway or packet switch had a number of advantages.
  217.  
  218. .IP (1)
  219. Timeliness: 
  220. The facilities provided by NNStat were needed quickly for NSFnet
  221. management.   
  222. It will be some time before equivalent traffic measurement
  223. standards are developed and implemented by gateway vendors.
  224.  
  225. .IP (2)
  226. Generality:
  227. We wanted to incorporate a degree of
  228. flexibility and generality into NNStat that is not currently available
  229. in gateways.
  230.  
  231. .IP (3)
  232. Performance:
  233. Comprehensive statistics gathering require a non-trivial amount of
  234. CPU time and memory space; it is very undesirable to burden the current
  235. generation of gateways with this additional resource drain.
  236.  
  237. .IP (4)
  238. Experimentation:
  239. By implementing this function outside gateways, we are free to experiment
  240. with different approaches; eventual incorporation of our results into
  241. gateways is a reasonable goal.
  242.  
  243. .IP (5)
  244. Universality:
  245. There may not be a gateway at the point to be monitored; for example,
  246. there might be a link-level bridge.
  247. .LP
  248.  
  249. The primary task of the SAA is to count the
  250. occurrences of packets with \*Qinteresting\*U configurations of values in
  251. their header fields.  In the NNStat design, what is \*Qinteresting\*U is
  252. determined by the SAA configurations, which
  253. can be set or changed dynamically.
  254.  
  255. Our model of NNStat operation within a particular network is
  256. as follows.  The administration will set up the acquisition agents,
  257. one at each point from which data is desired, configured to collect a basic
  258. set of statistics.  These statistics will be reported to the SCH to be
  259. summarized over sites, time, and perhaps administrative subsets of
  260. the networks.  
  261. In addition, management and operational personnel will dynamically
  262. modify the SAA configurations from time to time, to answer 
  263. additional statistical questions about the traffic. 
  264. .LP 
  265.  
  266. Finally, we should mention some non-goals for the NNStat effort.
  267.  
  268. .IP o
  269. NNStat does not provide fancy display or analysis programs
  270. for presenting the statistics.  This is potentially a large and
  271. complex problem that is outside the scope of the NNStat effort.
  272.  
  273. .IP o
  274. NNStat cannot gather statistics for traffic on the serial lines between
  275. IP routers; it can measure only the network entry and exit traffic.
  276. NNStat is intended to complement, not replace, the statistics gathering
  277. facilities built into gateways.  For example, gateways typically count
  278. line errors and dropped packets on each of their physical interfaces, to
  279. monitor and diagnose line problems.  These facilities are vital for
  280. operation and maintenance of the gateways and lines, forming the
  281. \*Qfirst line of defense\*U for problem diagnosis.  However, NNStat is
  282. not generally concerned with short-term operational functions. 
  283. .LP
  284.  
  285. .NH 
  286. Overview of NNStat
  287. .LP
  288.  
  289. The NNStat package, which has been implemented for a 4.2/3BSD system,
  290. includes the following components:
  291.  
  292. .IP (A)
  293. SAA Program -- 
  294. .B statspy
  295.  
  296. The statistics acquisition agent program of NNStat is named
  297. .B statspy .
  298. .B Statspy
  299. has been implemented for a Sun workstation, and it 
  300. must execute with
  301. \*Qsuperuser\*U privileges to access the NIT interface to the Ethernet.
  302. However, it could be ported to any other 4.2/3BSD system that provided
  303. an interface for promiscuous access to the Ethernet.
  304.  
  305. Each Ethernet packet that 
  306. .B statspy
  307. observes contains an Ethernet header
  308. followed by a sequence of one or more other protocol
  309. headers (e.g., IP, TCP, etc.), which
  310. reflect the successive encapsulation implied by protocol layering.
  311. Each protocol header may be considered to be a string of bits that is
  312. logically divided into substrings called 
  313. .I fields.
  314.  
  315. A particular 
  316. .B statspy
  317. process can (and typically will) gather
  318. a number of different statistical
  319. measures of the packet traffic simultaneously.
  320. Each of these measures is gathered by a separate \fIstatistical object\fP, 
  321. or simply \fIobject\fP.
  322. The set of objects and the selection of protocol fields that they monitor
  323. is determined by the 
  324. .I configuration ,
  325. that can be set or changed while 
  326. .B statspy
  327. is executing.
  328.  
  329. .B Statspy
  330. is controlled by a command language that provides
  331. commands for setting and displaying the
  332. configuration and for displaying the statistical data gathered by its
  333. objects.
  334. .B Statspy
  335. commands may be entered from three locations:
  336.  
  337. .RS
  338. .IP o
  339. From a file, at start-up time.  
  340.  
  341. This is the recommended way to set up the
  342. configuration for collecting long-term statistics, so 
  343. .B statspy
  344. will be self-configuring if the SAA host crashes and restarts.
  345.  
  346. .IP o
  347. Interactively, from the local console controlling statspy.
  348.  
  349. This allows 
  350. .B statspy
  351. to be used as a standalone 
  352. monitoring tool. 
  353.  
  354. .IP o
  355. Interactively, from a remote system running the 
  356. .B rspy
  357. program (see below).
  358. .RE
  359.  
  360. Section 3 describes the command language, including the
  361. command used to set or modify
  362. the configuration. Appendix C suggests useful configuration techniques.
  363.  
  364. If it is executed in foreground, 
  365. .B statspy
  366. accepts
  367. commands and displays statistics locally. Whether in foreground or
  368. background, it listens for a
  369. TCP connection from the remote collection machine (SCH) or from a
  370. remote 
  371. .B rspy
  372. program, and processes all
  373. commands entered over that TCP connection. 
  374. However, the acquisition of new
  375. statistical data from the Ethernet takes highest
  376. priority.
  377.  
  378. Note that 
  379. .B statspy
  380. is not expected to record its data on a local disk;
  381. permanent data recording is assumed to take place only at the SCH.
  382. This choice was made to minimize operational problems at each SAA
  383. site.
  384.  
  385. For more details on the operation and configuration of 
  386. .B statspy , 
  387. see Section 3 below.
  388.   
  389. .IP (B)
  390. Remote SAA Control Program --  
  391. .B rspy
  392.  
  393. The 
  394. .B rspy
  395. program provides an interactive command interface for controlling a
  396. remote 
  397. .B statspy
  398. instance.  
  399. .B Rspy
  400. can be used to establish, query, or modify the 
  401. configuration
  402. and to read and/or clear the statistical objects.
  403. The use of 
  404. .B rspy
  405. is described in Section 3.4.
  406.  
  407. .IP (C)
  408. Centralized Collection Program --
  409. .B collect
  410.  
  411. .B Collect
  412. is the central data collection program of NNStat; it executes
  413. on the SCH to
  414. collect data from one or more 
  415. .B statspy
  416. instances. 
  417. .B Rspy
  418. and 
  419. .B collect
  420. use the same remote network interface to
  421. statspy, but they are designed for different tasks: 
  422. while 
  423. .B rspy
  424. is intended to be used interactively for
  425. testing, probing, and running short-term statistical studies,
  426. .B collect
  427. is intended to be
  428. executed as a daemon, collecting and recording traffic
  429. data over a long period of
  430. time.
  431.  
  432. In normal operation, 
  433. .B collect
  434. will periodically poll a specified set 
  435. of SAA's for statistical data and write the results into cumulative data files.
  436. Note that data is delivered to 
  437. .B collect
  438. only as a result of its polling
  439. the SAA's.  An alternative design would have the SAA's spontaneously
  440. report their data periodically to the SCH.  We chose to use polling for
  441. data collection in order to ensure (approximate) synchronization in gathering 
  442. statistics from all the SAA's, while avoiding an \*Qimplosion\*U of reports to
  443. at the central site.
  444.  
  445. The following basic parameters must be defined to run 
  446. .B collect :
  447.  
  448. .RS
  449. .IP *
  450. List of SAA host names or addresses.
  451. .IP *
  452. TCP port for 
  453. .B statspy
  454. on each SAA (optional).
  455. .IP  *
  456. The name(s) of objects whose accumulated data are to be retrieved from each
  457. .B statspy
  458. instance. 
  459. .IP *
  460. Polling interval Ti.
  461. .IP *
  462. Checkpoint interval Tc.
  463. .IP  *
  464. Clear (\*Qreset\*U) interval Tr.
  465. .RE
  466.  
  467. In one data collection cycle, 
  468. .B collect 
  469. will open a TCP connection to 
  470. .B statspy
  471. on each of the listed hosts 
  472. and retrieve data from (\*Qread\*U) the specified objects, recording the
  473. results in files.
  474. This cycle will be repeated every Ti minutes, but
  475. .B collect
  476. will save or \*Qcheckpoint\*U the data for later analysis 
  477. only every Tc minutes.  
  478.  
  479. The totals returned by each poll are cumulative, unless the objects
  480. are explicitly cleared by command or the SAA (crashes and) restarts.  
  481. Therefore,
  482. if communication between the SCH and an SAA is lost temporarily, a later
  483. successful poll should return complete data. The minimum polling interval
  484. Ti should be short enough that data lost because of a SAA restart
  485. will be negligible.  Of course, if an SAA is down for an extended period,
  486. there is no way to capture statistics from that interconnect Ethernet
  487. for that period.
  488.  
  489. .B Statspy
  490. generally keeps 32-bit counters for counting packet events.
  491. If the average rate were 1000 packets per second, some counters might
  492. overflow once every 4 weeks.  
  493. .B Statspy
  494. makes no special provision for overflow, but instead expects that 
  495. .B collect
  496. will be set up to
  497. periodically clear all the counters using the Tc parameter. 
  498. Every Tc minutes, 
  499. .B collect
  500. will instruct each 
  501. .B statspy
  502. to clear its data counters
  503. after the current values are retrieved.
  504.  
  505. Suggested values for the time parameters to 
  506. .B collect
  507. are:
  508.  
  509.  Ti = 5 minutes
  510.  Tc = 60 minutes
  511.  Tr = 1440 minutes (24 hours).
  512.  
  513. .B Collect
  514. will produce a separate data file for each (statistical measure, SAA
  515. host) pair, for all the statistical measures and hosts specified in its
  516. parameters.  Each of these data files will contain the read data for
  517. every checkpoint time, plus the last data recorded before the
  518. .B statspy
  519. was restarted or its object(s) cleared, and will be
  520. cumulative from the time that
  521. .B collect
  522. program was started.  If the SCH crashes or
  523. .B collect
  524. is restarted for some reason, a new set of data files will be created.
  525.  
  526. Section 4 explains how to use 
  527. .B collect .
  528.  
  529.  
  530. .IP (D)
  531. Data Reduction Programs
  532.  
  533. The NNStat distribution includes some useful programs and AWK scripts for
  534. processing and summarizing the data files created by the
  535. .B collect
  536. program.  These will be described in the Section 4.
  537. .LP
  538.  
  539. .bp
  540. .NH
  541. Statspy
  542. .LP
  543.  
  544. .NH 2
  545. Using Statspy
  546. .LP
  547.  
  548. To execute \fBstatspy\fP, issue the following system command:
  549.  
  550. .B1
  551. .nf
  552.                                                      
  553.   \fBstatspy\fP [\fB\-i \fIinterface\fR] [\fB\-p \fIport\fR] [\fB\-h\fP] [\fB\-t \fItimeout\fR]  [\fIcommand-file\fP]
  554.  
  555. .fi
  556. .B2
  557.     
  558. The parameters are:
  559.  
  560. .IP \fB\-i\fP
  561. Ethernet interface device name; the default is ie0.
  562.  
  563. .IP \fB\-p\fP
  564. TCP port number on which 
  565. .B statspy
  566. will listen for a connection from
  567. .B collect
  568. or 
  569. .B rspy .
  570. The default is 2222.  
  571. .I
  572. At present, the only security mechanism in statspy is the use of 
  573. a private TCP port number.
  574. .R
  575.  
  576. .IP \fB\-h\fP
  577. Causes 
  578. .B statspy
  579. to write a history of remote commands into the standard output.
  580.  
  581. .IP \fB\-t\fP 
  582. Specifies watchdog timeout value in seconds.
  583.  
  584. During a remote operation, 
  585. .B statspy
  586. sets a watchdog timer to detect
  587. a failure of the
  588. connection or remote 
  589. .B collect
  590. program.  The \fB\-t\fP parameter may be used to
  591. override the default timeout of 120 seconds.
  592.  
  593. .IP \fIcommand-file\fP
  594. This optional parameter is the name of a file containing
  595. commands to be executed when 
  596. .B statspy
  597. starts.
  598. Normally, these will be commands to establish the
  599. initial configuration of objects for gathering data.
  600. If this parameter is omitted, 
  601. .B statspy
  602. will await commands from the local console
  603. or from 
  604. .B rspy 
  605. (executing either on the SAA host or remotely)
  606. to establish the configuration.
  607. .LP
  608.  
  609. When it starts, 
  610. .B statspy
  611. executes the commands found in \fIcommand-file\fP, if any.  If it has
  612. been executed in foreground, 
  613. .B statspy
  614. then enters an interactive command mode
  615. in which it repeatedly issues a prompt (\*Q>\*U) and awaits command input.
  616. If 
  617. .B statspy
  618. is executed in background, its standard output and
  619. standard error output should be directed to a file to aid diagnosis
  620. in case a problem occurs.
  621.  
  622. .B Statspy
  623. listens on the specified TCP port for a connection from a
  624. remote 
  625. .B collect
  626. or 
  627. .B rspy
  628. program.  It is currently limited to
  629. one TCP connection at a time, so the TCP connection is opened for
  630. each sequence of remote commands
  631. and closed again when the responses have been returned.
  632.  
  633. .NH 2
  634. Statspy Command Language
  635. .LP
  636.  
  637. The operation and configuration of 
  638. .B statspy
  639. are controlled by a simple
  640. command language.  Commands to 
  641. .B statspy
  642. can be entered from three
  643. sources:
  644.  
  645. .IP (1)
  646. the initial command file (see preceding section);
  647.  
  648. .IP (2)
  649. interactively from the controlling console (i.e., from
  650. standard input); 
  651.  
  652. .IP (3)
  653. remotely from a 
  654. .B collect
  655. or 
  656. .B rspy
  657. program.
  658. .LP 
  659.  
  660. Remote command requests have priority over local commands, while
  661. processing new data from the Ethernet generally preempts either local or
  662. remote
  663. command processing.
  664.  
  665. Commands from any source are free-form and may occupy as many lines as
  666. necessary.  Any text following the \*Q#\*U character and up to the
  667. next newline will be ignored, to allow comments in the 
  668. command stream.
  669.  
  670. Various 
  671. .B statspy
  672. commands reference objects and protocol fields by name.
  673. The field names are built into the program (see Figure 2 in Section 3.3), 
  674. while object names are
  675. assigned by configuration commands.
  676. There are commands  
  677. to return a complete lists of the
  678. names of objects or fields (\*Qread ?\*U or \*Qshow ?\*U, respectively).
  679.  
  680. Commands refer to particular objects by their names.  They can refer to
  681. a set of objects by using a \*Qwildcard\*U matching scheme. An
  682. object specification parameter,  known as an \fIobject spec\fP,  
  683. may contain asterisks as wildcard characters
  684. to match any number of characters.
  685. For example, the command:
  686.  
  687.    read *IP*
  688.    
  689. will apply the read operation to all objects whose names include the
  690. string \*QIP\*U, and
  691.  
  692.    read *
  693.    
  694. will read all objects.
  695. In setting up the configuration, the user should choose a consistent scheme
  696. for assigning object names to increase the
  697. usefulness of this wildcard matching.
  698.  
  699. As we will see in the next section, some objects do not themselves gather
  700. data, but instead conditionally select other objects that do.  
  701. Such conditional objects can be left unnamed, since they
  702. will generally not be referenced by a command after they are created. 
  703. Commands differ in how they treat such unnamed objects
  704. (see below). 
  705.  
  706. We now list all the commands recognized by 
  707. .B statspy.
  708.  
  709. .IP o
  710. read <object spec>
  711.  
  712. Displays the data recorded by the object(s) whose names
  713. match <object\ spec>. 
  714. Unnamed objects cannot be the target of a read operation.
  715.  
  716. .IP o
  717. read ?
  718.  
  719. Displays a summary, which includes the names of all objects.
  720. Unnamed objects will be included in this summary.
  721.  
  722. .IP o
  723. clear <object spec>
  724.  
  725. Sets all objects whose names match <objec\ spec> to their initial
  726. states, i.e., clears their statistical accumulation.  
  727. \*QClear *\*U will clear all objects, including
  728. unnamed objects.
  729.  
  730. .IP o
  731. readclear <object spec>
  732.  
  733. Executes a read followed by a clear operation, atomically.
  734. \*QReadclear *\*U will clear but not read all unnamed objects.
  735.  
  736. .IP o
  737. show *
  738.  
  739. Displays a summary of the current configuration.
  740.  
  741. .IP o
  742. show ?
  743.  
  744. Displays a list of the built-in field names.
  745.  
  746. .IP o
  747. attach { <configuration program> }
  748.  
  749. Augments the current configuration with the additional statistical object(s)
  750. specified by <configuration program>. The curly braces are required.
  751. The <configuration program> is written using a set of rules 
  752. that we will refer to as the 
  753. .I configuration language, 
  754. although
  755. it is really a sub-language of the command
  756. language; see Section 3 for details.
  757.  
  758. The \fIattach\fP command is atomic -- if any error is found, 
  759. the current configuration will remain unchanged.
  760.  
  761. .IP o
  762. detach <object spec>
  763.  
  764. Deletes from the configuration each object whose name matches <object\ spec>.  
  765. This may implicitly delete other objects in order to 
  766. keep the configuration consistent.
  767. \*Qdetach *\*U will detach all objects, including those that have no names.
  768.  
  769. .IP o
  770. ?
  771.  
  772. Displays a list of the commands.  This command is only available on the local
  773. console.
  774.  
  775. .IP o
  776. quit
  777.  
  778. Exits to the operating system (shell) on the SAA host.  This command cannot
  779. be issued across the network.
  780.  
  781. .IP o
  782. enum { <enum parameters> }
  783.  
  784. Defines a set of label strings for use in \fIread\fP command displays.  See
  785. Section 3.3.4 for more explanation.
  786. The curly braces are required. 
  787. .LP
  788.  
  789. All of these commands may be entered remotely from 
  790. .B rspy
  791. or locally.
  792. The 
  793. .B collect
  794. program effectively issues the \fIread\fP and \fIreadclear\fP commands.
  795.  
  796. When a \*Qshow ?\*U command is issued to 
  797. .B statspy,
  798. the first line displayed summarizes the overall packet processing since 
  799. .B statspy
  800. was started.  For example:
  801.  
  802. .SM 
  803.      Acquired 56343 packets in 163 secs=> 345(avg) 755(max) 1250(inst)/sec
  804. .NL
  805.  
  806. This shows the total Ethernet
  807. packets acquired, the elapsed time since 
  808. .B statspy
  809. started, the average packets
  810. per second, the maximum number of packets processed in one second, and
  811. finally the maximum \*Qinstantaneous\*U packet rate.  The last is obtained
  812. by extrapolating to one second the maximum number of packets captured
  813. in one clock tick (20ms on the Sun workstation).
  814.  
  815. .NH 2
  816. Configuring Statspy
  817. .LP
  818.  
  819. We divide the extraction of statistical data from a particular
  820. Ethernet packet into two phases: 
  821.  
  822. .IP (1) 
  823. Parse the protocol headers
  824. to determine the values of
  825. the various header fields.
  826.  
  827. Since efficiency is essential and packet header formats do
  828. not change very often, the header formats are compiled into the 
  829. .B statspy
  830. code.  
  831. Each incoming Ethernet packet is passed to a subroutine
  832. that \*Qknows\*U how to parse all the headers and where to locate
  833. the fields.  To add new protocols or change header formats, 
  834. it will be necessary
  835. to recompile this packet-parsing subroutine of 
  836. .B statspy.
  837.  
  838. .IP (2) 
  839. Analyze the parsed field values and gather the
  840. desired statistics.  
  841.  
  842. This phase is performed interpretively, using a set of rules that 
  843. comprises the 
  844. .B statspy
  845. configuration.
  846. .LP       
  847.  
  848. .NH 3
  849. Fields
  850. .LP
  851.  
  852. Figure 2 shows a list of the fields that will be extracted by
  853. .B statspy
  854. and made available to the analysis phase.
  855. A particular packet will define values for only a subset of
  856. the possible fields; for example, a TCP packet will define the TCP source
  857. and destination ports but cannot define UDP ports or an ICMP type field.
  858.  
  859. As Figure 2 shows, each field is assigned a mnemonic
  860. name string, a size in bytes,
  861. and an intrinsic type.  The type is used principally to choose an appropriate
  862. format for displaying the data values from that field.
  863. Each field is extracted into an integral number of
  864. 8-bit bytes.  Thus, the IP version number (field \*QIP.version\*U)
  865. is actually 4 bits but is extracted (right-justified) by the parser 
  866. into a byte.
  867.  
  868. .KF
  869. .nf
  870. .RS
  871.  
  872. .B1
  873. .nf
  874.  
  875. .ta 1.8iC 3.0i
  876. Field Name    Length(bytes)    Type 
  877. .ta 1.8iR 3.0i
  878.  
  879. Ether.src    6    Ethernet Address
  880. Ether.dst    6    Ethernet Address
  881. Ether.type    2    Integer
  882.    
  883. IP.version *    1    Integer
  884. IP.length    2    Integer
  885. IP.option *    1    Integer
  886. IP.TOS    1    Bits
  887. IP.offset *    2    Integer
  888. IP.protocol    1    Integer
  889.             
  890. IP.srchost    4    IP Address                
  891. IP.dsthost    4    IP Address 
  892. IP.srcnet *    4    IP Address                
  893. IP.dstnet *    4    IP Address  
  894.        
  895. TCP.srcport    4    Integer               
  896. TCP.dstport    4    Integer               
  897. UDP.srcport    4    Integer               
  898. UDP.dstport    4    Integer
  899. ICMP.type    1    Integer 
  900.    
  901. .ta 1.8iC 3.0i
  902. packet *    Variable    Bits
  903.  
  904.  
  905.      Figure 2.  Field Definitions in Packet Parser 
  906.  
  907. .B2
  908.  
  909. .fi
  910. .KE
  911. This list includes virtual fields whose values are derived from those
  912. actually appearing in the header; these
  913. are marked with \*Q*\*U in Figure 2.  
  914. The virtual fields have
  915. the following meanings:
  916.  
  917. .IP (a)
  918. IP.option
  919.  
  920. This is the code byte for each IP option field found in the packet,
  921. or zero if there are no options.  Note that a single packet may
  922. contain several options, so this pseudo-field may be multiply defined.
  923.  
  924. .IP (b)
  925. IP.srcnet, IP.dstnet
  926.  
  927. These are the (Class A, B, or C) network numbers derived from the
  928. real IP source and destination address fields, respectively.
  929. These virtual fields provide a simple and efficient way to develop
  930. statistics based upon networks rather than hosts. 
  931.  
  932. .IP (c)
  933. IP.version
  934.  
  935. This virtual field containing the IP version number
  936. is extracted by
  937. .B statspy
  938. for analysis \fIonly\fP for a packet with a non-standard
  939. IP version number (i.e., not 4). No later fields
  940. (IP, TCP, or UDP) can or will be extracted from the same packet.
  941. .bp
  942.  
  943. .IP (d)
  944. IP.offset
  945.  
  946. This virtual field is extracted 
  947. (we say \*Qdefined\*U) by
  948. .B statspy 
  949. only for a packet that is a fragment
  950. of a complete IP datagram. 
  951. When it is defined, IP.offset is the
  952. ressembly offset of this fragment in bytes (i.e., 8 times the offset
  953. field in the IP header).
  954.  
  955. Only the first fragment, i.e., the fragment at offset zero, can be
  956. parsed further for higher-level protocol headers (TCP, UDP, or ICMP).
  957. We made the reasonable assumption that these headers will always fit
  958. within the first fragment, i.e, that the first fragment will always
  959. be larger than about 90 bytes (unless it is also the last fragment).
  960.  
  961. Note that for a fragmented packet the IP.length, IP.option, and
  962. IP.TOS fields are defined for each fragment separately. Thus, IP.length
  963. gives the length of the fragment; 
  964. .B statspy
  965. cannot determine the total length the reassembled IP datagram.
  966.  
  967. .IP (e)
  968. packet
  969.  
  970. This virtual field contains the binary value of the header sequence.
  971. It is intended for recording particular packet headers for diagnostic
  972. rather than statistical purposes.
  973. .LP
  974.  
  975. .NH 3
  976. Objects and Invocations
  977. .LP
  978.  
  979. Statistical analysis of field values is performed by a set of 
  980. .B statspy
  981. entities known as (statistical)
  982. .I objects.
  983. NNStat implements unary and binary objects, i.e., objects that take one
  984. and two input values.  Each object may have a unique name that
  985. is assigned when the object is defined.
  986.  
  987. Objects 
  988. are logically independent of fields; objects
  989. simply build and report statistical data structures based on 
  990. (field) values written
  991. into them.  
  992. The analysis phase is essentially a series of calls on object
  993. .I Write
  994. subroutines; in each call, 
  995. a particular field value (or pair of field values) is
  996. passed as a parameter.
  997. These Write subroutine calls are known as 
  998. .I invocations.
  999.  
  1000. For example, the configuration might specify that an object named
  1001. \*QProtocol.freq\*U is to be invoked on the field named
  1002. \*QIP.protocol\*U; that is, the value of field \*QIP.protocol\*U will be
  1003. written into object \*QProtocol.freq\*U.  The configuration may specify
  1004. that the same field is to invoke more than one object.  Conversely, the
  1005. same object may be invoked on more than one field, to build a composite
  1006. statistic. Fields that invoke the same object must be compatible, i.e.,
  1007. they must have the same size and type (see Figure 2 for the types).
  1008.  
  1009. Each object is an instance of a particular object class; all objects of
  1010. the same class share the same program modules but each has its private
  1011. data structure.  The
  1012. .B statspy
  1013. object classes generally fall into two categories:  recorders and
  1014. filters.
  1015.  
  1016. .IP (A)
  1017. Recorders
  1018.  
  1019. A data recorder object or 
  1020. .I recorder
  1021. builds some statistical data structure (e.g., a 
  1022. frequency distribution table) from the field values with which it is invoked.
  1023. .RS
  1024.  
  1025. Example:  \fIfreq-all\fP
  1026.  
  1027. An object
  1028. of class \fIfreq-all\fP builds a frequency distribution table for all
  1029. distinct values of the field on which it is invoked.
  1030. .RE
  1031.  
  1032. Figure 3 shows
  1033. an example of the display output resulting from a read operation 
  1034. on a \fIfreq-all\fP object named \*Qgwys\*U.  The field values recorded in
  1035. this object are 48-bit Ethernet addresses.
  1036.  
  1037. .KS
  1038. .B1
  1039. .nf
  1040.  
  1041.  OBJECT: gwys Class= freq-all [CreationTime: 11:51:25 11-05-87]
  1042.    ReadTime: 11:52:18 11-05-87, 
  1043.    ClearTime: 11:51:25 11-05-87 (@ -53 secs)
  1044.   Total Count= 492 (+0 orphans)
  1045.   #bins= 8  
  1046.  [2:7:1:0:8:30]= 219     (45%) @- 1secs 
  1047.  [8:0:2:0:49:30]= 127    (26%) @- 1secs 
  1048.  [2:60:8c:ee:2:34]= 52   (11%) @- 1secs 
  1049.  [24:24:80:9:0:6b]= 44   (8.9%) @- 1secs 
  1050.  [8:0:14:10:12:8]= 27    (5.5%) @- 1secs 
  1051.  [8:0:2:0:f7:2b]= 20     (4.1%) @- 2secs 
  1052.  [aa:0:3:1:5:90]= 2      (0.41%) @- 13secs 
  1053.  [2:7:1:0:4:45]= 1       (0.2%) @- 32secs 
  1054.  
  1055.  
  1056.       Figure 3. Example of Read Output
  1057.  
  1058. .fi
  1059. .B2
  1060. .KE
  1061.  
  1062. Each of the bottom 8 lines displays the contents of one bin:
  1063. the value (6 bytes in hex), 
  1064. the count, the percentage count,
  1065. and the last-update time relative to the current time (\*QReadTime\*U).
  1066.  
  1067. .IP (B)
  1068. Filters
  1069.  
  1070. Data filter objects or 
  1071. .I filters
  1072. provide conditional branches in the
  1073. configuration.
  1074.  
  1075. When invoked with a field value, a filter tests it against some
  1076. numerical or set-inclusion criterion, to determine a Boolean (True/False)
  1077. value.  This Boolean value is then used by the \fBstatspy\fP interpreter
  1078. to select one of two alternative sub-sequences of invocations, where either
  1079. of these sub-sequences may be empty.
  1080.  
  1081. .mc |
  1082. .RS
  1083. Example: \fIeqf\fP
  1084.  
  1085. An object of class \fIeqf\fP tests a field value for 
  1086. equality to a parameter
  1087. value that is specified when the object is created.
  1088. .RE
  1089.  
  1090. .mc
  1091. By nesting filter invocations in a configuration, record invocations can
  1092. be conditioned upon an arbitrary Boolean expression over field values.
  1093.  
  1094. Figure 4 shows an example of (a fragment of) a pseudo-program,
  1095. in flow-chart form. This
  1096. sequence of invocations was designed to answer the question: \*Qwhat are
  1097. the Ethernet addresses of hosts sending or receiving transit packets,
  1098. i.e., of IP packets that neither originate or terminate on the local
  1099. Ethernet?\*U.
  1100. .KF
  1101. .nf
  1102. .ta 0.5i 2.5i
  1103. .lc _
  1104.  
  1105.      ____________________________    
  1106.     |  Invoke \fIeqf\fP filter object  |
  1107.     |     with parm (128.9.0.0)  |
  1108.     |     on field \*QIP.srcnet\*U   |
  1109.     |____________________________|
  1110. .ta 1i 2i
  1111.     |    |
  1112.     | TRUE    | FALSE
  1113.     V    |
  1114.         (Null)    |
  1115.         |
  1116.         V
  1117. .ta 0.75i 2.75i
  1118.     _____________________________    
  1119.     |  Invoke \fIeqf\fP filter object  |
  1120.     |     with parm (128.9.0.0)  |
  1121.     |     on field \*QIP.dstnet\*U   |
  1122.     |____________________________|
  1123. .ta 1.25i 2.25i
  1124.     |    |
  1125.     | TRUE    | FALSE
  1126.     V    |
  1127.        \ \ \ \ \ \ (Null)    |
  1128.         |
  1129.         V    
  1130. .ta 1.0i 3.0i
  1131.      __________________________    
  1132.     | Invoke \fIfreq-all\fP recorder |
  1133.     |    object named \*Qgwys\*U   |
  1134.     |   on field \*QEther.src\*U   |
  1135.     |__________________________|
  1136. .ta 2.0i
  1137.     |
  1138.     |
  1139.     V
  1140. .ta 1.0i 3.0i
  1141.      __________________________    
  1142.     | Invoke \fIfreq-all\fP recorder |
  1143.     |    object named \*Qgwys\*U   |
  1144.     |   on field \*QEther.dst\*U   |
  1145.     |__________________________|
  1146.     
  1147.     
  1148.       Figure 4.  Example Pseudo-program  
  1149.  
  1150.  
  1151. .fi
  1152. .KE 
  1153.  
  1154. Figure 4 includes two invocations
  1155. of an unnamed \fIeqf\fP filter object whose parameter is the value
  1156. 128.9.0.0 (the IP address of the local Ethernet).
  1157. Thus, the first invocation shown in Figure 4 will return
  1158. TRUE if the IP source network number in field \*QIP.srcnet\*U
  1159. is 128.9.0.0, and FALSE otherwise.
  1160.  
  1161. .NH 3
  1162. Configuration Language
  1163. .LP
  1164.  
  1165. We begin with an example of the configuration (sub-)language for 
  1166. .B statspy.
  1167. The configuration of Figure 4 could be created by entering an
  1168. \fIattach\fP command with the <configuration program> shown in Figure 5.
  1169.  
  1170. .mc |
  1171. .KS
  1172. .nf
  1173. .RS
  1174. .B1
  1175.  
  1176.   if IP.srcnet is eqf(128.9.0.0)  {
  1177.      if IP.dstnet is eqf(128.9.0.0)  {
  1178.         record Ether.src in gwys freq-all;
  1179.         record Ether.dst in gwys;
  1180.      }
  1181.   }
  1182.   
  1183. .fi
  1184. .RE
  1185.  Figure 5. Configuration program that compiles into Figure 4.
  1186.      
  1187. .B2
  1188. .KE
  1189.  
  1190. .mc
  1191. Figure 5 illustrates several points about the configuration language:
  1192.  
  1193. .IP 1.
  1194. The language is free-field with newlines having no meaning.  Hence, we
  1195. can indent to illuminate the structure of the program.
  1196.  
  1197. .IP 2.
  1198. The language includes compound statements and \*Qif\*U statements; the latter
  1199. correspond to invocations of filter objects.
  1200.  
  1201. .IP 3.
  1202. The first time a named object occurs, its class (and parameters, if any)
  1203. must be specified.  They may be omitted in later references to the same
  1204. object. 
  1205. .mc |
  1206. If they are included, their values must exactly match the parameters
  1207. specified in the first occurrence of the same object.
  1208. .mc 
  1209.  
  1210. .IP 4.
  1211. Parameters, when required, are enclosed in parentheses 
  1212. following the class name.  If there is more than one parameter, they
  1213. are listed separated by commas.
  1214.  
  1215. .IP 5.
  1216. An unnamed object may be created, by giving only its class (and parameter,
  1217. if any).  Filter objects are often left unnamed, since there is
  1218. usually no need to read them.
  1219.  
  1220. Note: class names are reserved, and not coincide with object names.
  1221. The valid class names are all listed in Appendix A.
  1222. .LP
  1223.  
  1224. Two more things about the language are not apparent from this
  1225. example:
  1226.  
  1227. .IP 6.
  1228. The outer set of
  1229. braces in Figure 4 is unnecessary.  The syntax of the
  1230. configuration language is generally like \*QC\*U.
  1231.  
  1232. .IP 7.
  1233. Specific configuration rules are triggered only when the fields upon
  1234. which they depend are defined in a packet.
  1235.  
  1236. Thus, in Figure 4 it was not necessary to explicitly test that the packet
  1237. in question was an IP packet; if it were not an IP packet, then the
  1238. IP.srcnet and IP.dstnet fields would not be defined.
  1239.  
  1240. Furthermore,
  1241. .B statspy
  1242. checks and enforces consistency among the fields, so that the
  1243. configuration cannot include invocations that are logically impossible.
  1244. An example of such an illegal configuration is:
  1245.  
  1246. .mc |
  1247.     if TCP.srcport is eqf(23)
  1248.        IF UDP.dstport is eqf(6)
  1249.           record Ether.src in Imposs-obj freq-all;
  1250. .mc          
  1251.           
  1252. This configuration is illegal because TCP.srcport and UDP.dstport cannot
  1253. be defined in the same packet, hence the \*QImposs-obj\*U recorder
  1254. would never be invoked. 
  1255. .LP
  1256.  
  1257. We now list general syntax rules for the configuration language.
  1258. Appendix B specifies the exact syntax of the 
  1259. configuration language, using BNF.
  1260.  
  1261. .IP (1)
  1262. RECORDER OBJECT:
  1263.  
  1264. To create a (unary) recorder object that is invoked on a specified field, use
  1265. the following statement:
  1266.  
  1267.     \fBrecord\fP <field name> \fBin\fP <object name> 
  1268.     
  1269.                 <class> \fB(\fP <parameters> \fB) ;\fP
  1270.  
  1271. For a binary object, two fields are required:
  1272.  
  1273.     \fBrecord\fP  <field name>\fB,\fP <field name> \fBin\fP <object name> 
  1274.     
  1275.                 <class> \fB(\fP <parameters> \fB) ; \fP
  1276.  
  1277.    
  1278. In either case, <class> must match the name of a valid recorder class. 
  1279. The current set of <class> names and corresponding <parameters> 
  1280. are defined in Appendix A.  
  1281.  
  1282. Normally, every recorder object ought to have a unique <object name>,
  1283. so that it can be read, cleared, and/or detached independently
  1284. of other objects.  However, a recorder object may be created
  1285. with a null <object name>.  Such an object can be destroyed (detached) or
  1286. cleared, but not read.
  1287.  
  1288. Note the semicolons following record statements; these are
  1289. required.
  1290.    
  1291. .IP (2)
  1292. FILTER OBJECTS:
  1293.  
  1294. To create a filter object to be invoked by a specified field, use 
  1295. a conditional statement. This takes the form of
  1296. a \fIfilter clause\fP:
  1297.  
  1298.     \fBif\fP <field name> \fBis\fP <object name> 
  1299.     
  1300.                   <class> \fB(\fP <parameters> \fB)\fP 
  1301.     
  1302. followed by either:
  1303.  
  1304.     <TRUE invocation> 
  1305.     
  1306.  or:
  1307.  
  1308.     <TRUE invocation> else <FALSE invocation> 
  1309. .sp  
  1310.  
  1311. Here, <field name> <class> must match the name of a valid recorder class.
  1312.   
  1313. <TRUE invocation> and <FALSE invocation> may themselves be recorder
  1314. or filter invocations, or may be arbitrary sublists of invocations, grouped
  1315. together inside braces \*Q{ }\*U.  These sublists may themselves include filter 
  1316. invocations, and this nesting can go to any depth.
  1317.  
  1318. The sense of the filter clause may be reversed by specifying "isnot"
  1319. instead of "is".
  1320. .LP
  1321.  
  1322. The <parameters> string generally specifies a list of one or more values
  1323. separated by commas.  The number and meaning of these values depend
  1324. upon the particular class (see Appendix A for details).  The 
  1325. <parameters> string and the surrounding parentheses may be omitted if the
  1326. particular class does not require parameters or if the specified object
  1327. has been defined previously with parameters.
  1328.  
  1329. .mc |
  1330. If the specified <object name> already exists, a new invocation
  1331. specification refers to the same object.  In this case, <class> may
  1332. be omitted, but if it is respecified it must agree with the class
  1333. of the existing object.  If <class> is respecified, then
  1334. \*Q\ (\ <parameters>\ )\*U may also be respecified, but its values
  1335. must agree with the parameters given for the existing object.
  1336.  
  1337. .NH 3
  1338. Attach Error Messages
  1339. .LP
  1340.  
  1341. This section lists the error messages that may occur in processing an
  1342. attach command.
  1343.  
  1344. .IP *
  1345. ATTACH error -- Bad field name: <field name>
  1346.  
  1347. The specified string is not the name of any defined field.  The valid
  1348. field names can be obtained at any time using "show ?".
  1349. .IP *
  1350. ATTACH error -- Class Conflict for: <object name>
  1351.  
  1352. Two invocations of the same object specify conflicting class names.
  1353. .IP *
  1354. ATTACH error -- Parm list conflict for: <object name>
  1355.  
  1356. Two invocations of the same object specify conflicting parameter lists.
  1357. .IP *
  1358. ATTACH error -- Unknown class for new object: <object name>
  1359.  
  1360. In the first invocation of an object, no class has been specified.
  1361. .IP *
  1362. ATTACH error -- Conflicting data type: <object name>
  1363.  
  1364. The same object is being invoked on different fields thathave different
  1365. types and are therefore incompatible.
  1366. .IP *
  1367. ATTACH error -- Conflicting field size: <object name>
  1368.  
  1369. The same object is being invoked on different fields that have different
  1370. lengths and are therefore incompatible.
  1371. .IP *
  1372. ATTACH error -- Cannot start with <input text>
  1373.  
  1374. Syntax error.
  1375. .IP *
  1376. ATTACH error -- Syntax error at <input text>
  1377. .IP *
  1378. ATTACH error -- No matching enum for <text>
  1379.  
  1380. Unable to find matching enum string for symbolic parameter value.
  1381. .IP *
  1382. ATTACH error -- Unknown name: <string>
  1383.  
  1384. Unknown host domain name used as a parameter value.
  1385. .RE
  1386.  
  1387. .mc
  1388. .NH 3
  1389. Enumerations
  1390. .LP
  1391.  
  1392. Some packet header fields (e.g., the IP protocol number) 
  1393. may be characterized as \*Qenumerations\*U, 
  1394. meaning that there is a discrete set of possible values.
  1395. It is helpful to humans viewing the output of a \fIread\fP command to have 
  1396. appropriate mnemonic labels attached to the values of enumeration fields.
  1397. The \fIenum\fP command may be used to define such mnemonic label strings.
  1398.  
  1399. The \fIenum\fP command has only local effect;  
  1400. \fIEnum\fP commands taken from the 
  1401. .B statspy
  1402. configuration file or entered
  1403. locally on the 
  1404. .B statspy
  1405. console control only the formatting of
  1406. local read commands.  Similarly, an \fIenum\fP
  1407. command entered in 
  1408. .B rspy
  1409. is used locally at 
  1410. .B rspy
  1411. for formatting
  1412. read results; it is not transmitted across the network to 
  1413. .B statspy .
  1414.  
  1415. The \fIenum\fP command has the form:
  1416.  
  1417.      \fBenum {\fP <enum parameters> \fB}\fP
  1418.    
  1419. The general form of <enum parameters> is:
  1420.  
  1421. .DS
  1422. <object spec> ( <value> <label>, ... , <value> <label> ),
  1423.  
  1424.      ...
  1425.      
  1426. <object spec> ( <value> <label>, ... , <value> <label> )
  1427.  
  1428. .DE
  1429.  
  1430. That is, it generally specifies a list of object name specs, 
  1431. and for each 
  1432. a sub-list of (label, value) pairs. 
  1433.  
  1434. Here is a possible \fIenum\fP command parameter that defines label strings
  1435. for objects attached to the IP protocol field:
  1436.  
  1437. .KS
  1438.    *IP.proto* (1 \*QICMP\*U, 3 \*QGGP\*U, 6 \*QTCP\*U, 8 \*QEGP\*U, 
  1439.      
  1440.            12 \*QPUP\*U, 17 \*QUDP\*U,  20 \*QHMP\*U, 21 \*QXNS-IDP\*U, 
  1441.        
  1442.            27 \*QRDP\*U, 77 \*QND\*U) 
  1443. .KE
  1444.  
  1445. The string \*Q*IP.proto*\*U is an <object spec>, indicating that this
  1446. list of labels will be used in formatting a read operation for any object
  1447. whose name contains the embedded string \*QIP.proto\*U.
  1448.  
  1449. Note that each sublist is keyed to an <object spec>, not an object name
  1450. or a field name.  When the results of reading a specific object are
  1451. formatted for display, the <object name> of that object is matched
  1452. against each <object spec> that has appeared in any \fIenum\fP command;
  1453. the first match causes the corresponding set of (label, value) pairs to
  1454. be used.  Careful choice of object names is necessary to take advantage
  1455. of this wildcard matching mechanism.
  1456.  
  1457. The <label> elements may be surrounded with quotation marks (\*Q\*U), and
  1458. must be if they contain embedded blanks or other special
  1459. .mc |
  1460. characters.  A label surrounded with quotation marks may contain any
  1461. printable characters except: comma, linefeed ("\\n"), or
  1462. quotation marks themselves.
  1463. .mc
  1464.  
  1465. The effect of \fIenum\fP commands is cumulative.  There is no command to
  1466. delete an enumeration; however, new label definitions will override
  1467. previous definitions for the same (object-spec, value) pairing.
  1468. .LP
  1469.  
  1470. .NH 2
  1471. Remote Control of Statspy
  1472. .LP
  1473.  
  1474. The 
  1475. .B rspy
  1476. program may be used to enter commands remotely to a running
  1477. .B statspy
  1478. program.  The command to execute 
  1479. .B rspy
  1480. is:
  1481.  
  1482.  
  1483. .B1
  1484.                                              
  1485.   \fBrspy\fP  [\fB\-p \fIport\fR] [\fB\-h \fIhost\fR] [\fIcommand-file\fP] 
  1486.     
  1487. .B2        
  1488.  
  1489.         
  1490. Here the parameters are:
  1491.  
  1492. .IP \fB\-p\fP
  1493. TCP port number on which 
  1494. .B statspy
  1495. is listening.
  1496. The default is 2222.  
  1497.  
  1498. .IP \fB\-h\fP
  1499. The name or dotted-decimal IP address of the 
  1500. .B statspy
  1501. host.  The default is the local host.
  1502.  
  1503. .IP \fIcommand-file\fP
  1504. The optional name of a file containing a script of commands to be executed when
  1505. .B rspy
  1506. begins.
  1507. .LP
  1508.  
  1509. .B Rspy
  1510. will then prompt for input (\*QRspy>\*U), accepting
  1511. new commands from standard input and writing any output to standard
  1512. output.  Unix*
  1513. .FS
  1514. * UNIX is a trademark of AT&T Bell Laboratories.
  1515. .FE
  1516. pipes can be used for input commands and/or output results.
  1517.  
  1518. The commands to 
  1519. .B rspy
  1520. are those listed in Section 3.2 for 
  1521. .B statspy , 
  1522. plus one additional command peculiar to 
  1523. .B rspy :
  1524.  
  1525. .IP o
  1526. \fIhost\fP <IP address>
  1527.  
  1528. Overrides the -h parameter
  1529. to specify the remote host to which following commands
  1530. will be directed.
  1531. Here <IP address> may be a host domain name or a dotted-decimal IP address.
  1532. .LP
  1533.  
  1534. Generally, commands entered to 
  1535. .B rspy
  1536. are sent to 
  1537. .B statspy
  1538. on the
  1539. remote host.  However, the \fI?\fP, \fIenum\fP, \fIhost\fP, and \fIquit\fP
  1540. commands are executed locally by \fBrspy\fP.
  1541.  
  1542. .bp
  1543. .NH 
  1544. Data Collection
  1545. .LP
  1546.    
  1547. .NH 2
  1548. Using Collect
  1549. .LP
  1550.  
  1551. .B Collect
  1552. is executed as:
  1553.  
  1554.  
  1555. .B1
  1556. .nf
  1557.  
  1558.   \fBcollect\fP [\fB\-e \fIenumfile\fR]  [\fB\-h \fIhost1\fR] ... [\fB\-h \fIhostn\fR]   [\fB\-p \fIport\fR]
  1559.   
  1560.       [\fB\-i \fImin\fR]  [\fB\-c \fImin\fR]  [\fB\-r \fImin\fR]  [\fB\-d\fP|\fB\-dl\fP|\fB\-dx\fP]  \fIobject-spec\fP
  1561.  
  1562. .fi
  1563. .B2
  1564.  
  1565. These parameters are:
  1566.  
  1567. .nf
  1568. .IP \fIobject-spec\fP
  1569. The objects from which data is to be collected.  \fIobject-spec\fP may
  1570. contain the \*Qwild-card\*U character \*Q*\*U.  
  1571. \fIobject-spec\fP is a mandatory parameter, with no default.
  1572.  
  1573. .IP \fB\-e\fP
  1574. Name of a file containing <enum parameters>
  1575. (see Section 3.3.4) for labeling results.  Default is no enum file.
  1576.  
  1577. .IP \fB-p\fP
  1578. TCP port to connect to; default is 2222.
  1579.  
  1580. .IP \fB-h\fP
  1581. An SAA host from which data is being collected.  A series of \fB-h\fP
  1582. parameters may appear, to define a list of SAA hosts.  Parameter may be a
  1583. dotted decimal IP address or a domain name.  Default is the local host.
  1584.  
  1585. .IP \fB-i\fP
  1586. Polling interval Ti in minutes. Default is 0, causing \fBcollect\fP to
  1587. run once.
  1588.  
  1589. .IP \fB-c\fP
  1590. Checkpoint interval Tc in minutes.  Default is 0, causing only the latest
  1591. data to be saved.
  1592.  
  1593. .IP \fB-r\fP
  1594. Clear interval Tr in minutes.  This
  1595. is the interval at which \fBcollect\fP sends \fIreadclear\fP 
  1596. instead of \fIread\fP command to the hosts.  Default is zero, causing
  1597. no clearing to take place.
  1598.  
  1599. .IP \fB-d\fP
  1600. Direct trace & log to stdout.
  1601. .IP \fB-dl\fP
  1602. Direct trace to stdout, log to files.
  1603. .IP \fB-dx\fP
  1604. Direct trace & hex dump to stdout.
  1605.  
  1606. Default is no trace, log directed to files.
  1607. .LP            
  1608.  
  1609. The time parameters used by the 
  1610. .B collect
  1611. program must be entered in minutes; this unit was chosen
  1612. both for convenience
  1613. and to avoid giving the user a false sense of precision.
  1614.  
  1615. An example of typical parameters that one might use to run 
  1616. .B collect
  1617. from a \*QC shell\*U is as follows:
  1618.  
  1619.    collect '*' -h 35.1.1.21 -i 5 -c 60 -r 1440 >& errors.log &
  1620. .fi
  1621.  
  1622. In this example:
  1623.  
  1624. .IP o
  1625. The read interval Ti is 5 minutes, the checkpoint interval Tc is 60 minutes,
  1626. and the clear interval Tr is 1440 minutes (24 hours).
  1627.  
  1628. .IP o
  1629. The '*' object-spec tells 
  1630. .B collect
  1631. to read and save
  1632. statistics from all objects.
  1633.  
  1634. .IP o
  1635. The -h 35.1.1.21 parameter specifies the host on which 
  1636. .B statspy
  1637. is executing.
  1638.  
  1639. .IP o
  1640. The \*Q>& errors.log\*U redirects any error reports to the file
  1641. \*Qerrors.log\*U.
  1642. .IP o
  1643. The final \*Q&\*U starts the collection of statistics 
  1644. in background mode, so that it is unaffected by other use of
  1645. the shell and logouts.  It can be stopped via use of the  
  1646. \*Qkill\*U command.
  1647. .LP
  1648.  
  1649. .NH 2
  1650. Collect Log Files
  1651. .LP
  1652.  
  1653. .B Collect
  1654. saves statistics in files whose names are formed from the 
  1655. .B statspy
  1656. host name, the object name, and the time that 
  1657. .B collect
  1658. is started.
  1659. For example, the statistics file named:
  1660.  
  1661.     \*Q35.1.1.21-gwys.1214.1540\*U
  1662.         
  1663. was
  1664. created at 1540 (local time for 
  1665. .B collect
  1666. ) on December 14th, and contains
  1667. statistics from the object named \*Qgwys\*U on
  1668. .B statspy
  1669. host \*Q35.1.1.21\*U.
  1670.  
  1671. Figure 3 shows an example of an individual
  1672. .B collect
  1673. log entry, which has the same format as a local display of the read data.    
  1674. Each log entry contains three timestamps:
  1675. .IP o
  1676. \*QCreationTime\*U is the time that the 
  1677. .B statspy
  1678. module was started.
  1679. .IP o
  1680. \*QReadTime\*U is the time associated with the data in the current log entry.
  1681. .IP o
  1682. \*QClearTime\*U is the last time that this object was cleared.  If the
  1683. object has never been explicitly cleared, the ClearTime is the same as
  1684. the CreationTime.
  1685. .LP
  1686.  
  1687. The 
  1688. .B statspy
  1689. module sends these timestamps 
  1690. in universal (UNIX) time, and 
  1691. .B collect
  1692. converts them to its
  1693. local time when they are formatted and written.
  1694.  
  1695. Not all of the data that
  1696. .B collect
  1697. receives from
  1698. .B statspy
  1699. are saved permanently in log files.  Data must be saved in two
  1700. situations:
  1701.  
  1702. .IP (1) 
  1703. The time between
  1704. checkpoints has elapsed.
  1705.  
  1706. The \*Qcheckpoint\*U
  1707. parameter is typically used to provide a statistical breakdown of traffic
  1708. by time of day, e.g.,
  1709. the number of packets received during each hour of the day.
  1710.  
  1711. .IP (2) 
  1712. The 
  1713. .B statspy
  1714. object has 
  1715. been cleared.  
  1716.  
  1717. The
  1718. .B statspy
  1719. object may have been cleared intentionally by a clear command or
  1720. unintentionally by a crash and restart of the SAA machine.  The
  1721. .B collect
  1722. program polls each
  1723. .B statspy
  1724. every Ti minutes, which should be short enough to minimize the
  1725. statistical loss due to SAA crashes.
  1726. .LP
  1727.  
  1728. It is also possible that the SCH running
  1729. .B collect
  1730. will itself crash.  Therefore,
  1731. .B collect
  1732. always writes new data into the log file, but it may either overwrite the
  1733. previous log entry or append to the end of the file, saving the
  1734. previous entry.
  1735.   
  1736. In order to decide whether a particular entry should be
  1737. saved, 
  1738. .B collect
  1739. keeps track of the
  1740. last \*QClearTime\*U received and the next time that a checkpoint
  1741. log entry should be saved.  
  1742. Specifically, 
  1743. .B collect
  1744. will overwrite the previous entry unless:
  1745. .IP a. 
  1746. The previous entry is the very first entry appearing in
  1747. the log file, or
  1748. .IP b.
  1749. The previous entry was received after/at the time that 
  1750. a checkpoint was required, or
  1751. .IP c.
  1752. The ClearTime on the current entry is different from 
  1753. the ClearTime on the previous entry.
  1754. .LP
  1755.  
  1756. .NH 2
  1757. Data Reduction Programs
  1758. .LP
  1759.  
  1760. The NNStat package includes several programs to process log files
  1761. produced by the  
  1762. .B collect
  1763. program.  
  1764. The 
  1765. .B lookupnames
  1766. program scans through log files, outputting the
  1767. original text of the log file with the appropriate domain name added
  1768. following each instance of a host number or a network number.
  1769. Shell scripts that invoke AWK programs have also been included.  
  1770. These scripts may be installed as command aliases named 
  1771. .B count-totals
  1772. and 
  1773. .B bin-totals .
  1774. These commands are intended to provide
  1775. part of the data reduction capability needed to produce traffic statistics. 
  1776.  
  1777. .NH 3
  1778. Lookupnames Program
  1779. .LP
  1780.  
  1781. The 
  1782. .B lookupnames
  1783. program may be used to scan log files for embedded host and 
  1784. network numbers, map these numbers into corresponding names, and create a
  1785. new file with the names inserted immediately after the corresponding numbers.
  1786.  
  1787. The following is an example of output produced by 
  1788. .B lookupnames:
  1789.  
  1790. .KS
  1791.   [35.0.0.0 MERIT:35.0.0.0 MERIT]= 112665 (93.9%) @-0sec
  1792.   [35.0.0.0 MERIT:128.116.0.0 USAN]= 387  ( 0.3%) @-36sec
  1793.   [128.116.0.0 USAN:35.0.0.0 MERIT]= 462  ( 0.4%) @-35sec
  1794.   [35.0.0.0 MERIT:128.182.0.0 PSCNET]= 388 ( 0.3%) @-46sec
  1795.    [128.182.0.0 PSCNET:35.0.0.0 MERIT]= 345 ( 0.3%) @-45sec
  1796. .KE
  1797.  
  1798.  
  1799. The number-to-name conversion is performed using the Domain Name 
  1800. system, or if
  1801. no matching entry is returned, by a local file of network names.  A standard
  1802. hosts.txt file may also be used to supply the network names.  
  1803. If no host/network name is found in either database, the string
  1804. \*Q(UNKNOWN-HOST)\*U is displayed in place of the name.
  1805.  
  1806. The usage is:
  1807.  
  1808. .B1
  1809.  
  1810.   \fBlookupnames\fP [\fB\-n \fIfilename\fR] [\fB\-t \fIseconds\fR] \fIinput-file-list\fP
  1811.  
  1812. .B2    
  1813.     
  1814. The input files, concatenated and augmented with the name strings, are
  1815. written to standard output.
  1816.  
  1817. The optional command line flags are as follows:
  1818.  
  1819. .IP \fB\-n\fP
  1820. The name of a networks file. If this parameter is unspecified, the
  1821. program looks for a file named: 
  1822. \*Qnetworks.txt\*U.  
  1823. This file should contain the networks 
  1824. portion of a standard \*Qhosts.txt\*U file, for example:
  1825.  
  1826.     NET : 128.9.0.0 : ISI-NET :
  1827.  
  1828. Alternatively, the full hosts.txt may be used.  The 
  1829. .B lookupnames
  1830. program scans the networks list for \*QNET\*U entries, until the
  1831. beginning of first \*QGATEWAY\*U entry or the end of the file.
  1832.  
  1833. .IP \fB\-t\fP
  1834. The timeout time for host name lookups; the default is 5 seconds.
  1835. If this timeout expires, the 
  1836. .B lookupnames
  1837. program checks the
  1838. networks-file for a matching entry.  If none is found, the string
  1839. \*Q(TIMEOUT)\*U is printed in place of the host/network name.
  1840.  
  1841. .NH 3
  1842. Count-totals
  1843. .LP
  1844.  
  1845. The command 
  1846. .B count-totals
  1847. can be used to summarize total packet counts logged by the 
  1848. .B collect
  1849. program.
  1850. Taking into account any 
  1851. .B statspy
  1852. restarts or 
  1853. .B statspy
  1854. totals that were
  1855. cleared, it computes both daily totals and a grand total from a given log
  1856. file.  It may be invoked on a list of log files, in which case it 
  1857. summarizes each file independently.
  1858.  
  1859. The command used to invoke 
  1860. .B count-totals
  1861. is:
  1862.  
  1863.     \fBcount-totals [v=1] \fIlogfile\fR ... 
  1864.  
  1865. The required \fIlogfile\fP parameter is a list of one or more log files 
  1866. produced by 
  1867. .B collect
  1868. (and no others).
  1869. The list may contain the usual wildcard specification(s).
  1870. Output is written to a results file named \*Qcount-totals.out\*U,
  1871. as well as to the standard output. 
  1872.  
  1873. An example is:
  1874.  
  1875.     count-totals v=1 *IP*
  1876.  
  1877. The optional \fBv=1\fP parameter is used to signify that the results should
  1878. be \*Qverbose\*U, which in this case means that a line summarizing each update
  1879. appears in the results file.  If the \fBv=1\fP parameter is omitted, only
  1880. daily totals and a grand total are included.
  1881.  
  1882. The following is an example of the format of a verbose results file:
  1883.  
  1884. .KS
  1885. .nf
  1886. .B1
  1887.  
  1888.   File: 35.1.1.21-IP.lens.1221.1523
  1889.  
  1890.   Log created on Tue Dec 22 08:00:25 1987, for host 35.1.1.21.
  1891.     Sample interval = 60 min; checkpoint interval = 60 min.
  1892.     Object name = 'IP.lens'.
  1893. .ta 1.3i 2.3i 3.3i
  1894.  
  1895.     Read-Time    Clear-Time    Total-Count    Increment
  1896.     ---------    ----------    -----------    ---------
  1897. .ta 2.3iR 2.8iR 3.8iR
  1898.  
  1899.     08:01:10 12-22    07:06:22 12-22    19262    0
  1900.     09:00:55 12-22        52297    33035
  1901.     10:01:04 12-22        81393    29096
  1902.     11:00:54 12-22        119954    38561
  1903.    ... (etc)
  1904.     23:00:54 12-22        468588    12147
  1905.     00:00:55 12-23        493492    24904
  1906.   Daily total = 474230 (08:01:10 12-22 to 00:00:55 12-23)
  1907.  
  1908.     01:00:54 12-23        515588    22096
  1909.     02:00:54 12-23        542095    26507
  1910.     03:00:54 12-23        566430    24335
  1911.     04:00:54 12-23        586511    20081
  1912.    ... (etc)
  1913.     22:00:57 12-23        1043959    7317
  1914.     23:00:55 12-23        1054753    10794
  1915.     00:00:58 12-24        1070114    15361
  1916.   Daily total = 576622 (00:00:55 12-23 to 00:00:58 12-24)
  1917.    ... (etc)
  1918.    ... (etc)
  1919.   Daily total = 182408 (00:00:58 12-24 to 14:01:17 12-24)
  1920.  
  1921.   Grand Total = 1233260 (08:01:10 12-22 to 14:01:17 12-24)
  1922.   
  1923. .B2
  1924. .fi
  1925. .KE
  1926.  
  1927. The following is an example of the corresponding non-verbose
  1928. format:
  1929.  
  1930. .KS
  1931. .nf
  1932. .B1
  1933.  
  1934.   File: 35.1.1.21-IP.lens.1221.1523
  1935.  
  1936.   Log created on Tue Dec 22 08:00:25 1987, for host 35.1.1.21.
  1937.     Sample interval = 60 min; checkpoint interval = 60 min.
  1938.     Object name = 'IP.lens'.
  1939.  
  1940.   Daily total = 474230 (08:01:10 12-22 to 00:00:55 12-23)
  1941.   Daily total = 576622 (00:00:55 12-23 to 00:00:58 12-24)
  1942.   Daily total = 182408 (00:00:58 12-24 to 14:01:17 12-24)
  1943.  
  1944.   Grand Total = 1233260 (08:01:10 12-22 to 14:01:17 12-24)
  1945.  
  1946. .B2
  1947. .fi
  1948. .KE
  1949.  
  1950.  
  1951. In the verbose format, column headings have the following meanings:
  1952.  
  1953. .IP o
  1954. \*QRead-Time\*U contains the ReadTime
  1955. returned from each
  1956. .B statspy
  1957. response to a query performed by
  1958. .B collect.
  1959.  
  1960. .IP o
  1961. \*QClear-Time\*U is filled in for each new 
  1962. ClearTime found in the current log file being processed.  A blank
  1963. Clear-Time field signifies that the field is unchanged since the previous
  1964. entry. 
  1965.  
  1966. .IP o
  1967. \*QTotal-Count\*U corresponds to the \*QTotalCount\*U on each
  1968. response.
  1969.   
  1970. .IP o
  1971. \*QIncrement\*U contains the number of packets counted
  1972. between the current response and the previous response.
  1973. .LP
  1974.                            
  1975. .NH 3
  1976. Bin-totals
  1977. .LP
  1978.  
  1979. The command 
  1980. .B bin-totals
  1981. produces a summary showing the total number of packets counted in each of the
  1982. corresponding bins appearing in a log file, taking into account any 
  1983. .B statspy
  1984. restarts or object clears.
  1985. It can be invoked on a list of log files
  1986. to summarize each independently.
  1987.  
  1988. The command to invoke 
  1989. .B bin-totals
  1990. is:
  1991.  
  1992.     \fBbin-totals \fIlogfile\fR ...
  1993.     
  1994. As before, the parameter is a list of name(s) of one or more log files produced
  1995. by the 
  1996. .B collect
  1997. program, or a wildcard file specification that matches
  1998. (only) files produced by the 
  1999. .B collect
  2000. program.
  2001. Output is written to a results file named \*Qbin-totals.out,\*U
  2002. as well as to the standard output.
  2003.   
  2004. The following is an example of the output from the 
  2005. .B bin-totals
  2006. command:
  2007.  
  2008. .KS
  2009. .nf
  2010. .B1
  2011.  
  2012.   File: 35.1.1.21-IP.lens.1221.1523
  2013.  
  2014.   Log created on Tue Dec 22 08:00:25 1987, for host 35.1.1.21.
  2015.     Sample interval = 60 min; checkpoint interval = 60 min.
  2016.     Object name = 'IP.lens'.
  2017.  
  2018.   Summary Period: 08:01:10 12-22 to 14:01:17 12-24.
  2019.  
  2020.     [0-9] total = 0
  2021.     [10-19] total = 0
  2022.     [20-39] total = 1112
  2023.     [40-79] total = 557177
  2024.     [80-159] total = 149395
  2025.     [160-319] total = 194274
  2026.     [320-639] total = 61625
  2027.     [640-1279] total = 192769
  2028.     [1280-2559] total = 76908
  2029.     [2560-5119] total = 0
  2030.  
  2031. .B2
  2032. .fi
  2033. .KE
  2034.  
  2035. .bp                        
  2036. .SH
  2037. Appendix A -- Catalog of Objects
  2038. .LP
  2039.  
  2040. This Appendix describes the statistical object classes currently implemented
  2041. in \fBstatspy\fP.
  2042.  
  2043. .SH 2
  2044. Recorder Objects
  2045. .LP
  2046.  
  2047. A recorder object is invoked at its Write() entry point to record values
  2048. of a specific field or set of fields.
  2049.  
  2050. .IP 1.
  2051. Frequency of all Values
  2052.  
  2053.       \fBfreq-all\fP 
  2054.  
  2055. An object of class \fIfreq-all\fP (abbreviated as \fIFA\fP) builds a
  2056. frequency distribution table for a single field.  This table is built
  2057. dynamically, with a bin for every distinct value that occurs.
  2058.  
  2059. Each time a bin is added or incremented, the current time (in seconds
  2060. since Jan 1, 1970) is recorded in the bin.  A read operation returns this
  2061. last-update time with the value and count for each bin.  We expect that
  2062. these times will be useful in analysis of the data; for example, it
  2063. would be possible to extract only recently occuring values.
  2064.  
  2065. The list of bins returned by a read operation is sorted into order
  2066. of decreasing counts, and within the same count, by last update time.
  2067.  
  2068. The implementation of the \fIfreq-all\fP class uses a chained hash
  2069. scheme, dynamically allocating memory for bins in \*Qpages\*U of 2K
  2070. bytes.  There is a built-in limit of 1024 bins.  In addition to the hash
  2071. chain, each bin is chained into a doubly-linked sorted list that is
  2072. used to order the read sequence.  Sorting
  2073. bins into this list is accomplished using an incremental algorithm whose
  2074. CPU time is linear in the total count (and is in fact negligible).
  2075.  
  2076. .bp
  2077. .IP 2.
  2078. Frequency of selected set of values
  2079.  
  2080.       \fBfreq-only ( <value>, ... <value> ) \fP
  2081.  
  2082. An object of class \fIfreq-only\fP (abbreviated as \fIFO\fP) builds a
  2083. frequency distribution table for only those values that are included in
  2084. the parameter list; values not in the list are counted in a single
  2085. \*QOther\*U bin.  A read operation on the object displays this
  2086. frequency table and the \*QOther\*U count.  If the given set of values is
  2087. empty, the \*QOther\*U count equals the total number of invocations.
  2088.  
  2089. The <value> entries may be expressed in a variety of ways.
  2090.  
  2091. .RS
  2092. .IP o
  2093. Decimal integer, limited to 2**31 maximum.
  2094.  
  2095. .IP o
  2096. Hex integer, using the \*QC\*U notation 0x....
  2097.  
  2098. .IP o
  2099. IP address, specified as either a dotted-decimal
  2100. number or as a domain name.
  2101.  
  2102. .IP o
  2103. Ethernet Address, specified in \*Qcoloned-hex\*U format:
  2104. xx:xx:xx:xx:xx:xx, where each x represents a hex digit.
  2105.  
  2106. .IP o
  2107. A  quoted enumeration label: \*Q<label>\*U.  This implies
  2108. the corresponding value, and
  2109. provides a way to define field values symbolically.  See
  2110. Appendix C for examples.
  2111. .RE
  2112. .LP
  2113.  
  2114. .bp
  2115. .IP 3.
  2116. Frequency of all Value Pairs
  2117.  
  2118.        \fBmatrix-all\fP 
  2119.  
  2120. An object of class \fImatrix-all\fP (abbreviated as \fIMA\fP) builds a
  2121. table of frequencies of all pairs of values in two fields.  This table is
  2122. built dynamically, with a bin for every distinct value pair that occurs.
  2123. The pair of values (a,b) is counted separately from the pair (b,a).  
  2124. The list of bins returned by a read operation is sorted into
  2125. order of decreasing counts, and within the same count, by last update time.
  2126.  
  2127. The internal structure and implementation of this class is the same as the
  2128. \fIfreq-all\fP class, described above.
  2129.  
  2130. If the object name matches an enumeration, the corresponding labels
  2131. are used for the first value of each pair.
  2132.  
  2133. Note: if a \fImatrix-all\fP object is defined with a non-zero parameter, it
  2134. operates as a \fImatrix-sym\fP object (see following).
  2135.  
  2136. .IP 4.
  2137. Symmetric Frequency of Value Pairs
  2138.  
  2139.        \fBmatrix-sym\fP
  2140.  
  2141. An object of class \fImatrix-sym\fP (abbreviated as \fIMS\fP) builds a
  2142. table of frequencies of all pairs of values in two fields.  This table is
  2143. built dynamically, with a bin for every distinct value pair that occurs.
  2144. The list of bins returned by a read operation is sorted in order
  2145. of decreasing counts, and within the same count, by last update time.
  2146.  
  2147. If the two argument fields have the same length, they are
  2148. treated \*Qsymmetrically\*U:  (b,a) and (a,b) are counted in the same bin.
  2149. If the lengths differ, \fImatrix-sym\fP operates like \fImatrix-all\fP.
  2150.  
  2151. The internal structure and implementation of this class is the same as the
  2152. \fImatrix-all\fP class, described above.
  2153.  
  2154. If the object name matches an enumeration, the corresponding labels
  2155. are used for the first value of each pair.
  2156. .bp
  2157. .IP 5.
  2158. Histogram
  2159.  
  2160.       \fBhist ( <scale factor> [, <max bin>] )\fP
  2161.     
  2162. An object of class \fIhist\fP (abbreviated as \fIHI\fP) 
  2163. builds a linear histogram of (unsigned)
  2164. integer field values. Each bin of the histogram has the same size,
  2165. given by the value <scale factor>. 
  2166. The optional second parameter specifies the ordinal number of the
  2167. maximum bin that is collected; if it is omitted, 1024 is used.
  2168.  
  2169. If <scale factor> is S and
  2170. <max bin> is M, a Read operation on the object defined by hist(S, M)
  2171. returns the counts:
  2172.  
  2173. .KS
  2174.     Bin 0:  Count( 0 <= X < S )
  2175.     ...
  2176.     Bin j:  Count( j*S <= X < (J+1)*S )
  2177.     ...
  2178.     Bin M:  Count( M*S <= X < (M+1)*S )
  2179. .KE
  2180.     
  2181. plus a count of values that were off-scale, i.e., >= (M+1)*S.
  2182. Here \*QCount(\ f(X)\ )\*U means the number of invocations with
  2183. value X for which f(X) was true.
  2184.  
  2185. The Read operation also reports the average, maximum, and minimum
  2186. values observed.
  2187. A \fIhist\fP object is restricted to invocation on a field of 4 bytes or less.
  2188.  
  2189. .IP 6.
  2190. Logarithmic Histogram
  2191.  
  2192.       \fBhist-pwr2 ( <scale factor> )\fP
  2193.  
  2194. An object of class \fIhist-pwr2\fP (abbreviated as \fIP2\fP) 
  2195. builds a logarithmic histogram, i.e, one with intervals
  2196. increasing as powers of 2.  Specifically, a Read()
  2197. operation on a \fIhist-pwr2\fP object returns the following counts:
  2198.  
  2199. .KS
  2200.     Bin 0:  Count(X < S)
  2201.     
  2202.     Bin 1:  Count(S <= X < 2*S)
  2203.     ...
  2204.     Bin j:  Count(S*(2**j) <= X < S*(2**(j+1)) )
  2205. .KE
  2206.     
  2207. where S is the value of the unsigned integer <scale factor>.
  2208.  
  2209. A \fIhist-pwr2\fP object also reports the average, maximum, and minimum values
  2210. observed.
  2211. A \fIhist\fP object is restricted to invocation on a field of 4 bytes or less.
  2212.  
  2213. .IP 7.
  2214. Measure Temporal Locality of Reference
  2215.   
  2216.        \fBworking-set\fP
  2217.  
  2218. An object of class \fIworking-set\fP (abbreviated as \fIWS\fP) measures the degree of 
  2219. temporal clustering of values of a given field.  This clustering is
  2220. known as \*Qlocality of reference\*U, and in the memory domain leads to the
  2221. concept of a \fIworking set\fP.
  2222.  
  2223. Suppose we keep the set of n 
  2224. distinct values that have occurred most recently in
  2225. the field.  This set will change over time, as new values occur that were
  2226. not in the set replace the oldest (\*Qleast-recently used\*U) values in the set.
  2227. Let C(n) be the number of new values in the observed sequence that 
  2228. replace values already in the set. If there have been a total of N packets
  2229. in the sequence, C(n)/N is the probability of a new value falling outside
  2230. the set.  
  2231.  
  2232. The \fIworking-set\fP object measures the values of C(1), C(2), C(4), C(8),...
  2233. C(4096). 
  2234.  
  2235. .IP 8.
  2236. Record Sequence of Values in Binary
  2237.  
  2238.         \fBbin-pkt ( <max> )\fP 
  2239.  
  2240. An object of class \fIbin-pkt\fP (abbreviated as \fIBP\fP) 
  2241. builds a circular buffer of <max> entries, containing the
  2242. most recent values in a specified field.
  2243. A read operation on the object displays all
  2244. values in this buffer, oldest first.
  2245.  
  2246. Although this object may be invoked from any field, it is really intended
  2247. for recording the complete headers (up to 63 bytes) of packets.
  2248. For this purpose, the virtual field \*Qpacket\*U is defined 
  2249. (see Section 3.3.1).
  2250. Normally, a \fIbin-pkt\fP object invocation will be under control of
  2251. filter object(s) to record selected packets for diagnostic purposes.
  2252.  
  2253. .IP 9.
  2254. Variant of \fIfreq-all\fP
  2255.  
  2256.          \fBfreq-all2\fP  
  2257.  
  2258. An object of class \fIfreq-all2\fP (abbreviated as \fIFA2\fP) performs
  2259. the same function as an object of the \fIfreq-all\fP class, except a
  2260. \fIfreq-all2\fP objects does not sort the list of bins, but rather
  2261. displays bins in the order of their first occurrence.  As a result,
  2262. \fIfreq-all2\fP objects may use sligntly less CPU time (although the
  2263. difference appears to be negligible) and always use less memory for bins
  2264. (16-20 bytes per bin, compared to 24-28 bytes for \fIfreq-all\fP objects.)
  2265.  
  2266. .IP 10.
  2267. Variant of \fImatrix-all\fP
  2268.  
  2269.         \fB matrix-all2\fP 
  2270.  
  2271. An object of class \fImatrix-all2\fP (abbreviated  as \fIMA2\fP) performs
  2272. the same function as an object of the \fImatrix-all\fP class, except a
  2273. \fImatrix-all2\fP objects does not sort the list of bin, but rather
  2274. displays bins in the order of their first occurrence.  As a result,
  2275. \fImatrix-all2\fP objects may use slightly less CPU time (although the
  2276. difference appears to be negligible) and always use less memory for bins
  2277. (16-24 bytes per bin, compared to 24-32 bytes for \fImatrix-all\fP
  2278. objects.)
  2279.  
  2280. .bp
  2281. .SH 2
  2282. Filter Objects
  2283. .LP
  2284.  
  2285. A filter object tests given field values against some criterion and
  2286. returns a Boolean value; the interpreter uses this result to select one
  2287. of two alternative sequences of invocations.
  2288.  
  2289. A filter object generally has a read-only data structure, but it does
  2290. keep two statistical counters: the total number of invocations, and
  2291. the number that resulted in a TRUE result.  These two numbers are
  2292. returned by a Read operation.
  2293.  
  2294. .IP 1.
  2295. Filter on range of values
  2296.  
  2297.        \fBrangef ( <Lower>, <Upper>)\fP 
  2298.    
  2299. A \fIrangef\fP object (abbreviated as \fIRF\fP)
  2300. returns TRUE if the given value X falls inside the
  2301. specified range:
  2302.  
  2303.        L <= X <= U,
  2304.      
  2305. otherwise it returns FALSE.  
  2306. Here L and U are the unsigned integer values corresponding to <Lower>
  2307. and <Upper>, respectively.
  2308.  
  2309. .mc |
  2310. .IP 2.
  2311. Filter on equality
  2312.  
  2313.        \fBeqf( <value> )\fP
  2314.        
  2315. An \fIeqf\fP object (abbreviated as \fIEQ\fP)
  2316. returns TRUE if the given field value matches the
  2317. specified parameter value, otherwise it returns false.
  2318. Here <value> may take any of the forms described earlier for
  2319. the \fIfreq-only\fP class.
  2320.  
  2321. .mc
  2322. .IP 3
  2323. Filter on selected set of values
  2324.  
  2325.        \fBsetf ( <value>, ... <value> )\fP 
  2326.    
  2327. A \fIsetf\fP object (abbreviated as \fISF\fP)
  2328. returns TRUE if the given field value matches one of the
  2329. values in the parameter list, otherwise it returns FALSE.
  2330. Each <value> may take any of the forms described earlier for
  2331. the \fIfreq-only\fP class.
  2332.  
  2333. .mc |
  2334. Note that setf with a single value is equivalent to eqf, but is
  2335. much less efficient.
  2336. .LP
  2337.  
  2338. .mc
  2339. .bp
  2340. .SH
  2341. Appendix B -- Syntax of Attach Command
  2342. .LP
  2343.  
  2344. This Appendix contains a BNF specification of the \fIattach\fP command syntax.
  2345.  
  2346. The syntax of Attach parameters has been (deliberately) designed to parallel
  2347. the syntax of \*QC\*U statements (that correspond to simple invocations) and
  2348. statement-lists (that correspond to lists of invocations).
  2349.  
  2350.  
  2351.   <Attach command> ::= attach { <S-list> }
  2352.      
  2353.  
  2354.   <S-list> ::= <Statement> | <S-list> <Statement>
  2355.      
  2356.  
  2357.   <Statement> ::= record <record-invoke> ; |
  2358.  
  2359.           if <if-invoke> <Statement> else <Statement> |
  2360.           
  2361.           if <if-invoke> <Statement> |
  2362.                          
  2363.           { <S-list> }   |  ;
  2364.                   
  2365.                   
  2366.   <record-invoke> ::= <field name> in <object defn>  |
  2367.      
  2368.                <field name>, <field name> in <object defn> 
  2369.      
  2370.                     
  2371.   <if-invoke> ::=     <field name> is <object defn>  |
  2372.  
  2373.                <field name> isnot <object defn>
  2374.                          
  2375.                     
  2376.   <object defn> ::=   <object name> <class> <class parm> |
  2377.       
  2378.                <class> <class parm> | 
  2379.  
  2380.                <object name> 
  2381.  
  2382.  
  2383.   <class parm> ::=  <empty> | ( <value list> )  
  2384.  
  2385.   <value list> ::= <empty> | <value list> <value> 
  2386.  
  2387.   <value> ::= <decimal integer> |
  2388.      
  2389.                0x<hex number>  |  0X<hex number>  |
  2390.                  
  2391.                <IP address>  |
  2392.                                   
  2393.                <Ethernet address> |
  2394.                  
  2395.                \*Q<label>\*U
  2396.                  
  2397.   <IP address> ::= 
  2398.                  
  2399.                <dotted-decimal number> |
  2400.                  
  2401.                <host domain name>
  2402.                  
  2403.   <Ethernet address> ::=
  2404.                       
  2405.                 <hex digit>:<hex digit>:<hex digit>:
  2406.                      <hex digit>:<hex digit>:<hex digit>
  2407.                                          
  2408.   <hex number> ::= <hex digit>  |  <hex number><hex digit>
  2409.       
  2410.   <hex digit> ::= 00 | 01 | ... | fe | ff           
  2411.                  
  2412.   <field name> ::= <identifier> 
  2413.         
  2414.   <object name> ::= <identifier>    
  2415.  
  2416.   <identifier> ::= a letter, followed by: any string of
  2417.                    letters, digits, or any of the 
  2418.                    special characters +-&._
  2419.  
  2420. .bp
  2421. .SH
  2422. Appendix C -- Building Configuration Files
  2423. .LP
  2424.  
  2425. This Appendix provides some guidelines, suggestions, and examples for building
  2426. .B statspy
  2427. configurations.
  2428.  
  2429. .IP "Example A."
  2430.  
  2431. Traffic flowing to and from a particular gateway can be selected 
  2432. with a filter:
  2433.  
  2434. attach {
  2435.     if Ether.dst is eqf(08:00:2b:03:4a:e7) { 
  2436.           ####going to gateway
  2437.        record ... ;
  2438.        record ... ;
  2439.        ...
  2440.        }
  2441.     if Ether.src is eqf(08:00:2b:03:4a:e7) {  
  2442.           ####coming from gateway
  2443.        record ... ;
  2444.        record ... ;
  2445.        ...
  2446.        }
  2447.     }
  2448.  
  2449. where 08:00:2b:03:4a:e7 is the Ethernet address of the gateway.  
  2450. (Note the convention for Ethernet addresses: \*Qcoloned-hex\*U).
  2451.  
  2452. .IP "Example B."
  2453.  
  2454. Another filtering approach is to select packets by classes of IP
  2455. addresses.  For example, suppose it is known that the list 128.1.0.0,
  2456. 128.2.0.0, and 128.3.0.0 includes all local networks.  In that case, the
  2457. following selects \*Qtransit\*U packets, i.e., packets whose source and
  2458. destination are both outside the local administrative area:
  2459.  
  2460.   if IP.srcnet isnot 
  2461.               setf(128.1.0.0, 128.2.0.0, 128.3.0.0)
  2462.        if IP.dstnet isnot
  2463.               setf(128.1.0.0, 128.2.0.0, 128.3.0.0) {
  2464.            record ... ;
  2465.            record ... ;
  2466.               ...
  2467.         }
  2468.             
  2469. .B Statspy 
  2470. has been designed to be efficient even if the list of values
  2471. used as parameters to \fIsetf\fP() is very large (say, several hundred
  2472. values) -- a \fIsetf\fP object uses a hash-table. 
  2473.  
  2474. .IP "Example C."
  2475.  
  2476. Suppose the problem is to collect data on all TCP traffic destined
  2477. for a particular gateway, broken down by source and destination IP addresses
  2478. as well as packet type (Telnet, FTP, etc.).
  2479.  
  2480. Here, \*Qpacket type\*U is a little bit hazy, but it is related to the
  2481. occurrence of a well-known port number in the TCP source or destination
  2482. port.
  2483.  
  2484. In principle, there is no reason why
  2485. .B statspy
  2486. could not provide for three-way distributions, but it does not.  One of
  2487. the main reasons (besides distaste for the resulting messiness in the
  2488. specifications and code) for not implementing three-way distributions is
  2489. disbelief that administrators will want all that data!  Running
  2490. .B statspy
  2491. 12 hours on a typical large Ethernet has found packets to/from 100
  2492. networks and 500 different IP hosts.  The complete three-way matrix asked
  2493. for here may therefore contain 10**6 bins.  It seems unlikely that anyone
  2494. will have use for a million numbers, accumulated over days, weeks, and
  2495. months!
  2496.  
  2497. In fact, it seems doubtful that even the hardiest administrator will
  2498. really want to keep complete statistics by (IP source, IP destination)
  2499. host pairs; after a few months of looking at 10**5 numbers, he/she will
  2500. tire of it and begin to collect data only on source and destination
  2501. network, or only for specific subsets of networks.
  2502.  
  2503. The 
  2504. .B statspy
  2505. design includes a number of features to contain the
  2506. amount of data it can generat, for example the inclusion of IP network
  2507. numbers distinct from host numbers, the conditional (filter)
  2508. mechanism, and the \fIsetf\fP() filter described above. 
  2509.  
  2510. The recommended approach to using NNStat is as follows: set up some simple,
  2511. general overall statistical measures, producing a volume of data that 
  2512. can reasonably be scanned.  If some apparent anomalies are observed --
  2513. e.g., a
  2514. particular network seems to be producing more packets than expected --
  2515. then augment the configuration for 24 hours with specific
  2516. objects to analyze exactly those anomalous data.
  2517.  
  2518. In any case, the following command sets up a configuration to
  2519. provide counts broken down by source address, destination address,
  2520. and packet type.
  2521.  
  2522. .KS
  2523. .nf
  2524.  attach {
  2525.  
  2526.    if TCP.dstport is  setf(23, 43, 79, 513) 
  2527.       record IP.srchost, IP.dsthost in Telnet.hosts matrix-sym;
  2528.    else if TCP.srcport is  setf(23, 43, 79, 513)
  2529.       record IP.srchost, IP.dsthost in Telnet.hosts;
  2530.       
  2531.    else if TCP.dstport is  setf(20, 21, 69) 
  2532.       record IP.srchost IP.dsthost in ftp.hosts matrix-sym;
  2533.    else if TCP.srcport is  setf(20, 21, 69) 
  2534.       record IP.srchost IP.dsthost in ftp.hosts;
  2535.     
  2536.    else if TCP.dstport is  setf(25, 103, 104, 119) 
  2537.       record IP.srchost IP.dsthost in mail.hosts matrix-sym;
  2538.    else if TCP.srcport is  setf(25, 103, 104, 119)
  2539.       record IP.srchost IP.dsthost in mail.hosts;
  2540.  }
  2541. .KE
  2542. .fi
  2543.  
  2544. .mc |
  2545. We can avoid replicating the parameter lists to the setf objects by
  2546. naming the first occurrence of each case and referencing the same
  2547. object in later occurrences, as shown by following:
  2548.  
  2549. .KS
  2550. .nf
  2551.  attach {
  2552.  
  2553.    if TCP.dstport is  port.telnet  setf(23, 43, 79, 513) 
  2554.       record IP.srchost, IP.dsthost in Telnet.hosts matrix-sym;
  2555.    else if TCP.srcport is  port.telnet
  2556.       record IP.srchost, IP.dsthost in Telnet.hosts;
  2557.       
  2558.    else if TCP.dstport is  port.ftp  setf(20, 21, 69) 
  2559.       record IP.srchost IP.dsthost in ftp.hosts matrix-sym;
  2560.    else if TCP.srcport is  port.ftp 
  2561.       record IP.srchost IP.dsthost in ftp.hosts;
  2562.     
  2563.    else if TCP.dstport is  port.mail  setf(25, 103, 104, 119) 
  2564.       record IP.srchost IP.dsthost in mail.hosts matrix-sym;
  2565.    else if TCP.srcport is  port.mail
  2566.       record IP.srchost IP.dsthost in mail.hosts;
  2567.  }
  2568. .KE
  2569. .fi
  2570.  
  2571. Using symbolic label defined by an \fIenum\fP command, we can write this as:
  2572.  
  2573. .KS
  2574. .nf
  2575.  enum {
  2576.   *port* (20 \*QFTP data\*U, 21 FTP, 23 Telnet, 25 SMTP,
  2577.      37 Time, 42 Name, 43 Whois, 53 Domains, 
  2578.      69 TFTP, 79 Finger, 103 X.400, 104 \*QX.400-SND\*U,
  2579.      109 POP2, 111 sunrpc, 115 SFTP, 119 NetNews, 
  2580.      153 SGMP, 512 exec, 513 \*Qrwho|rlogin\*U, 514 shell,
  2581.      515 printer, 520 RIP)       
  2582.  }
  2583.  
  2584.  attach {
  2585.    if TCP.dstport is port.telnet 
  2586.               setf(\*QTelnet\*U, \*QWhois\*U, \*QFinger\*U, \*Qrwho|rlogin\*U)
  2587.         record IP.srchost, IP.dsthost in Telnet.hosts matrix-sym;
  2588.         
  2589.    else if TCP.srcport is port.telnet 
  2590.         record IP.srchost, IP.dsthost in Telnet.hosts;
  2591.       
  2592.    else if TCP.dstport is port.ftp setf(\*QFTP data\*U, \*QFTP\*U, \*QTFTP\*U) 
  2593.         record IP.srchost IP.dsthost in ftp.hosts matrix-sym;
  2594.         
  2595.    else if TCP.srcport is port.ftp 
  2596.         record IP.srchost IP.dsthost in ftp.hosts;
  2597.       
  2598.    else if TCP.dstport is port.mail 
  2599.               setf(\*QSMTP\*U, \*QX.400\*U, \*QX.400-SND\*U, \*QNetNews\*U) 
  2600.         record IP.srchost IP.dsthost in mail.hosts matrix-sym;
  2601.         
  2602.    else if TCP.srcport is port.mail
  2603.         record IP.srchost IP.dsthost in mail.hosts;
  2604.  }
  2605. .KE
  2606. .fi
  2607.  
  2608. .mc
  2609. Now, all this needs to be conditional upon packets coming and going
  2610. through a specific gateway.  This requires a very redundant configuration
  2611. file, but the good news is that the redundancy does not effect either the
  2612. CPU time or memory space required for data collection.  
  2613. Assuming the \fIenum\fP command of the previous example, the
  2614. complete \fIattach\fP command can be written as:
  2615. .mc |
  2616. .KS
  2617. .nf
  2618.  attach {
  2619.  
  2620.  if  Ether.src is eqf(08:00:2b:03:4a:e7) { 
  2621.    if TCP.dstport is port.telnet 
  2622.               setf(\*QTelnet\*U, \*QWhois\*U, \*QFinger\*U, \*Qrwho|rlogin\*U)
  2623.         record IP.srchost, IP.dsthost in Telnet.hosts matrix-sym;
  2624.         
  2625.    else if TCP.srcport is port.telnet               
  2626.         record IP.srchost, IP.dsthost in Telnet.hosts;
  2627.         
  2628.    else if TCP.dstport is port.ftp setf(\*QFTP data\*U, \*QFTP\*U, \*QTFTP\*U) 
  2629.         record IP.srchost IP.dsthost in ftp.hosts matrix-sym;
  2630.         
  2631.    else if TCP.srcport is port.ftp  
  2632.         record IP.srchost IP.dsthost in ftp.hosts;
  2633.       
  2634.    else if TCP.dstport is port.mail 
  2635.               setf(\*QSMTP\*U, \*QX.400\*U, \*QX.400-SND\*U, \*QNetNews\*U) 
  2636.         record IP.srchost IP.dsthost in mail.hosts matrix-sym;
  2637.         
  2638.    else if TCP.srcport is port.mail 
  2639.         record IP.srchost IP.dsthost in mail.hosts;
  2640.  }
  2641.  if  Ether.dst is eqf(08:00:2b:03:4a:e7) { 
  2642.    if TCP.dstport is port.telnet 
  2643.         record IP.srchost, IP.dsthost in Telnet.hosts matrix-sym;
  2644.         
  2645.    else if TCP.srcport is port.telnet 
  2646.         record IP.srchost, IP.dsthost in Telnet.hosts;
  2647.       
  2648.    else if TCP.dstport is port.ftp  
  2649.         record IP.srchost IP.dsthost in ftp.hosts matrix-sym;
  2650.         
  2651.    else if TCP.srcport is port.ftp 
  2652.         record IP.srchost IP.dsthost in ftp.hosts;
  2653.       
  2654.    else if TCP.dstport is port.mail 
  2655.         record IP.srchost IP.dsthost in mail.hosts matrix-sym;
  2656.         
  2657.    else if TCP.srcport is port.mail 
  2658.         record IP.srchost IP.dsthost in mail.hosts;
  2659.   }
  2660.  }
  2661. .KE
  2662. .fi
  2663. .mc
  2664.  
  2665.  
  2666.   
  2667.