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