Initial import from FreeBSD RELENG_4:
[games.git] / usr.sbin / atm / scspd / scsp_print.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/usr.sbin/atm/scspd/scsp_print.c,v 1.3 1999/08/28 01:15:34 peter Exp $
27  *
28  */
29
30
31 /*
32  * Server Cache Synchronization Protocol (SCSP) Support
33  * ----------------------------------------------------
34  *
35  * Print routines
36  *
37  */
38
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/socket.h>
42 #include <net/if.h>
43 #include <netinet/in.h>
44 #include <netatm/port.h> 
45 #include <netatm/queue.h> 
46 #include <netatm/atm.h>
47 #include <netatm/atm_if.h>
48 #include <netatm/atm_sap.h>
49 #include <netatm/atm_sys.h>
50 #include <netatm/atm_ioctl.h>
51   
52 #include <errno.h>
53 #include <libatm.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <syslog.h>
58 #include <unistd.h>
59
60 #include "scsp_msg.h"
61 #include "scsp_if.h"
62 #include "scsp_var.h"
63
64 #ifndef lint
65 __RCSID("@(#) $FreeBSD: src/usr.sbin/atm/scspd/scsp_print.c,v 1.3 1999/08/28 01:15:34 peter Exp $");
66 #endif
67
68
69 /*
70  * Indent string
71  */
72 #define MIN_INDENT      2
73 #define MAX_INDENT      64
74 static char     indent[MAX_INDENT + 1];
75
76
77 /*
78  * Value-name translation table entry
79  */
80 struct type_name {
81         char    *name;
82         u_char  type;
83 };
84 typedef struct type_name        Type_name;
85
86
87 /*
88  * SCSP name-type tables
89  */
90 static Type_name if_msg_types[] = {
91         { "Config Request",             SCSP_CFG_REQ },
92         { "Config Response",            SCSP_CFG_RSP },
93         { "Cache Indication",           SCSP_CACHE_IND },
94         { "Cache Response",             SCSP_CACHE_RSP },
95         { "Solicit Indication",         SCSP_SOLICIT_IND },
96         { "Solicit Response",           SCSP_SOLICIT_RSP },
97         { "Cache Update Indication",    SCSP_UPDATE_IND },
98         { "Cache Update Request",       SCSP_UPDATE_REQ },
99         { "Cache Update Response",      SCSP_UPDATE_RSP },
100         { (char *)0,    0 }
101 };
102
103 static Type_name msg_types[] = {
104         { "Cache Alignment",    SCSP_CA_MSG },
105         { "CSU Request",        SCSP_CSU_REQ_MSG },
106         { "CSU Reply",          SCSP_CSU_REPLY_MSG },
107         { "CSU Solicit",        SCSP_CSUS_MSG },
108         { "Hello",              SCSP_HELLO_MSG },
109         { (char *)0,            0 }
110 };
111
112 static Type_name proto_types[] = {
113         { "ATMARP",     SCSP_PROTO_ATMARP },
114         { "NHRP",       SCSP_PROTO_NHRP },
115         { "MARS",       SCSP_PROTO_MARS },
116         { "DHCP",       SCSP_PROTO_DHCP },
117         { "LNNI",       SCSP_PROTO_LNNI },
118         { (char *)0,    0 }
119 };
120
121 static Type_name ext_types[] = {
122         { "End of Extensions",  SCSP_EXT_END },
123         { "Authentication",     SCSP_EXT_AUTH },
124         { "Vendor Private",     SCSP_EXT_VENDOR },
125         { (char *)0,            0 }
126 };
127
128 static Type_name hfsm_state_names[] = {
129         { "Down",               SCSP_HFSM_DOWN },
130         { "Waiting",            SCSP_HFSM_WAITING },
131         { "Unidirectional",     SCSP_HFSM_UNI_DIR },
132         { "Bidirectional",      SCSP_HFSM_BI_DIR },
133         { (char *)0,            0 }
134 };
135
136 static Type_name hfsm_event_names[] = {
137         { "VC open",            SCSP_HFSM_VC_ESTAB },
138         { "VC closed",          SCSP_HFSM_VC_CLOSED },
139         { "Hello timer",        SCSP_HFSM_HELLO_T },
140         { "Receive timer",      SCSP_HFSM_RCV_T },
141         { "Msg received",       SCSP_HFSM_RCVD },
142         { (char *)0,            0 }
143 };
144
145 static Type_name cafsm_state_names[] = {
146         { "Down",                       SCSP_CAFSM_DOWN },
147         { "Master/Slave negotiation",   SCSP_CAFSM_NEG },
148         { "Master",                     SCSP_CAFSM_MASTER },
149         { "Slave",                      SCSP_CAFSM_SLAVE },
150         { "Update cache",               SCSP_CAFSM_UPDATE },
151         { "Aligned",                    SCSP_CAFSM_ALIGNED },
152         { (char *)0,                    0 }
153 };
154
155 static Type_name cafsm_event_names[] = {
156         { "Hello FSM up",               SCSP_CAFSM_HELLO_UP },
157         { "Hello FSM down",             SCSP_CAFSM_HELLO_DOWN },
158         { "CA received",                SCSP_CAFSM_CA_MSG },
159         { "CSU Solicit received",       SCSP_CAFSM_CSUS_MSG },
160         { "CSU Request received",       SCSP_CAFSM_CSU_REQ },
161         { "CSU Reply received",         SCSP_CAFSM_CSU_REPLY },
162         { "CA timer",                   SCSP_CAFSM_CA_T },
163         { "CSUS timer",                 SCSP_CAFSM_CSUS_T },
164         { "CSU timer",                  SCSP_CAFSM_CSU_T },
165         { "Cache Update",               SCSP_CAFSM_CACHE_UPD },
166         { "Cache Response",             SCSP_CAFSM_CACHE_RSP },
167         { (char *)0,                    0 }
168 };
169
170 static Type_name cifsm_state_names[] = {
171         { "Null",       SCSP_CIFSM_NULL },
172         { "Summarize",  SCSP_CIFSM_SUM },
173         { "Update",     SCSP_CIFSM_UPD },
174         { "Aligned",    SCSP_CIFSM_ALIGN },
175         { (char *)0,                    0 }
176 };
177
178 static Type_name cifsm_event_names[] = {
179         { "CA FSM down",        SCSP_CIFSM_CA_DOWN },
180         { "CA FSM to Summarize",SCSP_CIFSM_CA_SUMM },
181         { "CA FSM to Update",   SCSP_CIFSM_CA_UPD },
182         { "CA FSM to Aligned",  SCSP_CIFSM_CA_ALIGN },
183         { "Solicit Rsp",        SCSP_CIFSM_SOL_RSP },
184         { "Update Req",         SCSP_CIFSM_UPD_REQ },
185         { "Update Rsp",         SCSP_CIFSM_UPD_RSP },
186         { "CSU Request",        SCSP_CIFSM_CSU_REQ },
187         { "CSU Reply",          SCSP_CIFSM_CSU_REPLY },
188         { "CSU Solicit",        SCSP_CIFSM_CSU_SOL },
189         { (char *)0,                    0 }
190 };
191
192 static Type_name atmarp_state_names[] = {
193         { "New",        SCSP_ASTATE_NEW },
194         { "Updated",    SCSP_ASTATE_UPD },
195         { "Deleted",    SCSP_ASTATE_DEL },
196         { (char *)0,    0 }
197 };
198
199
200 /*
201  * Initialize the indent string
202  *
203  * Arguments:
204  *      none
205  *
206  * Returns:
207  *      none
208  *
209  */
210 static void
211 init_indent()
212 {
213         indent[0] = '\0';
214 }
215
216
217 /*
218  * Increment the indent string
219  *
220  * Arguments:
221  *      none
222  *
223  * Returns:
224  *      none
225  *
226  */
227 static void
228 inc_indent()
229 {
230         if (strlen(indent) >= MAX_INDENT)
231                 return;
232         strcat(indent, "  ");
233 }
234
235
236 /*
237  * Decrement the indent string
238  *
239  * Arguments:
240  *      none
241  *
242  * Returns:
243  *      none
244  *
245  */
246 static void
247 dec_indent()
248 {
249         if (strlen(indent) < MIN_INDENT)
250                 return;
251         indent[strlen(indent) - 2] = '\0';
252 }
253
254
255
256 /*
257  * Search for a type in a name-type table
258  *
259  * Arguments:
260  *      type    the value being searched for
261  *      tbl     pointer to the table to search
262  *
263  * Returns:
264  *      pointer to a string identifying the type
265  *
266  */
267 static char *
268 scsp_type_name(type, tbl)
269         u_char  type;
270         Type_name       *tbl;
271 {
272         int     i;
273
274         /*
275          * Search the table
276          */
277         for (i = 0; tbl[i].name != (char *)0 && tbl[i].type != type;
278                         i++)
279                 ;
280
281         /*
282          * Check the result and return the appropriate value
283          */
284         if (tbl[i].name)
285                 return(tbl[i].name);
286         else
287                 return("-");
288 }
289
290
291 /*
292  * Format a Hello FSM state name
293  *
294  * Arguments:
295  *      state   the state
296  *
297  * Returns:
298  *      pointer to a string identifying the state
299  *
300  */
301 char *
302 format_hfsm_state(state)
303         int     state;
304 {
305         return(scsp_type_name((u_char)state, hfsm_state_names));
306 }
307
308
309 /*
310  * Format a Hello FSM event name
311  *
312  * Arguments:
313  *      event   the event
314  *
315  * Returns:
316  *      pointer to a string identifying the event
317  *
318  */
319 char *
320 format_hfsm_event(event)
321         int     event;
322 {
323         char    *cp;
324
325         cp = scsp_type_name((u_char)event, hfsm_event_names);
326         return(cp);
327 }
328
329
330 /*
331  * Format a CA FSM state name
332  *
333  * Arguments:
334  *      state   the state
335  *
336  * Returns:
337  *      pointer to a string identifying the state
338  *
339  */
340 char *
341 format_cafsm_state(state)
342         int     state;
343 {
344         return(scsp_type_name((u_char)state, cafsm_state_names));
345 }
346
347
348 /*
349  * Format a CA FSM event name
350  *
351  * Arguments:
352  *      event   the event
353  *
354  * Returns:
355  *      pointer to a string identifying the event
356  *
357  */
358 char *
359 format_cafsm_event(event)
360         int     event;
361 {
362         return(scsp_type_name((u_char)event, cafsm_event_names));
363 }
364
365
366 /*
367  * Format a client interface FSM state name
368  *
369  * Arguments:
370  *      state   the state
371  *
372  * Returns:
373  *      pointer to a string identifying the state
374  *
375  */
376 char *
377 format_cifsm_state(state)
378         int     state;
379 {
380         return(scsp_type_name((u_char)state, cifsm_state_names));
381 }
382
383
384 /*
385  * Format a client interface FSM event name
386  *
387  * Arguments:
388  *      event   the event
389  *
390  * Returns:
391  *      pointer to a string identifying the event
392  *
393  */
394 char *
395 format_cifsm_event(event)
396         int     event;
397 {
398         return(scsp_type_name((u_char)event, cifsm_event_names));
399 }
400
401
402 /*
403  * Print a Sender or Receiver ID structure
404  *
405  * Arguments:
406  *      fp      file to print message to
407  *      idp     pointer to ID to be printed
408  *
409  * Returns:
410  *      none
411  *
412  */
413 void
414 print_scsp_id(fp, idp)
415         FILE    *fp;
416         Scsp_id *idp;
417 {
418         int     i;
419
420         inc_indent();
421         fprintf(fp, "%sNext:                 %p\n", indent, idp->next);
422         fprintf(fp, "%sLength:               %d\n", indent,
423                         idp->id_len);
424         fprintf(fp, "%sID:                   0x", indent);
425         for (i = 0; i < idp->id_len; i++)
426                 fprintf(fp, "%02x ", idp->id[i]);
427         fprintf(fp, "\n");
428         dec_indent();
429 }
430
431
432 /*
433  * Print a Cache Key structure
434  *
435  * Arguments:
436  *      fp      file to print message to
437  *      ckp     pointer to cache key structure
438  *
439  * Returns:
440  *      none
441  *
442  */
443 void
444 print_scsp_cache_key(fp, ckp)
445         FILE            *fp;
446         Scsp_ckey       *ckp;
447 {
448         int     i;
449
450         inc_indent();
451         fprintf(fp, "%sLength:               %d\n", indent,
452                         ckp->key_len);
453         fprintf(fp, "%sKey:                  0x", indent);
454         for (i = 0; i < ckp->key_len; i++)
455                 fprintf(fp, "%02x ", ckp->key[i]);
456         fprintf(fp, "\n");
457         dec_indent();
458 }
459
460
461 /*
462  * Print the mandatory common part of a message
463  *
464  * Arguments:
465  *      fp      file to print message to
466  *      mcp     pointer to mandatory common part structure
467  *
468  * Returns:
469  *      none
470  *
471  */
472 static void
473 print_scsp_mcp(fp, mcp)
474         FILE            *fp;
475         Scsp_mcp        *mcp;
476 {
477         inc_indent();
478         fprintf(fp, "%sProtocol ID:          %s (0x%02x)\n", indent,
479                         scsp_type_name(mcp->pid, proto_types),
480                         mcp->pid);
481         fprintf(fp, "%sServer Group ID:      %d\n", indent, mcp->sgid);
482         fprintf(fp, "%sFlags:                0x%04x\n", indent,
483                         mcp->flags);
484         fprintf(fp, "%sRecord Count:         %d\n", indent,
485                         mcp->rec_cnt);
486         fprintf(fp, "%sSender ID:\n", indent);
487         print_scsp_id(fp, &mcp->sid);
488         fprintf(fp, "%sReceiver ID:\n", indent);
489         print_scsp_id(fp, &mcp->rid);
490         dec_indent();
491 }
492
493
494 /*
495  * Print an extension
496  *
497  * Arguments:
498  *      fp      file to print message to
499  *      exp     pointer to extension
500  *
501  * Returns:
502  *      none
503  *
504  */
505 static void
506 print_scsp_ext(fp, exp)
507         FILE            *fp;
508         Scsp_ext        *exp;
509 {
510         int     i;
511         u_char  *cp;
512
513         inc_indent();
514         fprintf(fp, "%sNext:                 %p\n", indent, exp->next);
515         fprintf(fp, "%sType:                 %s (0x%02x)\n", indent,
516                         scsp_type_name(exp->type, ext_types),
517                         exp->type);
518         fprintf(fp, "%sLength:               %d\n", indent, exp->len);
519         if (exp->len) {
520                 fprintf(fp, "%sValue:                0x", indent);
521                 cp = (u_char *)((caddr_t)exp + sizeof(Scsp_ext));
522                 for (i = 0; i < exp->len; i++)
523                         fprintf(fp, "%02x ", *cp++);
524                 fprintf(fp, "\n");
525         }
526         dec_indent();
527 }
528
529
530 /*
531  * Print an ATMARP Cache State Advertisement record
532  *
533  * Arguments:
534  *      fp      file to print message to
535  *      acsp    pointer to extension
536  *
537  * Returns:
538  *      none
539  *
540  */
541 static void
542 print_scsp_atmarp_csa(fp, acsp)
543         FILE            *fp;
544         Scsp_atmarp_csa *acsp;
545 {
546         inc_indent();
547         fprintf(fp, "%sState:                 %s (%d)\n", indent,
548                         scsp_type_name(acsp->sa_state,
549                                 atmarp_state_names),
550                         acsp->sa_state);
551         fprintf(fp, "%sSource ATM addr:       %s\n", indent,
552                         format_atm_addr(&acsp->sa_sha));
553         fprintf(fp, "%sSource ATM subaddr:    %s\n", indent,
554                         format_atm_addr(&acsp->sa_ssa));
555         fprintf(fp, "%sSource IP addr:        %s\n", indent,
556                         format_ip_addr(&acsp->sa_spa));
557         fprintf(fp, "%sTarget ATM addr:       %s\n", indent,
558                         format_atm_addr(&acsp->sa_tha));
559         fprintf(fp, "%sTarget ATM subaddr:    %s\n", indent,
560                         format_atm_addr(&acsp->sa_tsa));
561         fprintf(fp, "%sTarget IP addr:        %s\n", indent,
562                         format_ip_addr(&acsp->sa_tpa));
563         dec_indent();
564 }
565
566
567 /*
568  * Print a Cache State Advertisement record or
569  * Cache State Advertisement Summary record
570  *
571  * Arguments:
572  *      fp      file to print message to
573  *      csap    pointer to CSA or CSAS
574  *
575  * Returns:
576  *      none
577  *
578  */
579 static void
580 print_scsp_csa(fp, csap)
581         FILE            *fp;
582         Scsp_csa        *csap;
583 {
584         inc_indent();
585         fprintf(fp, "%sNext:                 %p\n", indent, csap->next);
586         fprintf(fp, "%sHops:                 %d\n", indent, csap->hops);
587         fprintf(fp, "%sNull Flag:            %s\n", indent,
588                         csap->null ? "True" : "False");
589         fprintf(fp, "%sSequence no.:         %ld (0x%lx)\n",
590                         indent, csap->seq, csap->seq);
591         fprintf(fp, "%sCache Key:\n", indent);
592         print_scsp_cache_key(fp, &csap->key);
593         fprintf(fp, "%sOriginator ID:\n", indent);
594         print_scsp_id(fp, &csap->oid);
595         if (csap->atmarp_data) {
596                 fprintf(fp, "%sATMARP data:\n", indent);
597                 print_scsp_atmarp_csa(fp, csap->atmarp_data);
598         }
599         dec_indent();
600 }
601
602
603 /*
604  * Print a Cache Alignment message
605  *
606  * Arguments:
607  *      fp      file to print message to
608  *      cap     pointer to extension
609  *
610  * Returns:
611  *      none
612  *
613  */
614 static void
615 print_scsp_ca(fp, cap)
616         FILE    *fp;
617         Scsp_ca *cap;
618 {
619         int             n;
620         Scsp_csa        *csap;
621
622         inc_indent();
623         fprintf(fp, "%sCA Seq. No.:          %ld\n", indent,
624                         cap->ca_seq);
625         fprintf(fp, "%sM bit:                %s\n", indent,
626                         cap->ca_m ? "True" : "False");
627         fprintf(fp, "%sI bit:                %s\n", indent,
628                         cap->ca_i ? "True" : "False");
629         fprintf(fp, "%sO bit:                %s\n", indent,
630                         cap->ca_o ? "True" : "False");
631         fprintf(fp, "%sMandatory Common Part:\n", indent);
632         print_scsp_mcp(fp, &cap->ca_mcp);
633         for (csap = cap->ca_csa_rec, n = 1; csap;
634                         csap = csap->next, n++) {
635                 fprintf(fp, "%sCSA Record %d (%p):\n", indent, n, csap);
636                 print_scsp_csa(fp, csap);
637         }
638         dec_indent();
639 }
640
641
642 /*
643  * Print a Cache State Update Request, Cache State Update Reply, or
644  * Cache State Update Solicit message
645  *
646  * Arguments:
647  *      fp      file to print message to
648  *      csup    pointer to CSU message
649  *
650  * Returns:
651  *      none
652  *
653  */
654 static void
655 print_scsp_csu(fp, csup)
656         FILE            *fp;
657         Scsp_csu_msg    *csup;
658 {
659         int             i;
660         Scsp_csa        *csap;
661
662         inc_indent();
663         fprintf(fp, "%sMandatory Common Part:\n", indent);
664         print_scsp_mcp(fp, &csup->csu_mcp);
665         for (csap = csup->csu_csa_rec, i = 1; csap;
666                         csap = csap->next, i++) {
667                 fprintf(fp, "%sCSA Record %d:\n", indent, i);
668                 print_scsp_csa(fp, csap);
669         }
670         dec_indent();
671 }
672
673
674 /*
675  * Print a Hello message
676  *
677  * Arguments:
678  *      fp      file to print message to
679  *      hp      pointer to hello message
680  *
681  * Returns:
682  *      none
683  *
684  */
685 static void
686 print_scsp_hello(fp, hp)
687         FILE            *fp;
688         Scsp_hello      *hp;
689 {
690         Scsp_id *ridp;
691
692         inc_indent();
693         fprintf(fp, "%sHello Interval:       %d\n", indent,
694                         hp->hello_int);
695         fprintf(fp, "%sDead Factor:          %d\n", indent,
696                         hp->dead_factor);
697         fprintf(fp, "%sFamily ID:            %d\n", indent,
698                         hp->family_id);
699         fprintf(fp, "%sMandatory Common Part:\n", indent);
700         print_scsp_mcp(fp, &hp->hello_mcp);
701         ridp = hp->hello_mcp.rid.next;
702         if (ridp) {
703                 fprintf(fp, "%sAdditional Receiver IDs:\n", indent);
704                 for (; ridp; ridp = ridp->next)
705                         print_scsp_id(fp, ridp);
706         }
707         dec_indent();
708 }
709
710
711 #ifdef NOTDEF
712 /*
713  * NHRP-specific Cache State Advertisement record
714  */
715 struct scsp_nhrp_csa {
716         u_char  req_id;                 /* Request ID */
717         u_char  state;                  /* State */
718         u_char  pref_len;               /* Prefix length */
719         u_short flags;                  /* See below */
720         u_short mtu;                    /* Maximim transmission unit */
721         u_short hold_time;              /* Entry holding time */
722         u_char  caddr_tlen;             /* Client addr type/length */
723         u_char  csaddr_tlen;            /* Client subaddr type/length */
724         u_char  cproto_len;             /* Client proto addr length */
725         u_char  pref;                   /* Preference */
726         Atm_addr        caddr;          /* Client address */
727         Atm_addr        csaddr;         /* Client subaddress */
728         struct in_addr  cproto_addr;    /* Client protocol address */
729 };
730 typedef struct scsp_nhrp        Scsp_nhrp;
731
732 #define SCSP_NHRP_UNIQ  0x8000
733 #define SCSP_NHRP_ARP   0x4000
734
735 #endif
736
737
738 /*
739  * Print an SCSP message
740  *
741  * Arguments:
742  *      fp      file to print message to
743  *      msg     pointer to message to be printed
744  *
745  * Returns:
746  *      none
747  *
748  */
749 void
750 print_scsp_msg(fp, msg)
751         FILE            *fp;
752         Scsp_msg        *msg;
753 {
754         int             n;
755         Scsp_ext        *exp;
756
757         /*
758          * Initialize
759          */
760         init_indent();
761
762         /*
763          * Print the message type
764          */
765         inc_indent();
766         fprintf(fp, "%sMessage type:         %s (0x%02x)\n", indent,
767                         scsp_type_name(msg->sc_msg_type, msg_types),
768                         msg->sc_msg_type);
769
770         /*
771          * Print the body of the message
772          */
773         switch(msg->sc_msg_type) {
774         case SCSP_CA_MSG:
775                 print_scsp_ca(fp, msg->sc_ca);
776                 break;
777         case SCSP_CSU_REQ_MSG:
778         case SCSP_CSU_REPLY_MSG:
779         case SCSP_CSUS_MSG:
780                 print_scsp_csu(fp, msg->sc_csu_msg);
781                 break;
782         case SCSP_HELLO_MSG:
783                 print_scsp_hello(fp, msg->sc_hello);
784                 break;
785         }
786
787         /*
788          * Print any extensions
789          */
790         for (exp = msg->sc_ext, n = 1; exp; exp = exp->next, n++) {
791                 fprintf(fp, "%sExtension %d:\n", indent, n);
792                 print_scsp_ext(fp, exp);
793         }
794         dec_indent();
795
796         (void)fflush(fp);
797 }
798
799
800 /*
801  * Print an SCSP ATMARP message
802  *
803  * Arguments:
804  *      fp      file to print message to
805  *      acp     pointer to ATMARP message
806  *
807  * Returns:
808  *      none
809  *
810  */
811 static void
812 print_scsp_if_atmarp(fp, amp)
813         FILE            *fp;
814         Scsp_atmarp_msg *amp;
815 {
816         inc_indent();
817         fprintf(fp, "%sState:                %s (%d)\n", indent,
818                         scsp_type_name(amp->sa_state,
819                                 atmarp_state_names),
820                         amp->sa_state);
821         fprintf(fp, "%sCached protocol addr: %s\n", indent,
822                         format_ip_addr(&amp->sa_cpa));
823         fprintf(fp, "%sCached ATM addr:      %s\n", indent,
824                         format_atm_addr(&amp->sa_cha));
825         fprintf(fp, "%sCached ATM subaddr:      %s\n", indent,
826                         format_atm_addr(&amp->sa_csa));
827         fprintf(fp, "%sCache key:\n", indent);
828         print_scsp_cache_key(fp, &amp->sa_key);
829         fprintf(fp, "%sOriginator ID:\n", indent);
830         print_scsp_id(fp, &amp->sa_oid);
831         fprintf(fp, "%sSequence number:         %ld (0x%08lx)\n", indent,
832                         amp->sa_seq, (u_long)amp->sa_seq);
833         dec_indent();
834 }
835
836
837 /*
838  * Print an SCSP client interface message
839  *
840  * Arguments:
841  *      fp      file to print message to
842  *      imsg    pointer to message to be printed
843  *
844  * Returns:
845  *      none
846  *
847  */
848 void
849 print_scsp_if_msg(fp, imsg)
850         FILE            *fp;
851         Scsp_if_msg     *imsg;
852 {
853         int             len;
854         Scsp_atmarp_msg *ap;
855
856         /*
857          * Initialize
858          */
859         init_indent();
860         fprintf(fp, "SCSP Client Interface Message at %p\n", imsg);
861
862         /*
863          * Print the message header
864          */
865         inc_indent();
866         fprintf(fp, "%sMessage type:         %s (0x%02x)\n", indent,
867                         scsp_type_name(imsg->si_type, if_msg_types),
868                         imsg->si_type);
869         fprintf(fp, "%sResponse code:        %d\n", indent,
870                         imsg->si_rc);
871         fprintf(fp, "%sProtocol type:        %s (%d)\n", indent,
872                         scsp_type_name(imsg->si_proto, proto_types),
873                         imsg->si_proto);
874         fprintf(fp, "%sLength:               %d\n", indent,
875                         imsg->si_len);
876         fprintf(fp, "%sToken:                0x%lx\n", indent,
877                         imsg->si_tok);
878
879         /*
880          * Print the body of the message
881          */
882         switch(imsg->si_type) {
883         case SCSP_CFG_REQ:
884                 fprintf(fp, "%sInterface:            %s\n", indent,
885                                 imsg->si_cfg.atmarp_netif);
886                 break;
887         case SCSP_CACHE_RSP:
888         case SCSP_UPDATE_IND:
889         case SCSP_UPDATE_REQ:
890                 len = imsg->si_len - sizeof(Scsp_if_msg_hdr);
891                 ap = &imsg->si_atmarp;
892                 while (len) {
893                         switch(imsg->si_proto) {
894                         case SCSP_PROTO_ATMARP:
895                                 fprintf(fp, "%sATMARP CSA:\n", indent);
896                                 print_scsp_if_atmarp(fp, ap);
897                                 len -= sizeof(Scsp_atmarp_msg);
898                                 ap++;
899                                 break;
900                         case SCSP_PROTO_NHRP:
901                         case SCSP_PROTO_MARS:
902                         case SCSP_PROTO_DHCP:
903                         case SCSP_PROTO_LNNI:
904                         default:
905                                 fprintf(fp, "Protocol type not implemented\n");
906                                 break;
907                         }
908                 }
909                 break;
910         }
911         dec_indent();
912
913         (void)fflush(fp);
914 }
915
916
917 /*
918  * Print an SCSP pending connection block
919  *
920  * Arguments:
921  *      fp      file to print message to
922  *      pp      pointer to pending control block
923  *
924  * Returns:
925  *      none
926  *
927  */
928 void
929 print_scsp_pending(fp, pp)
930         FILE            *fp;
931         Scsp_pending    *pp;
932 {
933         /*
934          * Initialize
935          */
936         init_indent();
937
938         /*
939          * Print a header
940          */
941         fprintf(fp, "Pending control block at %p\n", pp);
942
943         /*
944          * Print the fields of the control block
945          */
946         inc_indent();
947         fprintf(fp, "%sNext:                 %p\n", indent, pp->sp_next);
948         fprintf(fp, "%sSocket:               %d\n", indent,
949                         pp->sp_sock);
950
951         dec_indent();
952 }
953
954
955 /*
956  * Print an SCSP server control block
957  *
958  * Arguments:
959  *      fp      file to print message to
960  *      ssp     pointer to server control block
961  *
962  * Returns:
963  *      none
964  *
965  */
966 void
967 print_scsp_server(fp, ssp)
968         FILE            *fp;
969         Scsp_server     *ssp;
970 {
971         /*
972          * Initialize
973          */
974         init_indent();
975
976         /*
977          * Print a header
978          */
979         fprintf(fp, "Server control block at %p\n", ssp);
980
981         /*
982          * Print the fields of the client control block
983          */
984         inc_indent();
985         fprintf(fp, "%sNext:                 %p\n", indent,
986                         ssp->ss_next);
987         fprintf(fp, "%sName:                 %s\n", indent,
988                         ssp->ss_name);
989         fprintf(fp, "%sNetwork Interface:    %s\n", indent,
990                         ssp->ss_intf);
991         fprintf(fp, "%sState:                %d\n", indent,
992                         ssp->ss_state);
993         fprintf(fp, "%sProtocol ID:          0x%lx\n", indent,
994                         ssp->ss_pid);
995         fprintf(fp, "%sID length:            %d\n", indent,
996                         ssp->ss_id_len);
997         fprintf(fp, "%sCache key length:     %d\n", indent,
998                         ssp->ss_ckey_len);
999         fprintf(fp, "%sServer Group ID:      0x%lx\n", indent,
1000                         ssp->ss_sgid);
1001         fprintf(fp, "%sFamily ID:            0x%lx\n", indent,
1002                         ssp->ss_fid);
1003         fprintf(fp, "%sSocket:               %d\n", indent,
1004                         ssp->ss_sock);
1005         fprintf(fp, "%sDCS Listen Socket:    %d\n", indent,
1006                         ssp->ss_dcs_lsock);
1007         fprintf(fp, "%sLocal Server ID:\n", indent);
1008         print_scsp_id(fp, &ssp->ss_lsid);
1009         fprintf(fp, "%sATM address:          %s\n", indent,
1010                         format_atm_addr(&ssp->ss_addr));
1011         fprintf(fp, "%sATM subaddress:       %s\n", indent,
1012                         format_atm_addr(&ssp->ss_subaddr));
1013         fprintf(fp, "%sInterface MTU:        %d\n", indent,
1014                         ssp->ss_mtu);
1015         fprintf(fp, "%sMark:                 %d\n", indent,
1016                         ssp->ss_mark);
1017         dec_indent();
1018 }
1019
1020
1021 /*
1022  * Print an SCSP client cache summary entry control block
1023  *
1024  * Arguments:
1025  *      fp      file to print message to
1026  *      csep    pointer to summary entry
1027  *
1028  * Returns:
1029  *      none
1030  *
1031  */
1032 void
1033 print_scsp_cse(fp, csep)
1034         FILE            *fp;
1035         Scsp_cse        *csep;
1036 {
1037         /*
1038          * Print the fields of the cache summary entry
1039          */
1040         inc_indent();
1041         fprintf(fp, "%sNext CSE:             %p\n", indent, csep->sc_next);
1042         fprintf(fp, "%sCSA sequence no.:     %ld (0x%lx)\n", indent,
1043                         csep->sc_seq, csep->sc_seq);
1044         fprintf(fp, "%sCache key:\n", indent);
1045         print_scsp_cache_key(fp, &csep->sc_key);
1046         fprintf(fp, "%sOrigin ID:\n", indent);
1047         print_scsp_id(fp, &csep->sc_oid);
1048         dec_indent();
1049 }
1050
1051
1052 /*
1053  * Print an SCSP CSU Request retransmission control block
1054  *
1055  * Arguments:
1056  *      fp      file to print message to
1057  *      csurp   pointer to retransmission entry
1058  *
1059  * Returns:
1060  *      none
1061  *
1062  */
1063 void
1064 print_scsp_csu_rexmt(fp, rxp)
1065         FILE            *fp;
1066         Scsp_csu_rexmt  *rxp;
1067 {
1068         int             i;
1069         Scsp_csa        *csap;
1070
1071         inc_indent();
1072         fprintf(fp, "%sNext CSU Req rexmt:   %p\n", indent, rxp->sr_next);
1073         fprintf(fp, "%sDCS address:          %p\n", indent, rxp->sr_dcs);
1074         for (csap = rxp->sr_csa, i = 1; csap;
1075                         csap = csap->next, i++) {
1076                 fprintf(fp, "%sCSA %d:\n", indent, i);
1077                 print_scsp_csa(fp, csap);
1078         }
1079         dec_indent();
1080 }
1081
1082
1083 /*
1084  * Print an SCSP DCS control block
1085  *
1086  * Arguments:
1087  *      fp      file to print message to
1088  *      dcsp    pointer to DCS control block
1089  *
1090  * Returns:
1091  *      none
1092  *
1093  */
1094 void
1095 print_scsp_dcs(fp, dcsp)
1096         FILE            *fp;
1097         Scsp_dcs        *dcsp;
1098 {
1099         Scsp_csa        *csap;
1100         Scsp_cse        *csep;
1101         Scsp_csu_rexmt  *rxp;
1102
1103         /*
1104          * Initialize
1105          */
1106         init_indent();
1107
1108         /*
1109          * Print a header
1110          */
1111         fprintf(fp, "DCS control block at %p\n", dcsp);
1112
1113         /*
1114          * Print the fields of the DCS control block
1115          */
1116         inc_indent();
1117         fprintf(fp, "%sNext DCS block:       %p\n", indent, dcsp->sd_next);
1118         fprintf(fp, "%sServer control block: %p\n", indent, dcsp->sd_server);
1119         fprintf(fp, "%sDCS ID:\n", indent);
1120         print_scsp_id(fp, &dcsp->sd_dcsid);
1121         fprintf(fp, "%sDCS address:          %s\n", indent,
1122                         format_atm_addr(&dcsp->sd_addr));
1123         fprintf(fp, "%sDCS subaddress        %s\n", indent,
1124                         format_atm_addr(&dcsp->sd_subaddr));
1125         fprintf(fp, "%sSocket:               %d\n", indent,
1126                         dcsp->sd_sock);
1127         fprintf(fp, "%sOpen VCC Retry Timer:\n", indent);
1128         fprintf(fp, "%sHello FSM State:      %s\n", indent,
1129                         format_hfsm_state(dcsp->sd_hello_state));
1130         fprintf(fp, "%sHello Interval:       %d\n", indent,
1131                         dcsp->sd_hello_int);
1132         fprintf(fp, "%sHello Dead Factor:    %d\n", indent,
1133                         dcsp->sd_hello_df);
1134         fprintf(fp, "%sHello Rcvd:           %d\n", indent,
1135                         dcsp->sd_hello_rcvd);
1136         fprintf(fp, "%sCA FSM State:         %s\n", indent,
1137                         format_cafsm_state(dcsp->sd_ca_state));
1138         fprintf(fp, "%sCA Seq. No.:          0x%lx\n", indent,
1139                         dcsp->sd_ca_seq);
1140         fprintf(fp, "%sCA Rexmit Int:        %d\n", indent,
1141                         dcsp->sd_ca_rexmt_int);
1142         fprintf(fp, "%sCA Retransmit Msg:    %p\n", indent,
1143                         dcsp->sd_ca_rexmt_msg);
1144         fprintf(fp, "%sCSASs to send:        ", indent);
1145         if (dcsp->sd_ca_csas == (Scsp_cse *)0) {
1146                 fprintf(fp, "Empty\n");
1147         } else {
1148                 fprintf(fp, "%p\n", dcsp->sd_ca_csas);
1149         }
1150         fprintf(fp, "%sCSUS Rexmit Int:      %d\n", indent,
1151                         dcsp->sd_csus_rexmt_int);
1152         fprintf(fp, "%sCache Request List:   ", indent);
1153         if (dcsp->sd_crl == (Scsp_csa *)0) {
1154                 fprintf(fp, "Empty\n");
1155         } else {
1156                 fprintf(fp, "%p\n", dcsp->sd_crl);
1157         }
1158         fprintf(fp, "%sCSUS Rexmit Msg:      %p\n", indent,
1159                         dcsp->sd_csus_rexmt_msg);
1160         fprintf(fp, "%sCSA Hop count:        %d\n", indent,
1161                         dcsp->sd_hops);
1162         fprintf(fp, "%sCSAs Pending ACK:     %p\n", indent,
1163                         dcsp->sd_csu_ack_pend);
1164         fprintf(fp, "%sCSAs ACKed:           %p\n", indent,
1165                         dcsp->sd_csu_ack);
1166         fprintf(fp, "%sCSU Req Rexmit Int:   %d\n", indent,
1167                         dcsp->sd_csu_rexmt_int);
1168         fprintf(fp, "%sCSU Req Rexmit Max:   %d\n", indent,
1169                         dcsp->sd_csu_rexmt_max);
1170         fprintf(fp, "%sCSU Req Rexmit Queue  ", indent);
1171         if (!dcsp->sd_csu_rexmt) {
1172                 fprintf(fp, "Empty\n");
1173         } else {
1174                 fprintf(fp, "%p\n", dcsp->sd_csu_rexmt);
1175         }
1176         fprintf(fp, "%sClient I/F state:     %d\n", indent,
1177                         dcsp->sd_client_state);
1178
1179         /*
1180          * Print the list of CSASs waiting to be sent
1181          */
1182         if (dcsp->sd_ca_csas) {
1183                 fprintf(fp, "\n%sCSASs to send:", indent);
1184                 inc_indent();
1185                 for (csep = dcsp->sd_ca_csas; csep;
1186                                 csep = csep->sc_next) {
1187                         fprintf(fp, "%sCache summary entry at %p\n",
1188                                         indent, csep);
1189                         print_scsp_cse(fp, csep);
1190                 }
1191                 dec_indent();
1192         }
1193
1194         /*
1195          * Print the Cache Request List
1196          */
1197         if (dcsp->sd_crl) {
1198                 fprintf(fp, "\n%sCache Request List:\n", indent);
1199                 inc_indent();
1200                 for (csap = dcsp->sd_crl; csap; csap = csap->next) {
1201                         fprintf(fp, "%sCSA at %p\n", indent, csap);
1202                         print_scsp_csa(fp, csap);
1203                 }
1204                 dec_indent();
1205         }
1206
1207         /*
1208          * Print the CSU retransmit queue
1209          */
1210         if (dcsp->sd_csu_rexmt) {
1211                 fprintf(fp, "\n%sCSU Req Rexmit Queue:\n", indent);
1212                 inc_indent();
1213                 for (rxp = dcsp->sd_csu_rexmt; rxp;
1214                                 rxp = rxp->sr_next) {
1215                         fprintf(fp, "%sCSU Rexmit Block at %p\n",
1216                                         indent, rxp);
1217                         print_scsp_csu_rexmt(fp, rxp);
1218                 }
1219                 dec_indent();
1220         }
1221
1222         dec_indent();
1223 }
1224
1225
1226 /*
1227  * Print SCSP's control blocks
1228  *
1229  * Arguments:
1230  *      none
1231  *
1232  * Returns:
1233  *      None
1234  *
1235  */
1236 void
1237 print_scsp_dump()
1238 {
1239         int             i;
1240         Scsp_server     *ssp;
1241         Scsp_dcs        *dcsp;
1242         Scsp_cse        *scp;
1243         Scsp_pending    *pp;
1244         FILE            *df;
1245         char            fname[64];
1246         static int      dump_no = 0;
1247
1248         /*
1249          * Build a file name
1250          */
1251         UM_ZERO(fname, sizeof(fname));
1252         sprintf(fname, "/tmp/scspd.%d.%03d.out", getpid(), dump_no++);
1253
1254         /*
1255          * Open the output file
1256          */
1257         df = fopen(fname, "w");
1258         if (df == (FILE *)0)
1259                 return;
1260
1261         /*
1262          * Dump the server control blocks
1263          */
1264         for (ssp = scsp_server_head; ssp; ssp = ssp->ss_next) {
1265                 print_scsp_server(df, ssp);
1266                 fprintf(df, "\n");
1267
1268                 /*
1269                  * Print the client's cache summary
1270                  */
1271                 for (i = 0; i < SCSP_HASHSZ; i++) {
1272                         for (scp = ssp->ss_cache[i]; scp;
1273                                         scp = scp->sc_next) {
1274                                 print_scsp_cse(df, scp);
1275                                 fprintf(df, "\n");
1276                         }
1277                 }
1278
1279                 /*
1280                  * Print the client's DCS control blocks
1281                  */
1282                 for (dcsp = ssp->ss_dcs; dcsp; dcsp = dcsp->sd_next) {
1283                         print_scsp_dcs(df, dcsp);
1284                         fprintf(df, "\n\n");
1285                 }
1286                 fprintf(df, "\n\n");
1287         }
1288
1289         /*
1290          * Print the pending connection blocks
1291          */
1292         for (pp = scsp_pending_head; pp; pp = pp->sp_next) {
1293                 print_scsp_pending(df, pp);
1294                 fprintf(df, "\n");
1295         }
1296
1297         /*
1298          * Close the output file
1299          */
1300         (void)fclose(df);
1301 }