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