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