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# 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
40void
41dlinforeq(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
60void
61dlinfoack(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
89void
90dlattachreq(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
111void
112dlenabmultireq(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
140void
141dldisabmultireq(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
169void
170dlpromisconreq(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
192void
193dlpromiscoff(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
214void
215dlphysaddrreq(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
236void
237dlsetphysaddrreq(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
265void
266dldetachreq(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
285void
286dlbindreq(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
315void
316dlunitdatareq(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
350void
351dlunbindreq(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
370void
371dlokack(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
399void
400dlerrorack(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
428void
429dlbindack(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
454void
455dlphysaddrack(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
480void
481sigalrm()
482{
483	(void) err("sigalrm:  TIMEOUT");
484}
485
486strgetmsg(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
538expecting(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 */
553printdlprim(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 */
657printdlinforeq(dlp)
658	union	DL_primitives	*dlp;
659{
660	(void) printf("DL_INFO_REQ\n");
661}
662
663printdlinfoack(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
700printdlattachreq(dlp)
701	union	DL_primitives	*dlp;
702{
703	(void) printf("DL_ATTACH_REQ:  ppa %d\n",
704		dlp->attach_req.dl_ppa);
705}
706
707printdlokack(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
714printdlerrorack(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
724printdlenabmultireq(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
738printdldisabmultireq(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
752printdlpromisconreq(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
759printdlpromiscoffreq(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
766printdlphysaddrreq(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
773printdlphysaddrack(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
787printdlsetphysaddrreq(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 */
802printdldetachreq(dlp)
803	union	DL_primitives	*dlp;
804{
805	(void) printf("DL_DETACH_REQ\n");
806}
807
808printdlbindreq(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
820printdlbindack(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 */
839printdlunbindreq(dlp)
840	union	DL_primitives	*dlp;
841{
842	(void) printf("DL_UNBIND_REQ\n");
843}
844
845printdlsubsbindreq(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
859printdlsubsbindack(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
873printdlsubsunbindreq(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
887printdlunitdatareq(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
904printdlunitdataind(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
927printdluderrorind(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
944printdltestreq(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
959printdltestind(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
981printdltestres(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
996printdltestcon(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
1018printdlxidreq(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
1033printdlxidind(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
1055printdlxidres(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
1070printdlxidcon(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
1092printdludqosreq(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 */
1103addrtostring(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 */
1121stringtoaddr(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
1144static char
1145hexnibble(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
1156char*
1157dlprim(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
1197char*
1198dlstate(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
1231char*
1232dlerrno(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
1273char*
1274dlpromisclevel(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
1289char*
1290dlservicemode(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
1306char*
1307dlstyle(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
1321char*
1322dlmactype(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*/
1343err(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
1352syserr(s)
1353	char	*s;
1354{
1355	(void) perror(s);
1356	exit(1);
1357}
1358
1359strioctl(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