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