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