]> gitweb.fperrin.net Git - iftop.git/blob - dlcommon.c
Import iftop-1.0pre4
[iftop.git] / dlcommon.c
1 /*
2  * Common (shared) DLPI test routines.
3  * Mostly pretty boring boilerplate sorta stuff.
4  * These can be split into individual library routines later
5  * but it's just convenient to keep them in a single file
6  * while they're being developed.
7  *
8  * Not supported:
9  *   Connection Oriented stuff
10  *   QOS stuff
11  */
12
13 #include "config.h"
14
15 #ifdef HAVE_DLPI
16
17 /*
18 typedef unsigned long   ulong;
19 */
20
21
22 #include        <sys/types.h>
23 #include        <sys/stream.h>
24 #include        <sys/stropts.h>
25 #include        <sys/dlpi.h>
26 #include        <sys/signal.h>
27 #include        <stdio.h>
28 #include        <stdlib.h>
29 #include        <string.h>
30 #include        "dlcommon.h"
31
32 #define         CASERET(s)      case s:  return ("s")
33
34 char    *dlprim();
35 char    *dlstate();
36 char    *dlerrno();
37 char    *dlpromisclevel();
38 char    *dlservicemode();
39 char    *dlstyle();
40 char    *dlmactype();
41
42
43 dlinforeq(fd)
44 int     fd;
45 {
46         dl_info_req_t   info_req;
47         struct  strbuf  ctl;
48         int     flags;
49
50         info_req.dl_primitive = DL_INFO_REQ;
51
52         ctl.maxlen = 0;
53         ctl.len = sizeof (info_req);
54         ctl.buf = (char *) &info_req;
55
56         flags = RS_HIPRI;
57
58         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
59                 syserr("dlinforeq:  putmsg");
60 }
61
62 dlinfoack(fd, bufp)
63 int     fd;
64 char    *bufp;
65 {
66         union   DL_primitives   *dlp;
67         struct  strbuf  ctl;
68         int     flags;
69
70         ctl.maxlen = MAXDLBUF;
71         ctl.len = 0;
72         ctl.buf = bufp;
73
74         strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlinfoack");
75
76         dlp = (union DL_primitives *) ctl.buf;
77
78         expecting(DL_INFO_ACK, dlp);
79
80         if (ctl.len < sizeof (dl_info_ack_t))
81                 err("dlinfoack:  response ctl.len too short:  %d", ctl.len);
82
83         if (flags != RS_HIPRI)
84                 err("dlinfoack:  DL_INFO_ACK was not M_PCPROTO");
85
86         if (ctl.len < sizeof (dl_info_ack_t))
87                 err("dlinfoack:  short response ctl.len:  %d", ctl.len);
88 }
89
90 dlattachreq(fd, ppa)
91 int     fd;
92 u_long  ppa;
93 {
94         dl_attach_req_t attach_req;
95         struct  strbuf  ctl;
96         int     flags;
97
98         attach_req.dl_primitive = DL_ATTACH_REQ;
99         attach_req.dl_ppa = ppa;
100
101         ctl.maxlen = 0;
102         ctl.len = sizeof (attach_req);
103         ctl.buf = (char *) &attach_req;
104
105         flags = 0;
106
107         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
108                 syserr("dlattachreq:  putmsg");
109 }
110
111 dlenabmultireq(fd, addr, length)
112 int     fd;
113 char    *addr;
114 int     length;
115 {
116         long    buf[MAXDLBUF];
117         union   DL_primitives   *dlp;
118         struct  strbuf  ctl;
119         int     flags;
120
121         dlp = (union DL_primitives*) buf;
122
123         dlp->enabmulti_req.dl_primitive = DL_ENABMULTI_REQ;
124         dlp->enabmulti_req.dl_addr_length = length;
125         dlp->enabmulti_req.dl_addr_offset = sizeof (dl_enabmulti_req_t);
126
127         (void) memcpy((char*)OFFADDR(buf, sizeof (dl_enabmulti_req_t)), addr, length);
128
129         ctl.maxlen = 0;
130         ctl.len = sizeof (dl_enabmulti_req_t) + length;
131         ctl.buf = (char*) buf;
132
133         flags = 0;
134
135         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
136                 syserr("dlenabmultireq:  putmsg");
137 }
138
139 dldisabmultireq(fd, addr, length)
140 int     fd;
141 char    *addr;
142 int     length;
143 {
144         long    buf[MAXDLBUF];
145         union   DL_primitives   *dlp;
146         struct  strbuf  ctl;
147         int     flags;
148
149         dlp = (union DL_primitives*) buf;
150
151         dlp->disabmulti_req.dl_primitive = DL_ENABMULTI_REQ;
152         dlp->disabmulti_req.dl_addr_length = length;
153         dlp->disabmulti_req.dl_addr_offset = sizeof (dl_disabmulti_req_t);
154
155         (void) memcpy((char*)OFFADDR(buf, sizeof (dl_disabmulti_req_t)), addr, length);
156
157         ctl.maxlen = 0;
158         ctl.len = sizeof (dl_disabmulti_req_t) + length;
159         ctl.buf = (char*) buf;
160
161         flags = 0;
162
163         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
164                 syserr("dldisabmultireq:  putmsg");
165 }
166
167 dlpromisconreq(fd, level)
168 int     fd;
169 u_long  level;
170 {
171         dl_promiscon_req_t      promiscon_req;
172         struct  strbuf  ctl;
173         int     flags;
174
175         promiscon_req.dl_primitive = DL_PROMISCON_REQ;
176         promiscon_req.dl_level = level;
177
178         ctl.maxlen = 0;
179         ctl.len = sizeof (promiscon_req);
180         ctl.buf = (char *) &promiscon_req;
181
182         flags = 0;
183
184         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
185                 syserr("dlpromiscon:  putmsg");
186
187 }
188
189 dlpromiscoff(fd, level)
190 int     fd;
191 u_long  level;
192 {
193         dl_promiscoff_req_t     promiscoff_req;
194         struct  strbuf  ctl;
195         int     flags;
196
197         promiscoff_req.dl_primitive = DL_PROMISCOFF_REQ;
198         promiscoff_req.dl_level = level;
199
200         ctl.maxlen = 0;
201         ctl.len = sizeof (promiscoff_req);
202         ctl.buf = (char *) &promiscoff_req;
203
204         flags = 0;
205
206         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
207                 syserr("dlpromiscoff:  putmsg");
208 }
209
210 dlphysaddrreq(fd, addrtype)
211 int     fd;
212 u_long  addrtype;
213 {
214         dl_phys_addr_req_t      phys_addr_req;
215         struct  strbuf  ctl;
216         int     flags;
217
218         phys_addr_req.dl_primitive = DL_PHYS_ADDR_REQ;
219         phys_addr_req.dl_addr_type = addrtype;
220
221         ctl.maxlen = 0;
222         ctl.len = sizeof (phys_addr_req);
223         ctl.buf = (char *) &phys_addr_req;
224
225         flags = 0;
226
227         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
228                 syserr("dlphysaddrreq:  putmsg");
229 }
230
231 dlsetphysaddrreq(fd, addr, length)
232 int     fd;
233 char    *addr;
234 int     length;
235 {
236         long    buf[MAXDLBUF];
237         union   DL_primitives   *dlp;
238         struct  strbuf  ctl;
239         int     flags;
240
241         dlp = (union DL_primitives*) buf;
242
243         dlp->set_physaddr_req.dl_primitive = DL_ENABMULTI_REQ;
244         dlp->set_physaddr_req.dl_addr_length = length;
245         dlp->set_physaddr_req.dl_addr_offset = sizeof (dl_set_phys_addr_req_t);
246
247         (void) memcpy((char*)OFFADDR(buf, sizeof (dl_set_phys_addr_req_t)), addr, length);
248
249         ctl.maxlen = 0;
250         ctl.len = sizeof (dl_set_phys_addr_req_t) + length;
251         ctl.buf = (char*) buf;
252
253         flags = 0;
254
255         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
256                 syserr("dlsetphysaddrreq:  putmsg");
257 }
258
259 dldetachreq(fd)
260 int     fd;
261 {
262         dl_detach_req_t detach_req;
263         struct  strbuf  ctl;
264         int     flags;
265
266         detach_req.dl_primitive = DL_DETACH_REQ;
267
268         ctl.maxlen = 0;
269         ctl.len = sizeof (detach_req);
270         ctl.buf = (char *) &detach_req;
271
272         flags = 0;
273
274         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
275                 syserr("dldetachreq:  putmsg");
276 }
277
278 dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest)
279 int     fd;
280 u_long  sap;
281 u_long  max_conind;
282 u_long  service_mode;
283 u_long  conn_mgmt;
284 u_long  xidtest;
285 {
286         dl_bind_req_t   bind_req;
287         struct  strbuf  ctl;
288         int     flags;
289
290         bind_req.dl_primitive = DL_BIND_REQ;
291         bind_req.dl_sap = sap;
292         bind_req.dl_max_conind = max_conind;
293         bind_req.dl_service_mode = service_mode;
294         bind_req.dl_conn_mgmt = conn_mgmt;
295         bind_req.dl_xidtest_flg = xidtest;
296
297         ctl.maxlen = 0;
298         ctl.len = sizeof (bind_req);
299         ctl.buf = (char *) &bind_req;
300
301         flags = 0;
302
303         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
304                 syserr("dlbindreq:  putmsg");
305 }
306
307 dlunitdatareq(fd, addrp, addrlen, minpri, maxpri, datap, datalen)
308 int     fd;
309 u_char  *addrp;
310 int     addrlen;
311 u_long  minpri, maxpri;
312 u_char  *datap;
313 int     datalen;
314 {
315         long    buf[MAXDLBUF];
316         union   DL_primitives   *dlp;
317         struct  strbuf  data, ctl;
318
319         dlp = (union DL_primitives*) buf;
320
321         dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ;
322         dlp->unitdata_req.dl_dest_addr_length = addrlen;
323         dlp->unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t);
324         dlp->unitdata_req.dl_priority.dl_min = minpri;
325         dlp->unitdata_req.dl_priority.dl_max = maxpri;
326
327         (void) memcpy(OFFADDR(dlp, sizeof (dl_unitdata_req_t)), addrp, addrlen);
328
329         ctl.maxlen = 0;
330         ctl.len = sizeof (dl_unitdata_req_t) + addrlen;
331         ctl.buf = (char *) buf;
332
333         data.maxlen = 0;
334         data.len = datalen;
335         data.buf = (char *) datap;
336
337         if (putmsg(fd, &ctl, &data, 0) < 0)
338                 syserr("dlunitdatareq:  putmsg");
339 }
340
341 dlunbindreq(fd)
342 int     fd;
343 {
344         dl_unbind_req_t unbind_req;
345         struct  strbuf  ctl;
346         int     flags;
347
348         unbind_req.dl_primitive = DL_UNBIND_REQ;
349
350         ctl.maxlen = 0;
351         ctl.len = sizeof (unbind_req);
352         ctl.buf = (char *) &unbind_req;
353
354         flags = 0;
355
356         if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0)
357                 syserr("dlunbindreq:  putmsg");
358 }
359
360 dlokack(fd, bufp)
361 int     fd;
362 char    *bufp;
363 {
364         union   DL_primitives   *dlp;
365         struct  strbuf  ctl;
366         int     flags;
367
368         ctl.maxlen = MAXDLBUF;
369         ctl.len = 0;
370         ctl.buf = bufp;
371
372         strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack");
373
374         dlp = (union DL_primitives *) ctl.buf;
375
376         expecting(DL_OK_ACK, dlp);
377
378         if (ctl.len < sizeof (dl_ok_ack_t))
379                 err("dlokack:  response ctl.len too short:  %d", ctl.len);
380
381         if (flags != RS_HIPRI)
382                 err("dlokack:  DL_OK_ACK was not M_PCPROTO");
383
384         if (ctl.len < sizeof (dl_ok_ack_t))
385                 err("dlokack:  short response ctl.len:  %d", ctl.len);
386 }
387
388 dlerrorack(fd, bufp)
389 int     fd;
390 char    *bufp;
391 {
392         union   DL_primitives   *dlp;
393         struct  strbuf  ctl;
394         int     flags;
395
396         ctl.maxlen = MAXDLBUF;
397         ctl.len = 0;
398         ctl.buf = bufp;
399
400         strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlerrorack");
401
402         dlp = (union DL_primitives *) ctl.buf;
403
404         expecting(DL_ERROR_ACK, dlp);
405
406         if (ctl.len < sizeof (dl_error_ack_t))
407                 err("dlerrorack:  response ctl.len too short:  %d", ctl.len);
408
409         if (flags != RS_HIPRI)
410                 err("dlerrorack:  DL_OK_ACK was not M_PCPROTO");
411
412         if (ctl.len < sizeof (dl_error_ack_t))
413                 err("dlerrorack:  short response ctl.len:  %d", ctl.len);
414 }
415
416 dlbindack(fd, bufp)
417 int     fd;
418 char    *bufp;
419 {
420         union   DL_primitives   *dlp;
421         struct  strbuf  ctl;
422         int     flags;
423
424         ctl.maxlen = MAXDLBUF;
425         ctl.len = 0;
426         ctl.buf = bufp;
427
428         strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack");
429
430         dlp = (union DL_primitives *) ctl.buf;
431
432         expecting(DL_BIND_ACK, dlp);
433
434         if (flags != RS_HIPRI)
435                 err("dlbindack:  DL_OK_ACK was not M_PCPROTO");
436
437         if (ctl.len < sizeof (dl_bind_ack_t))
438                 err("dlbindack:  short response ctl.len:  %d", ctl.len);
439 }
440
441 dlphysaddrack(fd, bufp)
442 int     fd;
443 char    *bufp;
444 {
445         union   DL_primitives   *dlp;
446         struct  strbuf  ctl;
447         int     flags;
448
449         ctl.maxlen = MAXDLBUF;
450         ctl.len = 0;
451         ctl.buf = bufp;
452
453         strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlphysaddrack");
454
455         dlp = (union DL_primitives *) ctl.buf;
456
457         expecting(DL_PHYS_ADDR_ACK, dlp);
458
459         if (flags != RS_HIPRI)
460                 err("dlbindack:  DL_OK_ACK was not M_PCPROTO");
461
462         if (ctl.len < sizeof (dl_phys_addr_ack_t))
463                 err("dlphysaddrack:  short response ctl.len:  %d", ctl.len);
464 }
465
466 void
467 sigalrm()
468 {
469         (void) err("sigalrm:  TIMEOUT");
470 }
471
472 strgetmsg(fd, ctlp, datap, flagsp, caller)
473 int     fd;
474 struct  strbuf  *ctlp, *datap;
475 int     *flagsp;
476 char    *caller;
477 {
478         int     rc;
479         static  char    errmsg[80];
480
481         /*
482          * Start timer.
483          */
484         (void) signal(SIGALRM, sigalrm);
485         if (alarm(MAXWAIT) < 0) {
486                 (void) sprintf(errmsg, "%s:  alarm", caller);
487                 syserr(errmsg);
488         }
489
490         /*
491          * Set flags argument and issue getmsg().
492          */
493         *flagsp = 0;
494         if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {
495                 (void) sprintf(errmsg, "%s:  getmsg", caller);
496                 syserr(errmsg);
497         }
498
499         /*
500          * Stop timer.
501          */
502         if (alarm(0) < 0) {
503                 (void) sprintf(errmsg, "%s:  alarm", caller);
504                 syserr(errmsg);
505         }
506
507         /*
508          * Check for MOREDATA and/or MORECTL.
509          */
510         if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA))
511                 err("%s:  MORECTL|MOREDATA", caller);
512         if (rc & MORECTL)
513                 err("%s:  MORECTL", caller);
514         if (rc & MOREDATA)
515                 err("%s:  MOREDATA", caller);
516
517         /*
518          * Check for at least sizeof (long) control data portion.
519          */
520         if (ctlp->len < sizeof (long))
521                 err("getmsg:  control portion length < sizeof (long):  %d", ctlp->len);
522 }
523
524 expecting(prim, dlp)
525 int     prim;
526 union   DL_primitives   *dlp;
527 {
528         if (dlp->dl_primitive != (u_long)prim) {
529                 printdlprim(dlp);
530                 err("expected %s got %s", dlprim(prim),
531                         dlprim(dlp->dl_primitive));
532                 exit(1);
533         }
534 }
535
536 /*
537  * Print any DLPI msg in human readable format.
538  */
539 printdlprim(dlp)
540 union   DL_primitives   *dlp;
541 {
542         switch (dlp->dl_primitive) {
543                 case DL_INFO_REQ:
544                         printdlinforeq(dlp);
545                         break;
546
547                 case DL_INFO_ACK:
548                         printdlinfoack(dlp);
549                         break;
550
551                 case DL_ATTACH_REQ:
552                         printdlattachreq(dlp);
553                         break;
554
555                 case DL_OK_ACK:
556                         printdlokack(dlp);
557                         break;
558
559                 case DL_ERROR_ACK:
560                         printdlerrorack(dlp);
561                         break;
562
563                 case DL_DETACH_REQ:
564                         printdldetachreq(dlp);
565                         break;
566
567                 case DL_BIND_REQ:
568                         printdlbindreq(dlp);
569                         break;
570
571                 case DL_BIND_ACK:
572                         printdlbindack(dlp);
573                         break;
574
575                 case DL_UNBIND_REQ:
576                         printdlunbindreq(dlp);
577                         break;
578
579                 case DL_SUBS_BIND_REQ:
580                         printdlsubsbindreq(dlp);
581                         break;
582
583                 case DL_SUBS_BIND_ACK:
584                         printdlsubsbindack(dlp);
585                         break;
586
587                 case DL_SUBS_UNBIND_REQ:
588                         printdlsubsunbindreq(dlp);
589                         break;
590
591                 case DL_ENABMULTI_REQ:
592                         printdlenabmultireq(dlp);
593                         break;
594
595                 case DL_DISABMULTI_REQ:
596                         printdldisabmultireq(dlp);
597                         break;
598
599                 case DL_PROMISCON_REQ:
600                         printdlpromisconreq(dlp);
601                         break;
602
603                 case DL_PROMISCOFF_REQ:
604                         printdlpromiscoffreq(dlp);
605                         break;
606
607                 case DL_UNITDATA_REQ:
608                         printdlunitdatareq(dlp);
609                         break;
610
611                 case DL_UNITDATA_IND:
612                         printdlunitdataind(dlp);
613                         break;
614
615                 case DL_UDERROR_IND:
616                         printdluderrorind(dlp);
617                         break;
618
619                 case DL_UDQOS_REQ:
620                         printdludqosreq(dlp);
621                         break;
622
623                 case DL_PHYS_ADDR_REQ:
624                         printdlphysaddrreq(dlp);
625                         break;
626
627                 case DL_PHYS_ADDR_ACK:
628                         printdlphysaddrack(dlp);
629                         break;
630
631                 case DL_SET_PHYS_ADDR_REQ:
632                         printdlsetphysaddrreq(dlp);
633                         break;
634
635                 default:
636                         err("printdlprim:  unknown primitive type 0x%x",
637                                 dlp->dl_primitive);
638                         break;
639         }
640 }
641
642 /* ARGSUSED */
643 printdlinforeq(dlp)
644 union   DL_primitives   *dlp;
645 {
646         (void) printf("DL_INFO_REQ\n");
647 }
648
649 printdlinfoack(dlp)
650 union   DL_primitives   *dlp;
651 {
652         u_char  addr[MAXDLADDR];
653         u_char  brdcst[MAXDLADDR];
654
655         addrtostring(OFFADDR(dlp, dlp->info_ack.dl_addr_offset),
656                 dlp->info_ack.dl_addr_length, addr);
657         addrtostring(OFFADDR(dlp, dlp->info_ack.dl_brdcst_addr_offset),
658                 dlp->info_ack.dl_brdcst_addr_length, brdcst);
659
660         (void) printf("DL_INFO_ACK:  max_sdu %d min_sdu %d\n",
661                 dlp->info_ack.dl_max_sdu,
662                 dlp->info_ack.dl_min_sdu);
663         (void) printf("addr_length %d mac_type %s current_state %s\n",
664                 dlp->info_ack.dl_addr_length,
665                 dlmactype(dlp->info_ack.dl_mac_type),
666                 dlstate(dlp->info_ack.dl_current_state));
667         (void) printf("sap_length %d service_mode %s qos_length %d\n",
668                 dlp->info_ack.dl_sap_length,
669                 dlservicemode(dlp->info_ack.dl_service_mode),
670                 dlp->info_ack.dl_qos_length);
671         (void) printf("qos_offset %d qos_range_length %d qos_range_offset %d\n",
672                 dlp->info_ack.dl_qos_offset,
673                 dlp->info_ack.dl_qos_range_length,
674                 dlp->info_ack.dl_qos_range_offset);
675         (void) printf("provider_style %s addr_offset %d version %d\n",
676                 dlstyle(dlp->info_ack.dl_provider_style),
677                 dlp->info_ack.dl_addr_offset,
678                 dlp->info_ack.dl_version);
679         (void) printf("brdcst_addr_length %d brdcst_addr_offset %d\n",
680                 dlp->info_ack.dl_brdcst_addr_length,
681                 dlp->info_ack.dl_brdcst_addr_offset);
682         (void) printf("addr %s\n", addr);
683         (void) printf("brdcst_addr %s\n", brdcst);
684 }
685
686 printdlattachreq(dlp)
687 union   DL_primitives   *dlp;
688 {
689         (void) printf("DL_ATTACH_REQ:  ppa %d\n",
690                 dlp->attach_req.dl_ppa);
691 }
692
693 printdlokack(dlp)
694 union   DL_primitives   *dlp;
695 {
696         (void) printf("DL_OK_ACK:  correct_primitive %s\n",
697                 dlprim(dlp->ok_ack.dl_correct_primitive));
698 }
699
700 printdlerrorack(dlp)
701 union   DL_primitives   *dlp;
702 {
703         (void) printf("DL_ERROR_ACK:  error_primitive %s errno %s unix_errno %d\n",
704                 dlprim(dlp->error_ack.dl_error_primitive),
705                 dlerrno(dlp->error_ack.dl_errno),
706                 dlp->error_ack.dl_unix_errno);
707 }
708
709 printdlenabmultireq(dlp)
710 union   DL_primitives   *dlp;
711 {
712         u_char  addr[MAXDLADDR];
713
714         addrtostring(OFFADDR(dlp, dlp->enabmulti_req.dl_addr_offset),
715                 dlp->enabmulti_req.dl_addr_length, addr);
716
717         (void) printf("DL_ENABMULTI_REQ:  addr_length %d addr_offset %d\n",
718                 dlp->enabmulti_req.dl_addr_length,
719                 dlp->enabmulti_req.dl_addr_offset);
720         (void) printf("addr %s\n", addr);
721 }
722
723 printdldisabmultireq(dlp)
724 union   DL_primitives   *dlp;
725 {
726         u_char  addr[MAXDLADDR];
727
728         addrtostring(OFFADDR(dlp, dlp->disabmulti_req.dl_addr_offset),
729                 dlp->disabmulti_req.dl_addr_length, addr);
730
731         (void) printf("DL_DISABMULTI_REQ:  addr_length %d addr_offset %d\n",
732                 dlp->disabmulti_req.dl_addr_length,
733                 dlp->disabmulti_req.dl_addr_offset);
734         (void) printf("addr %s\n", addr);
735 }
736
737 printdlpromisconreq(dlp)
738 union   DL_primitives   *dlp;
739 {
740         (void) printf("DL_PROMISCON_REQ:  level %s\n",
741                 dlpromisclevel(dlp->promiscon_req.dl_level));
742 }
743
744 printdlpromiscoffreq(dlp)
745 union   DL_primitives   *dlp;
746 {
747         (void) printf("DL_PROMISCOFF_REQ:  level %s\n",
748                 dlpromisclevel(dlp->promiscoff_req.dl_level));
749 }
750
751 printdlphysaddrreq(dlp)
752 union   DL_primitives   *dlp;
753 {
754         (void) printf("DL_PHYS_ADDR_REQ:  addr_type 0x%x\n",
755                 dlp->physaddr_req.dl_addr_type);
756 }
757
758 printdlphysaddrack(dlp)
759 union   DL_primitives   *dlp;
760 {
761         u_char  addr[MAXDLADDR];
762
763         addrtostring(OFFADDR(dlp, dlp->physaddr_ack.dl_addr_offset),
764                 dlp->physaddr_ack.dl_addr_length, addr);
765
766         (void) printf("DL_PHYS_ADDR_ACK:  addr_length %d addr_offset %d\n",
767                 dlp->physaddr_ack.dl_addr_length,
768                 dlp->physaddr_ack.dl_addr_offset);
769         (void) printf("addr %s\n", addr);
770 }
771
772 printdlsetphysaddrreq(dlp)
773 union   DL_primitives   *dlp;
774 {
775         u_char  addr[MAXDLADDR];
776
777         addrtostring(OFFADDR(dlp, dlp->set_physaddr_req.dl_addr_offset),
778                 dlp->set_physaddr_req.dl_addr_length, addr);
779
780         (void) printf("DL_SET_PHYS_ADDR_REQ:  addr_length %d addr_offset %d\n",
781                 dlp->set_physaddr_req.dl_addr_length,
782                 dlp->set_physaddr_req.dl_addr_offset);
783         (void) printf("addr %s\n", addr);
784 }
785
786 /* ARGSUSED */
787 printdldetachreq(dlp)
788 union   DL_primitives   *dlp;
789 {
790         (void) printf("DL_DETACH_REQ\n");
791 }
792
793 printdlbindreq(dlp)
794 union   DL_primitives   *dlp;
795 {
796         (void) printf("DL_BIND_REQ:  sap %d max_conind %d\n",
797                 dlp->bind_req.dl_sap,
798                 dlp->bind_req.dl_max_conind);
799         (void) printf("service_mode %s conn_mgmt %d xidtest_flg 0x%x\n",
800                 dlservicemode(dlp->bind_req.dl_service_mode),
801                 dlp->bind_req.dl_conn_mgmt,
802                 dlp->bind_req.dl_xidtest_flg);
803 }
804
805 printdlbindack(dlp)
806 union   DL_primitives   *dlp;
807 {
808         u_char  addr[MAXDLADDR];
809
810         addrtostring(OFFADDR(dlp, dlp->bind_ack.dl_addr_offset),
811                 dlp->bind_ack.dl_addr_length, addr);
812
813         (void) printf("DL_BIND_ACK:  sap %d addr_length %d addr_offset %d\n",
814                 dlp->bind_ack.dl_sap,
815                 dlp->bind_ack.dl_addr_length,
816                 dlp->bind_ack.dl_addr_offset);
817         (void) printf("max_conind %d xidtest_flg 0x%x\n",
818                 dlp->bind_ack.dl_max_conind,
819                 dlp->bind_ack.dl_xidtest_flg);
820         (void) printf("addr %s\n", addr);
821 }
822
823 /* ARGSUSED */
824 printdlunbindreq(dlp)
825 union   DL_primitives   *dlp;
826 {
827         (void) printf("DL_UNBIND_REQ\n");
828 }
829
830 printdlsubsbindreq(dlp)
831 union   DL_primitives   *dlp;
832 {
833         u_char  sap[MAXDLADDR];
834
835         addrtostring(OFFADDR(dlp, dlp->subs_bind_req.dl_subs_sap_offset),
836                 dlp->subs_bind_req.dl_subs_sap_length, sap);
837
838         (void) printf("DL_SUBS_BIND_REQ:  subs_sap_offset %d sub_sap_len %d\n",
839                 dlp->subs_bind_req.dl_subs_sap_offset,
840                 dlp->subs_bind_req.dl_subs_sap_length);
841         (void) printf("sap %s\n", sap);
842 }
843
844 printdlsubsbindack(dlp)
845 union   DL_primitives   *dlp;
846 {
847         u_char  sap[MAXDLADDR];
848
849         addrtostring(OFFADDR(dlp, dlp->subs_bind_ack.dl_subs_sap_offset),
850                 dlp->subs_bind_ack.dl_subs_sap_length, sap);
851
852         (void) printf("DL_SUBS_BIND_ACK:  subs_sap_offset %d sub_sap_length %d\n",
853                 dlp->subs_bind_ack.dl_subs_sap_offset,
854                 dlp->subs_bind_ack.dl_subs_sap_length);
855         (void) printf("sap %s\n", sap);
856 }
857
858 printdlsubsunbindreq(dlp)
859 union   DL_primitives   *dlp;
860 {
861         u_char  sap[MAXDLADDR];
862
863         addrtostring(OFFADDR(dlp, dlp->subs_unbind_req.dl_subs_sap_offset),
864                 dlp->subs_unbind_req.dl_subs_sap_length, sap);
865
866         (void) printf("DL_SUBS_UNBIND_REQ:  subs_sap_offset %d sub_sap_length %d\n",
867                 dlp->subs_unbind_req.dl_subs_sap_offset,
868                 dlp->subs_unbind_req.dl_subs_sap_length);
869         (void) printf("sap %s\n", sap);
870 }
871
872 printdlunitdatareq(dlp)
873 union   DL_primitives   *dlp;
874 {
875         u_char  addr[MAXDLADDR];
876
877         addrtostring(OFFADDR(dlp, dlp->unitdata_req.dl_dest_addr_offset),
878                 dlp->unitdata_req.dl_dest_addr_length, addr);
879
880         (void) printf("DL_UNITDATA_REQ:  dest_addr_length %d dest_addr_offset %d\n",
881                 dlp->unitdata_req.dl_dest_addr_length,
882                 dlp->unitdata_req.dl_dest_addr_offset);
883         (void) printf("dl_priority.min %d dl_priority.max %d\n",
884                 dlp->unitdata_req.dl_priority.dl_min,
885                 dlp->unitdata_req.dl_priority.dl_max);
886         (void) printf("addr %s\n", addr);
887 }
888
889 printdlunitdataind(dlp)
890 union   DL_primitives   *dlp;
891 {
892         u_char  dest[MAXDLADDR];
893         u_char  src[MAXDLADDR];
894
895         addrtostring(OFFADDR(dlp, dlp->unitdata_ind.dl_dest_addr_offset),
896                 dlp->unitdata_ind.dl_dest_addr_length, dest);
897         addrtostring(OFFADDR(dlp, dlp->unitdata_ind.dl_src_addr_offset),
898                 dlp->unitdata_ind.dl_src_addr_length, src);
899
900         (void) printf("DL_UNITDATA_IND:  dest_addr_length %d dest_addr_offset %d\n",
901                 dlp->unitdata_ind.dl_dest_addr_length,
902                 dlp->unitdata_ind.dl_dest_addr_offset);
903         (void) printf("src_addr_length %d src_addr_offset %d\n",
904                 dlp->unitdata_ind.dl_src_addr_length,
905                 dlp->unitdata_ind.dl_src_addr_offset);
906         (void) printf("group_address 0x%x\n",
907                 dlp->unitdata_ind.dl_group_address);
908         (void) printf("dest %s\n", dest);
909         (void) printf("src %s\n", src);
910 }
911
912 printdluderrorind(dlp)
913 union   DL_primitives   *dlp;
914 {
915         u_char  addr[MAXDLADDR];
916
917         addrtostring(OFFADDR(dlp, dlp->uderror_ind.dl_dest_addr_offset),
918                 dlp->uderror_ind.dl_dest_addr_length, addr);
919
920         (void) printf("DL_UDERROR_IND:  dest_addr_length %d dest_addr_offset %d\n",
921                 dlp->uderror_ind.dl_dest_addr_length,
922                 dlp->uderror_ind.dl_dest_addr_offset);
923         (void) printf("unix_errno %d errno %s\n",
924                 dlp->uderror_ind.dl_unix_errno,
925                 dlerrno(dlp->uderror_ind.dl_errno));
926         (void) printf("addr %s\n", addr);
927 }
928
929 printdltestreq(dlp)
930 union   DL_primitives   *dlp;
931 {
932         u_char  addr[MAXDLADDR];
933
934         addrtostring(OFFADDR(dlp, dlp->test_req.dl_dest_addr_offset),
935                 dlp->test_req.dl_dest_addr_length, addr);
936
937         (void) printf("DL_TEST_REQ:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
938                 dlp->test_req.dl_flag,
939                 dlp->test_req.dl_dest_addr_length,
940                 dlp->test_req.dl_dest_addr_offset);
941         (void) printf("dest_addr %s\n", addr);
942 }
943
944 printdltestind(dlp)
945 union   DL_primitives   *dlp;
946 {
947         u_char  dest[MAXDLADDR];
948         u_char  src[MAXDLADDR];
949
950         addrtostring(OFFADDR(dlp, dlp->test_ind.dl_dest_addr_offset),
951                 dlp->test_ind.dl_dest_addr_length, dest);
952         addrtostring(OFFADDR(dlp, dlp->test_ind.dl_src_addr_offset),
953                 dlp->test_ind.dl_src_addr_length, src);
954
955         (void) printf("DL_TEST_IND:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
956                 dlp->test_ind.dl_flag,
957                 dlp->test_ind.dl_dest_addr_length,
958                 dlp->test_ind.dl_dest_addr_offset);
959         (void) printf("src_addr_length %d src_addr_offset %d\n",
960                 dlp->test_ind.dl_src_addr_length,
961                 dlp->test_ind.dl_src_addr_offset);
962         (void) printf("dest_addr %s\n", dest);
963         (void) printf("src_addr %s\n", src);
964 }
965
966 printdltestres(dlp)
967 union   DL_primitives   *dlp;
968 {
969         u_char  dest[MAXDLADDR];
970
971         addrtostring(OFFADDR(dlp, dlp->test_res.dl_dest_addr_offset),
972                 dlp->test_res.dl_dest_addr_length, dest);
973
974         (void) printf("DL_TEST_RES:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
975                 dlp->test_res.dl_flag,
976                 dlp->test_res.dl_dest_addr_length,
977                 dlp->test_res.dl_dest_addr_offset);
978         (void) printf("dest_addr %s\n", dest);
979 }
980
981 printdltestcon(dlp)
982 union   DL_primitives   *dlp;
983 {
984         u_char  dest[MAXDLADDR];
985         u_char  src[MAXDLADDR];
986
987         addrtostring(OFFADDR(dlp, dlp->test_con.dl_dest_addr_offset),
988                 dlp->test_con.dl_dest_addr_length, dest);
989         addrtostring(OFFADDR(dlp, dlp->test_con.dl_src_addr_offset),
990                 dlp->test_con.dl_src_addr_length, src);
991
992         (void) printf("DL_TEST_CON:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
993                 dlp->test_con.dl_flag,
994                 dlp->test_con.dl_dest_addr_length,
995                 dlp->test_con.dl_dest_addr_offset);
996         (void) printf("src_addr_length %d src_addr_offset %d\n",
997                 dlp->test_con.dl_src_addr_length,
998                 dlp->test_con.dl_src_addr_offset);
999         (void) printf("dest_addr %s\n", dest);
1000         (void) printf("src_addr %s\n", src);
1001 }
1002
1003 printdlxidreq(dlp)
1004 union   DL_primitives   *dlp;
1005 {
1006         u_char  dest[MAXDLADDR];
1007
1008         addrtostring(OFFADDR(dlp, dlp->xid_req.dl_dest_addr_offset),
1009                 dlp->xid_req.dl_dest_addr_length, dest);
1010
1011         (void) printf("DL_XID_REQ:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
1012                 dlp->xid_req.dl_flag,
1013                 dlp->xid_req.dl_dest_addr_length,
1014                 dlp->xid_req.dl_dest_addr_offset);
1015         (void) printf("dest_addr %s\n", dest);
1016 }
1017
1018 printdlxidind(dlp)
1019 union   DL_primitives   *dlp;
1020 {
1021         u_char  dest[MAXDLADDR];
1022         u_char  src[MAXDLADDR];
1023
1024         addrtostring(OFFADDR(dlp, dlp->xid_ind.dl_dest_addr_offset),
1025                 dlp->xid_ind.dl_dest_addr_length, dest);
1026         addrtostring(OFFADDR(dlp, dlp->xid_ind.dl_src_addr_offset),
1027                 dlp->xid_ind.dl_src_addr_length, src);
1028
1029         (void) printf("DL_XID_IND:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
1030                 dlp->xid_ind.dl_flag,
1031                 dlp->xid_ind.dl_dest_addr_length,
1032                 dlp->xid_ind.dl_dest_addr_offset);
1033         (void) printf("src_addr_length %d src_addr_offset %d\n",
1034                 dlp->xid_ind.dl_src_addr_length,
1035                 dlp->xid_ind.dl_src_addr_offset);
1036         (void) printf("dest_addr %s\n", dest);
1037         (void) printf("src_addr %s\n", src);
1038 }
1039
1040 printdlxidres(dlp)
1041 union   DL_primitives   *dlp;
1042 {
1043         u_char  dest[MAXDLADDR];
1044
1045         addrtostring(OFFADDR(dlp, dlp->xid_res.dl_dest_addr_offset),
1046                 dlp->xid_res.dl_dest_addr_length, dest);
1047
1048         (void) printf("DL_XID_RES:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
1049                 dlp->xid_res.dl_flag,
1050                 dlp->xid_res.dl_dest_addr_length,
1051                 dlp->xid_res.dl_dest_addr_offset);
1052         (void) printf("dest_addr %s\n", dest);
1053 }
1054
1055 printdlxidcon(dlp)
1056 union   DL_primitives   *dlp;
1057 {
1058         u_char  dest[MAXDLADDR];
1059         u_char  src[MAXDLADDR];
1060
1061         addrtostring(OFFADDR(dlp, dlp->xid_con.dl_dest_addr_offset),
1062                 dlp->xid_con.dl_dest_addr_length, dest);
1063         addrtostring(OFFADDR(dlp, dlp->xid_con.dl_src_addr_offset),
1064                 dlp->xid_con.dl_src_addr_length, src);
1065
1066         (void) printf("DL_XID_CON:  flag 0x%x dest_addr_length %d dest_addr_offset %d\n",
1067                 dlp->xid_con.dl_flag,
1068                 dlp->xid_con.dl_dest_addr_length,
1069                 dlp->xid_con.dl_dest_addr_offset);
1070         (void) printf("src_addr_length %d src_addr_offset %d\n",
1071                 dlp->xid_con.dl_src_addr_length,
1072                 dlp->xid_con.dl_src_addr_offset);
1073         (void) printf("dest_addr %s\n", dest);
1074         (void) printf("src_addr %s\n", src);
1075 }
1076
1077 printdludqosreq(dlp)
1078 union   DL_primitives   *dlp;
1079 {
1080         (void) printf("DL_UDQOS_REQ:  qos_length %d qos_offset %d\n",
1081                 dlp->udqos_req.dl_qos_length,
1082                 dlp->udqos_req.dl_qos_offset);
1083 }
1084
1085 /*
1086  * Return string.
1087  */
1088 addrtostring(addr, length, s)
1089 u_char  *addr;
1090 u_long  length;
1091 u_char  *s;
1092 {
1093         int     i;
1094
1095         for (i = 0; i < length; i++) {
1096                 (void) sprintf((char*) s, "%x:", addr[i] & 0xff);
1097                 s = s + strlen((char*)s);
1098         }
1099         if (length)
1100                 *(--s) = '\0';
1101 }
1102
1103 /*
1104  * Return length
1105  */
1106 stringtoaddr(sp, addr)
1107 char    *sp;
1108 char    *addr;
1109 {
1110         int     n = 0;
1111         char    *p;
1112         int     val;
1113
1114         p = sp;
1115         while (p = strtok(p, ":")) {
1116                 if (sscanf(p, "%x", &val) != 1)
1117                         err("stringtoaddr:  invalid input string:  %s", sp);
1118                 if (val > 0xff)
1119                         err("stringtoaddr:  invalid input string:  %s", sp);
1120                 *addr++ = val;
1121                 n++;
1122                 p = NULL;
1123         }
1124         
1125         return (n);
1126 }
1127
1128
1129 static char
1130 hexnibble(c)
1131 char    c;
1132 {
1133         static  char    hextab[] = {
1134                 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
1135                 'a', 'b', 'c', 'd', 'e', 'f'
1136         };
1137
1138         return (hextab[c & 0x0f]);
1139 }
1140
1141 char*
1142 dlprim(prim)
1143 u_long  prim;
1144 {
1145         static  char    primbuf[80];
1146
1147         switch ((int)prim) {
1148                 CASERET(DL_INFO_REQ);
1149                 CASERET(DL_INFO_ACK);
1150                 CASERET(DL_ATTACH_REQ);
1151                 CASERET(DL_DETACH_REQ);
1152                 CASERET(DL_BIND_REQ);
1153                 CASERET(DL_BIND_ACK);
1154                 CASERET(DL_UNBIND_REQ);
1155                 CASERET(DL_OK_ACK);
1156                 CASERET(DL_ERROR_ACK);
1157                 CASERET(DL_SUBS_BIND_REQ);
1158                 CASERET(DL_SUBS_BIND_ACK);
1159                 CASERET(DL_UNITDATA_REQ);
1160                 CASERET(DL_UNITDATA_IND);
1161                 CASERET(DL_UDERROR_IND);
1162                 CASERET(DL_UDQOS_REQ);
1163                 CASERET(DL_CONNECT_REQ);
1164                 CASERET(DL_CONNECT_IND);
1165                 CASERET(DL_CONNECT_RES);
1166                 CASERET(DL_CONNECT_CON);
1167                 CASERET(DL_TOKEN_REQ);
1168                 CASERET(DL_TOKEN_ACK);
1169                 CASERET(DL_DISCONNECT_REQ);
1170                 CASERET(DL_DISCONNECT_IND);
1171                 CASERET(DL_RESET_REQ);
1172                 CASERET(DL_RESET_IND);
1173                 CASERET(DL_RESET_RES);
1174                 CASERET(DL_RESET_CON);
1175                 default:
1176                         (void) sprintf(primbuf, "unknown primitive 0x%x", prim);
1177                         return (primbuf);
1178         }
1179 }
1180
1181
1182 char*
1183 dlstate(state)
1184 u_long  state;
1185 {
1186         static  char    statebuf[80];
1187
1188         switch (state) {
1189                 CASERET(DL_UNATTACHED);
1190                 CASERET(DL_ATTACH_PENDING);
1191                 CASERET(DL_DETACH_PENDING);
1192                 CASERET(DL_UNBOUND);
1193                 CASERET(DL_BIND_PENDING);
1194                 CASERET(DL_UNBIND_PENDING);
1195                 CASERET(DL_IDLE);
1196                 CASERET(DL_UDQOS_PENDING);
1197                 CASERET(DL_OUTCON_PENDING);
1198                 CASERET(DL_INCON_PENDING);
1199                 CASERET(DL_CONN_RES_PENDING);
1200                 CASERET(DL_DATAXFER);
1201                 CASERET(DL_USER_RESET_PENDING);
1202                 CASERET(DL_PROV_RESET_PENDING);
1203                 CASERET(DL_RESET_RES_PENDING);
1204                 CASERET(DL_DISCON8_PENDING);
1205                 CASERET(DL_DISCON9_PENDING);
1206                 CASERET(DL_DISCON11_PENDING);
1207                 CASERET(DL_DISCON12_PENDING);
1208                 CASERET(DL_DISCON13_PENDING);
1209                 CASERET(DL_SUBS_BIND_PND);
1210                 default:
1211                         (void) sprintf(statebuf, "unknown state 0x%x", state);
1212                         return (statebuf);
1213         }
1214 }
1215
1216 char*
1217 dlerrno(errno)
1218 u_long  errno;
1219 {
1220         static  char    errnobuf[80];
1221
1222         switch (errno) {
1223                 CASERET(DL_ACCESS);
1224                 CASERET(DL_BADADDR);
1225                 CASERET(DL_BADCORR);
1226                 CASERET(DL_BADDATA);
1227                 CASERET(DL_BADPPA);
1228                 CASERET(DL_BADPRIM);
1229                 CASERET(DL_BADQOSPARAM);
1230                 CASERET(DL_BADQOSTYPE);
1231                 CASERET(DL_BADSAP);
1232                 CASERET(DL_BADTOKEN);
1233                 CASERET(DL_BOUND);
1234                 CASERET(DL_INITFAILED);
1235                 CASERET(DL_NOADDR);
1236                 CASERET(DL_NOTINIT);
1237                 CASERET(DL_OUTSTATE);
1238                 CASERET(DL_SYSERR);
1239                 CASERET(DL_UNSUPPORTED);
1240                 CASERET(DL_UNDELIVERABLE);
1241                 CASERET(DL_NOTSUPPORTED);
1242                 CASERET(DL_TOOMANY);
1243                 CASERET(DL_NOTENAB);
1244                 CASERET(DL_BUSY);
1245                 CASERET(DL_NOAUTO);
1246                 CASERET(DL_NOXIDAUTO);
1247                 CASERET(DL_NOTESTAUTO);
1248                 CASERET(DL_XIDAUTO);
1249                 CASERET(DL_TESTAUTO);
1250                 CASERET(DL_PENDING);
1251
1252                 default:
1253                         (void) sprintf(errnobuf, "unknown dlpi errno 0x%x", errno);
1254                         return (errnobuf);
1255         }
1256 }
1257
1258 char*
1259 dlpromisclevel(level)
1260 u_long  level;
1261 {
1262         static  char    levelbuf[80];
1263
1264         switch (level) {
1265                 CASERET(DL_PROMISC_PHYS);
1266                 CASERET(DL_PROMISC_SAP);
1267                 CASERET(DL_PROMISC_MULTI);
1268                 default:
1269                         (void) sprintf(levelbuf, "unknown promisc level 0x%x", level);
1270                         return (levelbuf);
1271         }
1272 }
1273
1274 char*
1275 dlservicemode(servicemode)
1276 u_long  servicemode;
1277 {
1278         static  char    servicemodebuf[80];
1279
1280         switch (servicemode) {
1281                 CASERET(DL_CODLS);
1282                 CASERET(DL_CLDLS);
1283                 CASERET(DL_CODLS|DL_CLDLS);
1284                 default:
1285                         (void) sprintf(servicemodebuf,
1286                                 "unknown provider service mode 0x%x", servicemode);
1287                         return (servicemodebuf);
1288         }
1289 }
1290
1291 char*
1292 dlstyle(style)
1293 long    style;
1294 {
1295         static  char    stylebuf[80];
1296
1297         switch (style) {
1298                 CASERET(DL_STYLE1);
1299                 CASERET(DL_STYLE2);
1300                 default:
1301                         (void) sprintf(stylebuf, "unknown provider style 0x%x", style);
1302                         return (stylebuf);
1303         }
1304 }
1305
1306 char*
1307 dlmactype(media)
1308 u_long  media;
1309 {
1310         static  char    mediabuf[80];
1311
1312         switch (media) {
1313                 CASERET(DL_CSMACD);
1314                 CASERET(DL_TPB);
1315                 CASERET(DL_TPR);
1316                 CASERET(DL_METRO);
1317                 CASERET(DL_ETHER);
1318                 CASERET(DL_HDLC);
1319                 CASERET(DL_CHAR);
1320                 CASERET(DL_CTCA);
1321                 default:
1322                         (void) sprintf(mediabuf, "unknown media type 0x%x", media);
1323                         return (mediabuf);
1324         }
1325 }
1326
1327 /*VARARGS1*/
1328 err(fmt, a1, a2, a3, a4)
1329 char    *fmt;
1330 char    *a1, *a2, *a3, *a4;
1331 {
1332         (void) fprintf(stderr, fmt, a1, a2, a3, a4);
1333         (void) fprintf(stderr, "\n");
1334         (void) exit(1);
1335 }
1336
1337 syserr(s)
1338 char    *s;
1339 {
1340         (void) perror(s);
1341         exit(1);
1342 }
1343
1344 strioctl(fd, cmd, timout, len, dp)
1345 int     fd;
1346 int     cmd;
1347 int     timout;
1348 int     len;
1349 char    *dp;
1350 {
1351         struct  strioctl        sioc;
1352         int     rc;
1353
1354         sioc.ic_cmd = cmd;
1355         sioc.ic_timout = timout;
1356         sioc.ic_len = len;
1357         sioc.ic_dp = dp;
1358         rc = ioctl(fd, I_STR, &sioc);
1359
1360         if (rc < 0)
1361                 return (rc);
1362         else
1363                 return (sioc.ic_len);
1364 }
1365
1366 #endif /* HAVE_DLPI */