xref: /openbsd-src/usr.sbin/mopd/mopprobe/mopprobe.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: mopprobe.c,v 1.5 1999/03/27 14:31:22 maja Exp $ */
2 
3 /*
4  * Copyright (c) 1993-96 Mats O Jansson.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Mats O Jansson.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef LINT
33 static char rcsid[] = "$OpenBSD: mopprobe.c,v 1.5 1999/03/27 14:31:22 maja Exp $";
34 #endif
35 
36 /*
37  * mopprobe - MOP Probe Utility
38  *
39  * Usage:	mopprobe -a [ -3 | -4 ] [-v] [-o]
40  *		mopprobe [ -3 | -4 ] [-v] [-o] interface
41  */
42 
43 #include "os.h"
44 #include "common/common.h"
45 #include "common/mopdef.h"
46 #include "common/device.h"
47 #include "common/print.h"
48 #include "common/get.h"
49 #include "common/cmp.h"
50 #include "common/pf.h"
51 #include "common/nmadef.h"
52 
53 /*
54  * The list of all interfaces that are being listened to.  rarp_loop()
55  * "selects" on the descriptors in this list.
56  */
57 struct if_info *iflist;
58 
59 #ifdef NO__P
60 void   Loop	     (/* void */);
61 void   Usage         (/* void */);
62 void   mopProcess    (/* struct if_info *, u_char * */);
63 #else
64 void   Loop	     __P((void));
65 void   Usage         __P((void));
66 void   mopProcess    __P((struct if_info *, u_char *));
67 #endif
68 
69 struct once {
70 	u_char	eaddr[6];		/* Ethernet addr */
71 	struct once *next;		/* Next one */
72 };
73 
74 int     AllFlag = 0;		/* listen on "all" interfaces  */
75 int	Not3Flag = 0;		/* Not MOP V3 messages         */
76 int	Not4Flag = 0;		/* Not MOP V4 messages         */
77 int	VerboseFlag = 0;	/* Print All Announces	       */
78 int     OnceFlag = 0;		/* print only once             */
79 int	promisc = 1;		/* Need promisc mode           */
80 char	*Program;
81 struct once *root = NULL;
82 
83 int
84 main(argc, argv)
85 	int     argc;
86 	char  **argv;
87 {
88 	int     op;
89 	char   *interface;
90 
91 	extern int optind, opterr;
92 
93 	if ((Program = strrchr(argv[0], '/')))
94 		Program++;
95 	else
96 		Program = argv[0];
97 	if (*Program == '-')
98 		Program++;
99 
100 	/* All error reporting is done through syslogs. */
101 	openlog(Program, LOG_PID | LOG_CONS, LOG_DAEMON);
102 
103 	opterr = 0;
104 	while ((op = getopt(argc, argv, "34aov")) != -1) {
105 		switch (op) {
106 		case '3':
107 			Not3Flag++;
108 			break;
109 		case '4':
110 			Not4Flag++;
111 			break;
112 		case 'a':
113 			AllFlag++;
114 			break;
115 		case 'o':
116 			OnceFlag++;
117 			break;
118 		case 'v':
119 			VerboseFlag++;
120 			break;
121 		default:
122 			Usage();
123 			/* NOTREACHED */
124 		}
125 	}
126 	interface = argv[optind++];
127 
128 	if ((AllFlag && interface) ||
129 	    (!AllFlag && interface == 0) ||
130 	    (Not3Flag && Not4Flag))
131 		Usage();
132 
133 	if (AllFlag)
134  		deviceInitAll();
135 	else
136 		deviceInitOne(interface);
137 
138 	Loop();
139 }
140 
141 void
142 Usage()
143 {
144 	(void) fprintf(stderr, "usage: %s -a [ -3 | -4 ] [-v] [-o]\n",Program);
145 	(void) fprintf(stderr, "       %s [ -3 | -4 ] [-v] [-o] interface\n",Program);
146 	exit(1);
147 }
148 
149 /*
150  * Process incomming packages.
151  */
152 void
153 mopProcess(ii, pkt)
154 	struct if_info *ii;
155 	u_char *pkt;
156 {
157 	u_char	*dst, *src, mopcode, tmpc, device, ilen;
158 	u_short	 ptype, moplen = 0, tmps, itype;
159 	int	 index, trans, len, i, hwa = 0;
160 	struct once *o = NULL;
161 
162 	/* We don't known with transport, Guess! */
163 
164 	trans = mopGetTrans(pkt, 0);
165 
166 	/* Ok, return if we don't wan't this message */
167 
168 	if ((trans == TRANS_ETHER) && Not3Flag) return;
169 	if ((trans == TRANS_8023) && Not4Flag)	return;
170 
171 	index = 0;
172 	mopGetHeader(pkt, &index, &dst, &src, &ptype, &len, trans);
173 
174 	/* Ignore our own transmissions */
175 
176 	if (mopCmpEAddr(ii->eaddr,src) == 0)
177 		return;
178 
179 	/* Just check multicast */
180 
181 	if (mopCmpEAddr(rc_mcst,dst) != 0) {
182 		return;
183 	}
184 
185 	switch(ptype) {
186 	case MOP_K_PROTO_RC:
187 		break;
188 	default:
189 		return;
190 	}
191 
192 	if (OnceFlag) {
193 		o = root;
194 		while (o != NULL) {
195 			if (mopCmpEAddr(o->eaddr,src) == 0)
196 				return;
197 			o = o->next;
198 		}
199 		o = (struct once *)malloc(sizeof(*o));
200 		o->eaddr[0] = src[0];
201 		o->eaddr[1] = src[1];
202 		o->eaddr[2] = src[2];
203 		o->eaddr[3] = src[3];
204 		o->eaddr[4] = src[4];
205 		o->eaddr[5] = src[5];
206 		o->next = root;
207 		root = o;
208 	}
209 
210 	moplen  = mopGetLength(pkt, trans);
211 	mopcode	= mopGetChar(pkt,&index);
212 
213 	/* Just process System Information */
214 
215 	if (mopcode != MOP_K_CODE_SID) {
216 		return;
217 	}
218 
219 	tmpc = mopGetChar(pkt,&index);		/* Reserved */
220 	tmps = mopGetShort(pkt,&index);		/* Receipt # */
221 
222 	device = 0;
223 
224 	switch(trans) {
225 	case TRANS_ETHER:
226 		moplen = moplen + 16;
227 		break;
228 	case TRANS_8023:
229 		moplen = moplen + 14;
230 		break;
231 	}
232 
233 	itype = mopGetShort(pkt,&index);
234 
235 	while (index < (int)(moplen)) {
236 		ilen  = mopGetChar(pkt,&index);
237 		switch (itype) {
238 		case 0:
239 			tmpc  = mopGetChar(pkt,&index);
240 			index = index + tmpc;
241 			break;
242 		case MOP_K_INFO_VER:
243 			index = index + 3;
244 			break;
245 		case MOP_K_INFO_MFCT:
246 			index = index + 2;
247 			break;
248 		case MOP_K_INFO_CNU:
249 			index = index + 6;
250 			break;
251 		case MOP_K_INFO_RTM:
252 			index = index + 2;
253 			break;
254 		case MOP_K_INFO_CSZ:
255 			index = index + 2;
256 			break;
257 		case MOP_K_INFO_RSZ:
258 			index = index + 2;
259 			break;
260 		case MOP_K_INFO_HWA:
261 			hwa = index;
262 			index = index + 6;
263 			break;
264 		case MOP_K_INFO_TIME:
265 			index = index + 10;
266 			break;
267 	        case MOP_K_INFO_SOFD:
268 			device = mopGetChar(pkt,&index);
269 			if (VerboseFlag &&
270 			    (device != NMA_C_SOFD_LCS) &&   /* DECserver 100 */
271 			    (device != NMA_C_SOFD_DS2) &&   /* DECserver 200 */
272 			    (device != NMA_C_SOFD_DP2) &&   /* DECserver 250 */
273 			    (device != NMA_C_SOFD_DS3))     /* DECserver 300 */
274 			{
275 				mopPrintHWA(stdout, src);
276 				(void)fprintf(stdout," # ");
277 				mopPrintDevice(stdout, device);
278 				(void)fprintf(stdout," ");
279 				mopPrintHWA(stdout, &pkt[hwa]);
280 				(void)fprintf(stdout,"\n");
281 			}
282 			break;
283 		case MOP_K_INFO_SFID:
284 			tmpc = mopGetChar(pkt,&index);
285 			if ((index > 0) && (index < 17))
286 			  index = index + tmpc;
287 			break;
288 		case MOP_K_INFO_PRTY:
289 			index = index + 1;
290 			break;
291 		case MOP_K_INFO_DLTY:
292 			index = index + 1;
293 			break;
294 	        case MOP_K_INFO_DLBSZ:
295 			index = index + 2;
296 			break;
297 		default:
298 			if (((device = NMA_C_SOFD_LCS) ||   /* DECserver 100 */
299 			     (device = NMA_C_SOFD_DS2) ||   /* DECserver 200 */
300 			     (device = NMA_C_SOFD_DP2) ||   /* DECserver 250 */
301 			     (device = NMA_C_SOFD_DS3)) &&  /* DECserver 300 */
302 			    ((itype > 101) && (itype < 107)))
303 			{
304 				switch (itype) {
305 				case 102:
306 					index = index + ilen;
307 					break;
308 				case 103:
309 					index = index + ilen;
310 					break;
311 				case 104:
312 					index = index + 2;
313 					break;
314 				case 105:
315 					mopPrintHWA(stdout, src);
316 					(void)fprintf(stdout," ");
317 					for (i = 0; i < ilen; i++) {
318 					  (void)fprintf(stdout, "%c",pkt[index+i]);
319 					}
320 					index = index + ilen;
321 					(void)fprintf(stdout, "\n");
322 					break;
323 				case 106:
324 					index = index + ilen;
325 					break;
326 				};
327 			} else {
328 				index = index + ilen;
329 			};
330 		}
331 		itype = mopGetShort(pkt,&index);
332 	}
333 }
334 
335