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