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