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