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