Blame IbaTools/opapacketcapture/opapacketcapture.c

Packit 857059
/* BEGIN_ICS_COPYRIGHT7 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015-2017, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
      documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT7   ****************************************/
Packit 857059
Packit 857059
/* [ICS VERSION STRING: unknown] */
Packit 857059
Packit 857059
#define _GNU_SOURCE
Packit 857059
#include <stdio.h>
Packit 857059
#include <getopt.h>
Packit 857059
#include <stdlib.h>
Packit 857059
#include <signal.h>
Packit 857059
#include <string.h>
Packit 857059
#include <errno.h>
Packit 857059
#include <sys/time.h>
Packit 857059
#include <sys/types.h>
Packit 857059
#include <sys/stat.h>
Packit 857059
#include <sys/ioctl.h>
Packit 857059
#include <arpa/inet.h>
Packit 857059
#include <fcntl.h>
Packit 857059
#include <unistd.h>
Packit 857059
#include <ctype.h>
Packit 857059
#include <features.h>
Packit 857059
Packit 857059
#include "iba/public/ibyteswap.h"
Packit 857059
#include "iba/stl_types.h"
Packit 857059
#include "iba/ib_mad.h"
Packit 857059
#include "iba/stl_pkt.h"
Packit 857059
#include "opapacketcapture.h"
Packit 857059
#include <umad.h> /* for ioctl commands */
Packit 857059
#include <dirent.h>
Packit 857059
Packit 857059
uint8					*blocks;
Packit 857059
packet					*packets;
Packit 857059
Packit 857059
packet					*freePackets;
Packit 857059
packet					*oldestPacket;
Packit 857059
packet					*newestPacket;
Packit 857059
Packit 857059
uint8					*currentBlock;
Packit 857059
Packit 857059
uint64				 	blocksTableSize;
Packit 857059
uint64			 		numpackets;
Packit 857059
Packit 857059
int				 		numPacketsRead = 0;
Packit 857059
int				 		numPacketsTaken = 0;
Packit 857059
uint64			 		numPacketsMax = (uint64)-1;
Packit 857059
int gotModeArg = 0;
Packit 857059
uint8					mode = 0;
Packit 857059
int				 		numPacketsStored = 0;
Packit 857059
int				 		stopcapture = 0;
Packit 857059
int				 		triggerSeen = 0;
Packit 857059
int				 		afterTriggerPackets = 0;
Packit 857059
Packit 857059
uint32					alarmArg = 0;
Packit 857059
char					filterFileArg[256];
Packit 857059
char					triggerFileArg[256];
Packit 857059
int						triggerLag = DEFAULT_TRIGGER_LAG;
Packit 857059
int						gotFilterFileArg = 0;
Packit 857059
int						gotTriggerFileArg = 0;
Packit 857059
int						gotAlarmArg = 0;
Packit 857059
int						gotTriggerLagArg = 0;
Packit 857059
int						writethrough = 0;
Packit 857059
int						retryCount;
Packit 857059
Packit 857059
filterFunc_t			filters[25];
Packit 857059
filterFunc_t			triggers[25];
Packit 857059
Packit 857059
int						numFilterFunctions = 0;
Packit 857059
int						numTriggerFunctions = 0;
Packit 857059
Packit 857059
int						filterCondition;
Packit 857059
int						gotCondition = 0;
Packit 857059
int						triggerCondition;
Packit 857059
int						gotTriggerCondition = 0;
Packit 857059
Packit 857059
int						gotdevfile;
Packit 857059
int						gotoutfile;
Packit 857059
char					devfile[256];
Packit 857059
char					out_file[256];
Packit 857059
int						fdIn;
Packit 857059
Packit 857059
int						ioctlConfigured = 0;
Packit 857059
qibPacketFilterCommand_t	filterCmd;
Packit 857059
uint32					filterValue;
Packit 857059
Packit 857059
int						verbose = 0;
Packit 857059
Packit 857059
static void my_handler(int signal)
Packit 857059
{
Packit 857059
	stopcapture = 1;
Packit 857059
	printf("\nopapacketcapture: Triggered\n");
Packit 857059
}
Packit 857059
Packit 857059
boolean isWfrPacketBypass(packet *p) {
Packit 857059
	WFR_SnC_HDR *wfr_hdr = NULL;
Packit 857059
	boolean res = 0;
Packit 857059
Packit 857059
	wfr_hdr = (WFR_SnC_HDR *)(&blocks[p->blockNum * BLOCKSIZE]);
Packit 857059
Packit 857059
	if (wfr_hdr->Direction == STL_WFR_OUTBOUND) {
Packit 857059
		res = (boolean) wfr_hdr->u.PBC.s.pbcpacketbypass;
Packit 857059
	} else if (wfr_hdr->Direction == STL_WFR_INBOUND) {
Packit 857059
		res = (wfr_hdr->u.RHF.s.rcvtype == STL_WFR_RCV_BYPASS);
Packit 857059
	}
Packit 857059
	return res;
Packit 857059
}
Packit 857059
Packit 857059
boolean is9BWfrPacket(packet *p) {
Packit 857059
	WFR_SnC_HDR *wfr_hdr = NULL;
Packit 857059
	boolean res = 0;
Packit 857059
Packit 857059
	wfr_hdr = (WFR_SnC_HDR *)(&blocks[p->blockNum * BLOCKSIZE]);
Packit 857059
Packit 857059
	if (wfr_hdr->Direction == STL_WFR_OUTBOUND) {
Packit 857059
		res = !((boolean)wfr_hdr->u.PBC.s.pbcpacketbypass);
Packit 857059
	} else if (wfr_hdr->Direction == STL_WFR_INBOUND) {
Packit 857059
		res = (wfr_hdr->u.RHF.s.rcvtype == STL_WFR_RCV_IB);
Packit 857059
	}
Packit 857059
	return res;
Packit 857059
}
Packit 857059
Packit 857059
boolean is16BWfrPacket(packet *p) {
Packit 857059
	boolean ret = 0;
Packit 857059
	STL_16B_HDR *lrh = NULL;
Packit 857059
	if (isWfrPacketBypass(p)) {
Packit 857059
		lrh = (STL_16B_HDR *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
		if (lrh->u1.s.L2 == STL_L2_16B) {
Packit 857059
			ret = 1;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
boolean hasBTH(packet *p) {
Packit 857059
	boolean ret = 0;
Packit 857059
	STL_16B_HDR *lrh_16 = NULL;
Packit 857059
	IB_LRH *lrh_9 = NULL;
Packit 857059
	if (is9BWfrPacket(p)) {
Packit 857059
		lrh_9 = (IB_LRH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) );
Packit 857059
		if (lrh_9->l.LNH == STL_9B_LNH_BTH) {
Packit 857059
			ret = 1;
Packit 857059
		}
Packit 857059
	} else if (is16BWfrPacket(p)) {
Packit 857059
		lrh_16 = (STL_16B_HDR *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
		if (lrh_16->L4 == STL_16B_L4_IB) {
Packit 857059
			ret = 1;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
IB_BTH *get9BTH(packet *p) {
Packit 857059
	IB_BTH *bth_9 = NULL;
Packit 857059
Packit 857059
	bth_9 = (IB_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) + sizeof(IB_LRH) );
Packit 857059
Packit 857059
	return bth_9;
Packit 857059
}
Packit 857059
Packit 857059
STL_16B_BTH *get16BTH(packet *p) {
Packit 857059
	STL_16B_BTH *bth_16 = NULL;
Packit 857059
Packit 857059
	bth_16 = (STL_16B_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR) + sizeof(STL_16B_HDR) );
Packit 857059
Packit 857059
	return bth_16;
Packit 857059
}
Packit 857059
Packit 857059
uint16 getPkey(packet *p) {
Packit 857059
	STL_16B_HDR *lrh_16_raw = NULL;
Packit 857059
	STL_16B_HDR lrh_16;
Packit 857059
	IB_LRH *lrh_9 = NULL;
Packit 857059
	IB_BTH *bth_9 = NULL;
Packit 857059
	uint16 ret = 0;
Packit 857059
Packit 857059
	if (is9BWfrPacket(p)) {
Packit 857059
		lrh_9 = (IB_LRH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) );
Packit 857059
		if (lrh_9->l.LNH == STL_9B_LNH_BTH) {
Packit 857059
			bth_9 = (IB_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) + sizeof(IB_LRH) );
Packit 857059
			ret = ntoh16(bth_9->Pkey);
Packit 857059
		}
Packit 857059
	} else if (is16BWfrPacket(p)) {
Packit 857059
		lrh_16_raw = (STL_16B_HDR *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
		memcpy((void *)&lrh_16, (void *)lrh_16_raw, sizeof(STL_16B_HDR));
Packit 857059
		BSWAP_STL_16B_HDR(&lrh_16);
Packit 857059
		ret = lrh_16.Pkey;
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
uint8 getOpCode(packet *p) {
Packit 857059
	uint8 ret = 0;
Packit 857059
	STL_16B_BTH *bth_16 = NULL;
Packit 857059
	IB_BTH *bth_9 = NULL;
Packit 857059
Packit 857059
	if (hasBTH(p)) {
Packit 857059
		if (is9BWfrPacket(p)) {
Packit 857059
			bth_9 = (IB_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) + sizeof(IB_LRH) );
Packit 857059
			ret = bth_9->OpCode;
Packit 857059
		} else if (is16BWfrPacket(p)) {
Packit 857059
			bth_16 = (STL_16B_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR) + sizeof(STL_16B_HDR) );
Packit 857059
			ret = bth_16->OpCode;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
uint32 getDestQp(packet *p) {
Packit 857059
	uint32 ret = 0;
Packit 857059
	STL_16B_BTH *bth_16 = NULL;
Packit 857059
	IB_BTH *bth_9 = NULL;
Packit 857059
Packit 857059
	if (hasBTH(p)) {
Packit 857059
		if (is9BWfrPacket(p)) {
Packit 857059
			bth_9 = (IB_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) + sizeof(IB_LRH) );
Packit 857059
			ret = ntoh32(bth_9->Qp.AsUINT32);
Packit 857059
		} else if (is16BWfrPacket(p)) {
Packit 857059
			bth_16 = (STL_16B_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR) + sizeof(STL_16B_HDR) );
Packit 857059
			ret = ntoh32(bth_16->Qp.AsReg32);
Packit 857059
		}
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
boolean isMAD(packet *p) {
Packit 857059
	boolean ret = 0;
Packit 857059
	STL_16B_HDR *lrh_16 = NULL;
Packit 857059
	STL_16B_BTH *bth_16 = NULL;
Packit 857059
	IB_BTH *bth_9 = NULL;
Packit 857059
Packit 857059
	if (hasBTH(p)) {
Packit 857059
		if (is9BWfrPacket(p)) {
Packit 857059
			bth_9 = (IB_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) + sizeof(IB_LRH) );
Packit 857059
			if (bth_9->Qp.s.DestQPNumber == 0 || bth_9->Qp.s.DestQPNumber == 1) {
Packit 857059
				ret = 1;
Packit 857059
			}
Packit 857059
		} else if (is16BWfrPacket(p)) {
Packit 857059
			bth_16 = (STL_16B_BTH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR) + sizeof(STL_16B_HDR) );
Packit 857059
			if (bth_16->Qp.s.DestQPNumber == 0 || bth_16->Qp.s.DestQPNumber == 1) {
Packit 857059
				ret = 1;
Packit 857059
			}
Packit 857059
		}
Packit 857059
	} else { /* Could still be a MAD packet even w/o a BTH */
Packit 857059
		if (is16BWfrPacket(p)) { /* Check for 16B MAD packet w/o BTH */
Packit 857059
			lrh_16 = (STL_16B_HDR *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
			if (lrh_16->u1.s.L2 == STL_16B_L4_FM) {
Packit 857059
				ret = 1;
Packit 857059
			}
Packit 857059
		}
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
MAD_COMMON *getMAD(packet *p) {
Packit 857059
	STL_16B_HDR *lrh_16 = NULL;
Packit 857059
	MAD_COMMON *m = NULL;
Packit 857059
Packit 857059
	if (hasBTH(p)) {
Packit 857059
		if (is9BWfrPacket(p)) {
Packit 857059
			m = (MAD_COMMON *)((uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR) + sizeof(IB_LRH) + sizeof(IB_BTH) + sizeof(IB_DETH));
Packit 857059
		} else if (is16BWfrPacket(p)) {
Packit 857059
			m = (MAD_COMMON *)((uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR) + sizeof(STL_16B_HDR) + sizeof(STL_16B_BTH) + sizeof(IB_DETH));
Packit 857059
		}
Packit 857059
	} else { /* Could still be a MAD packet even w/o a BTH */
Packit 857059
		if (is16BWfrPacket(p)) { /* Check for 16B MAD packet w/o BTH */
Packit 857059
			lrh_16 = (STL_16B_HDR *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
			if (lrh_16->u1.s.L2 == STL_16B_L4_FM) {
Packit 857059
				m = (MAD_COMMON *)((uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR) + sizeof(STL_16B_HDR) + STL_16B_L4_FM_SIZE);
Packit 857059
			}
Packit 857059
		}
Packit 857059
	}
Packit 857059
	return m;
Packit 857059
}
Packit 857059
Packit 857059
STL_LID getSLID(packet *p) {
Packit 857059
	STL_16B_HDR *lrh_16_raw = NULL;
Packit 857059
	STL_16B_HDR lrh_16;
Packit 857059
	IB_LRH *lrh_9 = NULL;
Packit 857059
Packit 857059
	STL_LID ret = 0;
Packit 857059
Packit 857059
	if (is9BWfrPacket(p)) {
Packit 857059
		lrh_9 = (IB_LRH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) );
Packit 857059
		if (lrh_9->l.LNH == STL_9B_LNH_BTH) {
Packit 857059
			ret = (STL_LID)ntoh16(lrh_9->SrcLID);
Packit 857059
		}
Packit 857059
	} else if (is16BWfrPacket(p)) {
Packit 857059
		lrh_16_raw = (STL_16B_HDR *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
		memcpy((void *)&lrh_16, (void *)lrh_16_raw, sizeof(STL_16B_HDR));
Packit 857059
		BSWAP_STL_16B_HDR(&lrh_16);
Packit 857059
		ret = ((lrh_16.u3.s.SLID_23_20 << 20) | lrh_16.u2.s.SLID_19_0);
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
STL_LID getDLID(packet *p) {
Packit 857059
	STL_16B_HDR *lrh_16_raw = NULL;
Packit 857059
	STL_16B_HDR lrh_16;
Packit 857059
	IB_LRH *lrh_9 = NULL;
Packit 857059
Packit 857059
	STL_LID ret = 0;
Packit 857059
Packit 857059
	if (is9BWfrPacket(p)) {
Packit 857059
		lrh_9 = (IB_LRH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) );
Packit 857059
		if (lrh_9->l.LNH == STL_9B_LNH_BTH) {
Packit 857059
			ret = (STL_LID)ntoh16(lrh_9->DestLID);
Packit 857059
		}
Packit 857059
	} else if (is16BWfrPacket(p)) {
Packit 857059
		lrh_16_raw = (STL_16B_HDR *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
		memcpy((void *)&lrh_16, (void *)lrh_16_raw, sizeof(STL_16B_HDR));
Packit 857059
		BSWAP_STL_16B_HDR(&lrh_16);
Packit 857059
		ret = ((lrh_16.u3.s.DLID_23_20 << 20) | lrh_16.u1.s.DLID_19_0);
Packit 857059
	}
Packit 857059
	return ret;
Packit 857059
}
Packit 857059
Packit 857059
int filterSLID(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	STL_LID slid = 0;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	slid = getSLID(p);
Packit 857059
Packit 857059
	res = (slid == (STL_LID)val);
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterDLID(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	STL_LID dlid = 0;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	dlid = getDLID(p);
Packit 857059
Packit 857059
	res = (dlid == (STL_LID)val);
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterServiceLevel(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	uint8 sl = (uint8)val;
Packit 857059
	IB_LRH *lrh;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	if (!is9BWfrPacket(p)) {
Packit 857059
		return res;
Packit 857059
	}
Packit 857059
Packit 857059
	lrh = (IB_LRH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE])  + sizeof(WFR_SnC_HDR) );
Packit 857059
Packit 857059
	res = (lrh->l.ServiceLevel == sl);
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterMgmtClass(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	uint8 mc = (uint8)val;
Packit 857059
	MAD_COMMON *m;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	if (!isMAD(p)) {
Packit 857059
		return res;
Packit 857059
	}
Packit 857059
Packit 857059
	m = getMAD(p);
Packit 857059
	if (m) {
Packit 857059
		res = (m->MgmtClass == mc);
Packit 857059
	}
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterPKey(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	uint16 pkey = (uint16)val;
Packit 857059
	uint16 Pkey = 0;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	Pkey = getPkey(p);
Packit 857059
Packit 857059
	res = ((Pkey & PKEY_MASK) == (pkey & PKEY_MASK));
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterPacketType(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	uint8 pktType = (uint8)val;
Packit 857059
	uint8 opCode = 0;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	opCode = getOpCode(p);
Packit 857059
Packit 857059
	res = ((opCode>>5) == pktType);
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterAttrID(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	uint16 aid = (uint16)val;
Packit 857059
	MAD_COMMON *m;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	if (!isMAD(p)) {
Packit 857059
		return res;
Packit 857059
	}
Packit 857059
Packit 857059
	m = getMAD(p);
Packit 857059
	if (m) {
Packit 857059
		res = (ntoh16(m->AttributeID) == aid);
Packit 857059
	}
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterTransactionIDLow(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	MAD_COMMON *m;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	if (!isMAD(p)) {
Packit 857059
		return res;
Packit 857059
	}
Packit 857059
Packit 857059
	m = getMAD(p);
Packit 857059
	if (m) {
Packit 857059
		res = ((uint32)(ntoh64(m->TransactionID) & 0xffffffff) == val);
Packit 857059
	}
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterTransactionIDHigh(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	MAD_COMMON *m;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	if (!isMAD(p)) {
Packit 857059
		return res;
Packit 857059
	}
Packit 857059
Packit 857059
	m = getMAD(p);
Packit 857059
	if (m) {
Packit 857059
		res = ((uint32)((ntoh64(m->TransactionID) >> 32) & 0xffffffff) == val);
Packit 857059
	}
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int filterQueuePair(packet *p, uint32 val)
Packit 857059
{
Packit 857059
	uint32 qp = val;
Packit 857059
	uint32 pkt_qp = 0;
Packit 857059
	int res = 0;
Packit 857059
Packit 857059
	if (!hasBTH(p)) {
Packit 857059
		return res;
Packit 857059
	}
Packit 857059
Packit 857059
	pkt_qp = getDestQp(p);
Packit 857059
	pkt_qp = pkt_qp & DESTQP_MASK;
Packit 857059
	res = (pkt_qp == qp);
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int applyFilters(packet *p)
Packit 857059
{
Packit 857059
	int res;
Packit 857059
	int i;
Packit 857059
Packit 857059
	res = (filterCondition == COND_TYPE_AND) ? 1 : 0;
Packit 857059
Packit 857059
	for (i = 0; (i < numFilterFunctions) && ((filterCondition == COND_TYPE_AND) ? res : !res); i++) {
Packit 857059
		if (!filters[i].ioctl) {
Packit 857059
			// XOR result with notFlag
Packit 857059
			res = filters[i].filterFunc(p, filters[i].filterVal) ^ filters[i].notFlag;
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int applyTriggers(packet *p)
Packit 857059
{
Packit 857059
	int res;
Packit 857059
	int i;
Packit 857059
Packit 857059
	res = (triggerCondition == COND_TYPE_AND) ? 1 : 0;
Packit 857059
Packit 857059
	for (i = 0; (i < numTriggerFunctions) && ((triggerCondition == COND_TYPE_AND) ? res : !res); i++) {
Packit 857059
		res = triggers[i].filterFunc(p, triggers[i].filterVal) ^ triggers[i].notFlag;
Packit 857059
	}
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int getFilterType(char *filter)
Packit 857059
{
Packit 857059
	int res;
Packit 857059
	if (!strcmp(filter, "COND"))
Packit 857059
		res = FILTER_COND;
Packit 857059
	else if (!strcmp(filter, "DLID"))
Packit 857059
		res = FILTER_DLID;
Packit 857059
	else if (!strcmp(filter, "SLID"))
Packit 857059
		res = FILTER_SLID;
Packit 857059
	else if (!strcmp(filter, "MCLASS"))
Packit 857059
		res = FILTER_MCLASS;
Packit 857059
	else if (!strcmp(filter, "PKEY"))
Packit 857059
		res = FILTER_PKEY;
Packit 857059
	else if (!strcmp(filter, "PTYPE"))
Packit 857059
		res = FILTER_PTYPE;
Packit 857059
	else if (!strcmp(filter, "SVCLEV"))
Packit 857059
		res = FILTER_SVCLEV;
Packit 857059
	else if (!strcmp(filter, "ATTRID"))
Packit 857059
		res = FILTER_ATTRID;
Packit 857059
	else if (!strcmp(filter, "QP"))
Packit 857059
		res = FILTER_QP;
Packit 857059
	else if (!strcmp(filter, "TRANSIDH"))
Packit 857059
		res = FILTER_TRANS_ID_HIGH;
Packit 857059
	else if (!strcmp(filter, "TRANSIDL"))
Packit 857059
		res = FILTER_TRANS_ID_LOW;
Packit 857059
	else
Packit 857059
		res = -1;
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int getPacketType(char *filter)
Packit 857059
{
Packit 857059
	int res;
Packit 857059
	if (!strcmp(filter, "RC"))
Packit 857059
		res = PACKETTYPE_RC;
Packit 857059
	else if (!strcmp(filter, "UC"))
Packit 857059
		res = PACKETTYPE_UC;
Packit 857059
	else if (!strcmp(filter, "RD"))
Packit 857059
		res = PACKETTYPE_RD;
Packit 857059
	else if (!strcmp(filter, "UD"))
Packit 857059
		res = PACKETTYPE_UD;
Packit 857059
	else
Packit 857059
		res = PACKETTYPE_ERR;
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
int getCondType(char *condition)
Packit 857059
{
Packit 857059
	int res;
Packit 857059
	if (!strcmp(condition, "AND"))
Packit 857059
		res = COND_TYPE_AND;
Packit 857059
	else if (!strcmp(condition, "OR"))
Packit 857059
		res = COND_TYPE_OR;
Packit 857059
	else
Packit 857059
		res = -1;
Packit 857059
Packit 857059
	return(res);
Packit 857059
}
Packit 857059
Packit 857059
void setupIoctl(int filter, uint32 *valPtr)
Packit 857059
{
Packit 857059
	filterCmd.value_ptr = (void *)valPtr;
Packit 857059
	switch (filter) {
Packit 857059
		case FILTER_DLID:
Packit 857059
			filterCmd.opcode = FILTER_BY_DLID;
Packit 857059
			filterCmd.length = sizeof(uint16);
Packit 857059
			break;
Packit 857059
		case FILTER_SLID:
Packit 857059
			filterCmd.opcode = FILTER_BY_LID;
Packit 857059
			filterCmd.length = sizeof(uint16);
Packit 857059
			break;
Packit 857059
		case FILTER_MCLASS:
Packit 857059
			filterCmd.opcode = FILTER_BY_MAD_MGMT_CLASS;
Packit 857059
			filterCmd.length = sizeof(uint8);
Packit 857059
			break;
Packit 857059
		case FILTER_PKEY:
Packit 857059
			filterCmd.opcode = FILTER_BY_PKEY;
Packit 857059
			filterCmd.length = sizeof(uint16);
Packit 857059
			break;
Packit 857059
		case FILTER_PTYPE:
Packit 857059
			filterCmd.opcode = FILTER_BY_PKT_TYPE;
Packit 857059
			filterCmd.length = sizeof(uint8);
Packit 857059
			break;
Packit 857059
		case FILTER_SVCLEV:
Packit 857059
			filterCmd.opcode = FILTER_BY_SERVICE_LEVEL;
Packit 857059
			filterCmd.length = sizeof(uint8);
Packit 857059
			break;
Packit 857059
		case FILTER_ATTRID:
Packit 857059
			/* not supported in driver */
Packit 857059
			fprintf(stderr, "Error: filter on attribute ID not supported in qib driver\n");
Packit 857059
			exit(1);
Packit 857059
			break;
Packit 857059
		case FILTER_TRANS_ID_HIGH:
Packit 857059
			/* not supported in driver */
Packit 857059
			fprintf(stderr, "Error: filter on transaction ID high not supported in qib driver\n");
Packit 857059
			exit(1);
Packit 857059
			break;
Packit 857059
		case FILTER_TRANS_ID_LOW:
Packit 857059
			/* not supported in driver */
Packit 857059
			fprintf(stderr, "Error: filter on transaction ID low not supported in qib driver\n");
Packit 857059
			exit(1);
Packit 857059
			break;
Packit 857059
		case FILTER_QP:
Packit 857059
			filterCmd.opcode = FILTER_BY_QP_NUMBER;
Packit 857059
			filterCmd.length = sizeof(uint32);
Packit 857059
			break;
Packit 857059
	}
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
void setupFilters(char *filterFile)
Packit 857059
{
Packit 857059
	FILE *fp;
Packit 857059
	char inbuf[128];
Packit 857059
	char *p;
Packit 857059
	char *p1;
Packit 857059
	char filterType[10];
Packit 857059
	int filter;
Packit 857059
	uint32 val;
Packit 857059
	char strVal[10];
Packit 857059
	int not;
Packit 857059
Packit 857059
	if ((fp = fopen(filterFile, "r")) == NULL) {
Packit 857059
		fprintf(stderr, "Error opening file <%s> for input: %s\n", filterFile, strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
Packit 857059
	while (fgets(inbuf, 128, fp) != NULL) {
Packit 857059
		p = inbuf;
Packit 857059
		if (*p == '#')
Packit 857059
			continue;
Packit 857059
		if (*p == '\n')
Packit 857059
			continue;
Packit 857059
		if (*p == ' ')
Packit 857059
			continue;
Packit 857059
		if ((*p == '!') || (*p == '~')) {
Packit 857059
			not = 1;
Packit 857059
			p++;
Packit 857059
		} else
Packit 857059
			not = 0;
Packit 857059
		if ((p1 = strchr(p, '#')) != NULL)
Packit 857059
			*p1 = '\0';
Packit 857059
		sscanf(p, "%9s", filterType);
Packit 857059
		if ((filter = getFilterType(filterType)) < 0) {
Packit 857059
			fprintf(stderr, "Invalid filter type %s\n", filterType);
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
		switch (filter) {
Packit 857059
			case FILTER_DLID:
Packit 857059
				sscanf(p, "%9s %u", filterType, &val;;
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterDLID;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = val;
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_SLID:
Packit 857059
				sscanf(p, "%9s %u", filterType, &val;;
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterSLID;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = val;
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_MCLASS:
Packit 857059
				sscanf(p, "%9s %u", filterType, &val;;
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterMgmtClass;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = val;
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_PKEY:
Packit 857059
				sscanf(p, "%9s 0x%x", filterType, &val;;
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterPKey;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = (val & PKEY_MASK);
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_PTYPE:
Packit 857059
				sscanf(p, "%9s %9s", filterType, strVal);
Packit 857059
				if ((val = getPacketType(strVal)) == PACKETTYPE_ERR) {
Packit 857059
					fprintf(stderr, "Invalid packet type %s\n", strVal);
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterPacketType;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = val;
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_SVCLEV:
Packit 857059
				sscanf(p, "%9s %u", filterType, &val;;
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterServiceLevel;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = val;
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_ATTRID:
Packit 857059
				sscanf(p, "%9s %9s", filterType, strVal);
Packit 857059
				if (strstr(strVal, "0x") != NULL) {
Packit 857059
					sscanf(p, "%9s 0x%x", strVal, &val;;
Packit 857059
				} else {
Packit 857059
					sscanf(p, "%9s %u", strVal, &val;;
Packit 857059
				}
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterAttrID;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
#if 0 /* filter on attribute id not supported in driver */
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = val;
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
#endif
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_TRANS_ID_HIGH:
Packit 857059
				sscanf(p, "%9s %9s", filterType, strVal);
Packit 857059
				if (strstr(strVal, "0x") != NULL) {
Packit 857059
					sscanf(p, "%9s 0x%x", strVal, &val;;
Packit 857059
				} else {
Packit 857059
					sscanf(p, "%9s %u", strVal, &val;;
Packit 857059
				}
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterTransactionIDHigh;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_TRANS_ID_LOW:
Packit 857059
				sscanf(p, "%9s %9s", filterType, strVal);
Packit 857059
				if (strstr(strVal, "0x") != NULL) {
Packit 857059
					sscanf(p, "%9s 0x%x", strVal, &val;;
Packit 857059
				} else {
Packit 857059
					sscanf(p, "%9s %u", strVal, &val;;
Packit 857059
				}
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterTransactionIDLow;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_QP:
Packit 857059
				sscanf(p, "%9s %u", filterType, &val;;
Packit 857059
				filters[numFilterFunctions].filterFunc = &filterQueuePair;
Packit 857059
				filters[numFilterFunctions].filterVal = val;
Packit 857059
				filters[numFilterFunctions].ioctl = 0;
Packit 857059
				filters[numFilterFunctions].notFlag = not;
Packit 857059
				if (!ioctlConfigured && !not) {
Packit 857059
					ioctlConfigured = 1;
Packit 857059
					filterValue = val;
Packit 857059
					setupIoctl(filter, &filterValue);
Packit 857059
					filters[numFilterFunctions].ioctl = 1;
Packit 857059
				}
Packit 857059
				numFilterFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_COND:
Packit 857059
				if (not) {
Packit 857059
					fprintf(stderr, "Not sign not allowed on condition\n");
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				if (gotCondition) {
Packit 857059
					fprintf(stderr, "Only one condition statement allowed\n");
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				gotCondition = 1;
Packit 857059
				sscanf(p, "%9s %9s", filterType, strVal);
Packit 857059
				if ((filterCondition = getCondType(strVal)) < 0) {
Packit 857059
					fprintf(stderr, "Invalid condition type %s\n", strVal);
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				break;
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	fclose(fp);
Packit 857059
Packit 857059
	/* if condition is OR, turn off ioctl */
Packit 857059
	if (filterCondition == COND_TYPE_OR) {
Packit 857059
		int i;
Packit 857059
		ioctlConfigured = 0;
Packit 857059
		for (i = 0; i <= numFilterFunctions; i++)
Packit 857059
			filters[i].ioctl = 0;
Packit 857059
	}
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
void setupTriggers(char *triggerFile)
Packit 857059
{
Packit 857059
	FILE *fp;
Packit 857059
	char inbuf[128];
Packit 857059
	char *p;
Packit 857059
	char *p1;
Packit 857059
	char triggerType[10];
Packit 857059
	int trigger;
Packit 857059
	uint32 val;
Packit 857059
	char strVal[10];
Packit 857059
	int not;
Packit 857059
Packit 857059
	if ((fp = fopen(triggerFile, "r")) == NULL) {
Packit 857059
		fprintf(stderr, "Error opening file <%s> for input: %s\n", triggerFile, strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
Packit 857059
	while (fgets(inbuf, 128, fp) != NULL) {
Packit 857059
		p = inbuf;
Packit 857059
		if (*p == '#')
Packit 857059
			continue;
Packit 857059
		if (*p == '\n')
Packit 857059
			continue;
Packit 857059
		if (*p == ' ')
Packit 857059
			continue;
Packit 857059
		if ((*p == '!') || (*p == '~')) {
Packit 857059
			not = 1;
Packit 857059
			p++;
Packit 857059
		} else
Packit 857059
			not = 0;
Packit 857059
		if ((p1 = strchr(p, '#')) != NULL)
Packit 857059
			*p1 = '\0';
Packit 857059
		sscanf(p, "%9s", triggerType);
Packit 857059
		if ((trigger = getFilterType(triggerType)) < 0) {
Packit 857059
			fprintf(stderr, "Invalid trigger type %s\n", triggerType);
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
		switch (trigger) {
Packit 857059
			case FILTER_DLID:
Packit 857059
				sscanf(p, "%9s %u", triggerType, &val;;
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterDLID;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_SLID:
Packit 857059
				sscanf(p, "%9s %u", triggerType, &val;;
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterSLID;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_MCLASS:
Packit 857059
				sscanf(p, "%9s %u", triggerType, &val;;
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterMgmtClass;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_PKEY:
Packit 857059
				sscanf(p, "%9s 0x%x", triggerType, &val;;
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterPKey;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_PTYPE:
Packit 857059
				sscanf(p, "%9s %9s", triggerType, strVal);
Packit 857059
				if ((val = getPacketType(strVal)) == PACKETTYPE_ERR) {
Packit 857059
					fprintf(stderr, "Invalid packet type %s\n", strVal);
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterPacketType;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_SVCLEV:
Packit 857059
				sscanf(p, "%9s %u", triggerType, &val;;
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterServiceLevel;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_ATTRID:
Packit 857059
				sscanf(p, "%9s %9s", triggerType, strVal);
Packit 857059
				if (strstr(strVal, "0x") != NULL) {
Packit 857059
					sscanf(p, "%9s 0x%x", strVal, &val;;
Packit 857059
				} else {
Packit 857059
					sscanf(p, "%9s %u", strVal, &val;;
Packit 857059
				}
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterAttrID;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_TRANS_ID_HIGH:
Packit 857059
				sscanf(p, "%9s %9s", triggerType, strVal);
Packit 857059
				if (strstr(strVal, "0x") != NULL) {
Packit 857059
					sscanf(p, "%9s 0x%x", strVal, &val;;
Packit 857059
				} else {
Packit 857059
					sscanf(p, "%9s %u", strVal, &val;;
Packit 857059
				}
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterTransactionIDHigh;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_TRANS_ID_LOW:
Packit 857059
				sscanf(p, "%9s %9s", triggerType, strVal);
Packit 857059
				if (strstr(strVal, "0x") != NULL) {
Packit 857059
					sscanf(p, "%9s 0x%x", strVal, &val;;
Packit 857059
				} else {
Packit 857059
					sscanf(p, "%9s %u", strVal, &val;;
Packit 857059
				}
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterTransactionIDLow;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_QP:
Packit 857059
				sscanf(p, "%9s %u", triggerType, &val;;
Packit 857059
				triggers[numTriggerFunctions].filterFunc = &filterQueuePair;
Packit 857059
				triggers[numTriggerFunctions].filterVal = val;
Packit 857059
				triggers[numTriggerFunctions].ioctl = 0;
Packit 857059
				triggers[numTriggerFunctions].notFlag = not;
Packit 857059
				numTriggerFunctions++;
Packit 857059
				break;
Packit 857059
			case FILTER_COND:
Packit 857059
				if (not) {
Packit 857059
					fprintf(stderr, "Not sign not allowed on condition\n");
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				if (gotCondition) {
Packit 857059
					fprintf(stderr, "Only one condition statement allowed\n");
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				gotTriggerCondition = 1;
Packit 857059
				sscanf(p, "%9s %9s", triggerType, strVal);
Packit 857059
				if ((triggerCondition = getCondType(strVal)) < 0) {
Packit 857059
					fprintf(stderr, "Invalid condition type %s\n", strVal);
Packit 857059
					exit(1);
Packit 857059
				}
Packit 857059
				break;
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	fclose(fp);
Packit 857059
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
void growPacketTable()
Packit 857059
{
Packit 857059
	packet		*newPackets;
Packit 857059
	int			i;
Packit 857059
	uint32		newNumPackets;
Packit 857059
	uint32		index;
Packit 857059
Packit 857059
	// grow by a quarter
Packit 857059
	newNumPackets = numpackets * 1.25;
Packit 857059
	newPackets = (packet *)malloc(newNumPackets * sizeof(packet));
Packit 857059
	if (newPackets == NULL) {
Packit 857059
		fprintf(stderr, "opapacketcapture: Error allocating new packets array: %s\n", strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
Packit 857059
	// copy in current table
Packit 857059
	memcpy(newPackets, packets, numpackets * sizeof(packet));
Packit 857059
Packit 857059
	// adjust next pointers
Packit 857059
	for (i = 0; i < (numpackets-1); i++) {
Packit 857059
		index = (uint32)(packets[i].next - packets);
Packit 857059
		newPackets[i].next = newPackets + index;
Packit 857059
	}
Packit 857059
Packit 857059
	// initialize rest of table
Packit 857059
	for (i = (numpackets - 1); i < (newNumPackets - 1); i++)
Packit 857059
		newPackets[i].next = &newPackets[i+1];
Packit 857059
	newPackets[newNumPackets-1].next = NULL;
Packit 857059
Packit 857059
	// reassign free/oldest/newest pointers
Packit 857059
	index = (uint32)(freePackets - packets);
Packit 857059
	freePackets = newPackets + index;
Packit 857059
	index = (uint32)(oldestPacket - packets);
Packit 857059
	oldestPacket = newPackets + index;
Packit 857059
	index = (uint32)(newestPacket - packets);
Packit 857059
	newestPacket = newPackets + index;
Packit 857059
Packit 857059
	// free old table and reset pointer
Packit 857059
	free(packets);
Packit 857059
	packets = newPackets;
Packit 857059
	numpackets = newNumPackets;
Packit 857059
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
packet *getPacket()
Packit 857059
{
Packit 857059
	packet *ret;
Packit 857059
Packit 857059
	if (freePackets->next == NULL)
Packit 857059
		growPacketTable();
Packit 857059
	ret = freePackets;
Packit 857059
	freePackets = freePackets->next;
Packit 857059
	numPacketsTaken++;
Packit 857059
Packit 857059
	return(ret);
Packit 857059
}
Packit 857059
Packit 857059
void returnPacket(packet *p)
Packit 857059
{
Packit 857059
	p->next = freePackets;
Packit 857059
	freePackets = p;
Packit 857059
	numPacketsTaken--;
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
void addNewPacket(packet *p)
Packit 857059
{
Packit 857059
	int done;
Packit 857059
	packet *p1;
Packit 857059
	packet *formerNewestPacket;
Packit 857059
	int overlap;
Packit 857059
	int myEndBlockNum = p->blockNum + p->numBlocks - 1;
Packit 857059
	int oldestEndBlockNum;
Packit 857059
Packit 857059
	if (oldestPacket != NULL) {
Packit 857059
		newestPacket->next = p;
Packit 857059
		formerNewestPacket = newestPacket;
Packit 857059
		newestPacket = p;
Packit 857059
		done = 0;
Packit 857059
		while (!done) {
Packit 857059
			/* did this packet overwrite oldest? */
Packit 857059
			overlap = 0;
Packit 857059
			oldestEndBlockNum = oldestPacket->blockNum + oldestPacket->numBlocks - 1;
Packit 857059
			if ((myEndBlockNum >= oldestPacket->blockNum) && (myEndBlockNum <= oldestEndBlockNum))	/* overwrote part of oldest */
Packit 857059
				overlap = 2;
Packit 857059
			else if ((p->blockNum <= oldestPacket->blockNum) && (myEndBlockNum >= oldestEndBlockNum))	/* new packet engulfs oldest */
Packit 857059
				overlap = 3;
Packit 857059
			if (overlap) {
Packit 857059
				p1 = oldestPacket;
Packit 857059
				oldestPacket = oldestPacket->next;
Packit 857059
				returnPacket(p1);
Packit 857059
			} else
Packit 857059
				done = 1;
Packit 857059
		}
Packit 857059
		if (!applyFilters(p)) {
Packit 857059
			p->numBlocks = 0;
Packit 857059
			newestPacket = formerNewestPacket;
Packit 857059
			newestPacket->next = NULL;
Packit 857059
			returnPacket(p);
Packit 857059
		} else
Packit 857059
			numPacketsStored++;
Packit 857059
		if (numTriggerFunctions && applyTriggers(p)) {
Packit 857059
			if (!triggerSeen) {
Packit 857059
				triggerSeen = 1;
Packit 857059
				printf("\nopapacketcapture: Triggered by trigger file conditions\n");
Packit 857059
			}
Packit 857059
		}
Packit 857059
	} else {
Packit 857059
		oldestPacket = p;
Packit 857059
		newestPacket = p;
Packit 857059
		p->next = NULL;
Packit 857059
		if (!applyFilters(p)) {
Packit 857059
			oldestPacket = NULL;
Packit 857059
			newestPacket = NULL;
Packit 857059
			p->numBlocks = 0;
Packit 857059
		} else
Packit 857059
			numPacketsStored++;
Packit 857059
		if (numTriggerFunctions && applyTriggers(p)) {
Packit 857059
			if (!triggerSeen) {
Packit 857059
				triggerSeen = 1;
Packit 857059
				printf("\nopapacketcapture: Triggered by trigger file conditions\n");
Packit 857059
			}
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
void advanceCurrentBlock(packet *p)
Packit 857059
{
Packit 857059
Packit 857059
	currentBlock += (p->numBlocks * BLOCKSIZE);
Packit 857059
Packit 857059
	/* wrap if big packet will be too big */
Packit 857059
	if ((blocksTableSize - (currentBlock - blocks)) < STL_MAX_PACKET_SIZE) {
Packit 857059
		currentBlock = blocks;
Packit 857059
	}
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
int initPcapHeader(int fd)
Packit 857059
{
Packit 857059
	pcapHdr_t			fileHdr;
Packit 857059
	memset(&fileHdr, 0, sizeof(fileHdr));
Packit 857059
Packit 857059
	fileHdr.magicNumber =		STL_WIRESHARK_MAGIC;
Packit 857059
	fileHdr.versionMajor =		STL_WIRESHARK_MAJOR;
Packit 857059
	fileHdr.versionMinor =		STL_WIRESHARK_MINOR;
Packit 857059
#if 0
Packit 857059
	fileHdr.snapLen =			IB_PACKET_SIZE;
Packit 857059
#else
Packit 857059
	fileHdr.snapLen =			65535;
Packit 857059
#endif
Packit 857059
	fileHdr.networkType =		STL_WIRESHARK_ERF;
Packit 857059
Packit 857059
	return ((write(fd, &fileHdr, sizeof(fileHdr)) > 0) ? 0 : -1);
Packit 857059
}
Packit 857059
Packit 857059
void writePCAP(int fd, uint64 pktLen, time_t sec, long nsec, uint8 *pkt)
Packit 857059
{
Packit 857059
	pcapRecHdr_t		pcapRec;
Packit 857059
	extHeader_t			ext;
Packit 857059
	WFR_SnC_HDR			*snc = (WFR_SnC_HDR *)pkt;
Packit 857059
	WFR_SnC_HDR			wfrLiteSnc = {0};
Packit 857059
	int i;
Packit 857059
	int erfRecordLen;
Packit 857059
Packit 857059
	/* Adjust to keep 'nsec' less than 1 second */
Packit 857059
	while (nsec >= 1E9L) {
Packit 857059
		sec++;
Packit 857059
		nsec -= 1E9L;
Packit 857059
	}
Packit 857059
Packit 857059
	pcapRec.ts_sec =            sec;
Packit 857059
	pcapRec.ts_nsec =           nsec;
Packit 857059
	ext.flags =                 4; /* set variable length bit */
Packit 857059
	ext.lossCtr =               0;
Packit 857059
	ext.linkType =              ERF_TYPE_OPA_SNC;
Packit 857059
Packit 857059
	/* The high 32 bits of the timestamp contain the integer number of seconds
Packit 857059
	 * while the lower 32 bits contain the binary fraction of the second.
Packit 857059
	 * Unlike the rest of the ERF header this is little endian
Packit 857059
	 */
Packit 857059
	StoreLeU64((uint8*)&ext.ts, ((uint64) sec << 32) + (((uint64) nsec << 32) / 1000 / 1000 / 1000));
Packit 857059
Packit 857059
	if (IS_FI_MODE(mode)) {
Packit 857059
		if (verbose > 1) {
Packit 857059
			fprintf(stderr, "Direction:  %u\n", snc->Direction);
Packit 857059
			fprintf(stderr, "PortNumber: %u\n", snc->PortNumber);
Packit 857059
			fprintf(stderr, "PBC/RHF:    0x%"PRIx64"\n", snc->u.AsReg64);
Packit 857059
			fprintf(stderr, "pktLen:     %"PRIu64"\n", pktLen);
Packit 857059
		}
Packit 857059
		ext.flags |= (snc->PortNumber & 0x1);
Packit 857059
	} else {
Packit 857059
		ext.flags |= 1;
Packit 857059
		wfrLiteSnc.Direction = 2;
Packit 857059
		wfrLiteSnc.PortNumber = 1;
Packit 857059
		pktLen += sizeof(WFR_SnC_HDR);
Packit 857059
	}
Packit 857059
Packit 857059
	erfRecordLen = pktLen + sizeof(extHeader_t);
Packit 857059
	/* PCAP record length, including pseudoheaders(e.g.ERF) but not PCAP header */
Packit 857059
	pcapRec.packetSize =                    erfRecordLen;
Packit 857059
	/* Technically should be wire length + erf header length but no
Packit 857059
	 * difference for OPA. Usually both set to ERF record length
Packit 857059
	 * because packetSize < packetOrigSize should be true
Packit 857059
	 */
Packit 857059
	pcapRec.packetOrigSize =                erfRecordLen;
Packit 857059
	/* Total ERF record length including header and any padding */
Packit 857059
	ext.length =                            hton16(erfRecordLen);
Packit 857059
	/* Packet wire length */
Packit 857059
	ext.realLength =                        hton16(pktLen);
Packit 857059
Packit 857059
	if (write(fd, &pcapRec, sizeof(pcapRec)) < 0) {
Packit 857059
		fprintf(stderr, "Failed to write PCAP packet header\n");
Packit 857059
	}
Packit 857059
	if (write(fd, &ext, sizeof(ext)) < 0) {
Packit 857059
		fprintf(stderr, "Failed to write Ext packet header\n");
Packit 857059
	}
Packit 857059
	if (wfrLiteSnc.Direction == 2) {
Packit 857059
		if (write(fd, &wfrLiteSnc, sizeof(WFR_SnC_HDR)) < 0) {
Packit 857059
			fprintf(stderr, "Failed to write SnC packet header\n");
Packit 857059
		}
Packit 857059
		pktLen -= sizeof(WFR_SnC_HDR);
Packit 857059
	}
Packit 857059
	if (write(fd, pkt, pktLen) < 0) {
Packit 857059
		fprintf(stderr, "Failed to write packet.\n");
Packit 857059
	}
Packit 857059
Packit 857059
	if (verbose > 2) {
Packit 857059
		fprintf(stderr, "TO PCAP: ");
Packit 857059
		i=0;
Packit 857059
		if (wfrLiteSnc.Direction == 2) {
Packit 857059
			for (; i < sizeof(WFR_SnC_HDR); i++ ){
Packit 857059
				if (i % 8 == 0) fprintf(stderr, "\n0x%04x ", i);
Packit 857059
				fprintf(stderr, "%02x ", ((uint8 *)&wfrLiteSnc)[i] );
Packit 857059
				if (i % 8 == 3) fprintf(stderr, " ");
Packit 857059
			}
Packit 857059
		}
Packit 857059
		for (; i < pktLen; i++ ) {
Packit 857059
			if (i % 8 == 0) fprintf(stderr, "\n0x%04x ", i);
Packit 857059
			fprintf(stderr,"%02x ", pkt[i]);
Packit 857059
			if (i % 8 == 3) fprintf(stderr, " ");
Packit 857059
		}
Packit 857059
		fprintf(stderr, "\n");
Packit 857059
	}
Packit 857059
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
void showPackets(packet *in) {
Packit 857059
	packet *p;
Packit 857059
	IB_LRH *pkt;
Packit 857059
	MAD_COMMON *m;
Packit 857059
	char packetType[5];
Packit 857059
	STL_LID dlid = 0;
Packit 857059
	STL_LID slid = 0;
Packit 857059
	uint8 opcode = 0;
Packit 857059
	uint16 pkey = 0;
Packit 857059
Packit 857059
	if (in) {
Packit 857059
		p = in;
Packit 857059
	} else {
Packit 857059
		p = oldestPacket;
Packit 857059
	}
Packit 857059
Packit 857059
	while (p != NULL) {
Packit 857059
		// Don't print anything but 9B and 16B
Packit 857059
		if (is9BWfrPacket(p)) {
Packit 857059
			pkt = (IB_LRH *)( (uint8 *)(&blocks[p->blockNum * BLOCKSIZE]) + sizeof(WFR_SnC_HDR));
Packit 857059
			dlid = getDLID(p);
Packit 857059
			slid = getSLID(p);
Packit 857059
			opcode = getOpCode(p);
Packit 857059
			pkey = getPkey(p);
Packit 857059
			switch ( opcode >>5 ) {
Packit 857059
				case 0:
Packit 857059
					strcpy(packetType, "RC");
Packit 857059
					break;
Packit 857059
				case 1:
Packit 857059
					strcpy(packetType, "UC");
Packit 857059
					break;
Packit 857059
				case 2:
Packit 857059
					strcpy(packetType, "RD");
Packit 857059
					break;
Packit 857059
				case 3:
Packit 857059
					strcpy(packetType, "UD");
Packit 857059
					break;
Packit 857059
				default:
Packit 857059
					strcpy(packetType, "??");
Packit 857059
					break;
Packit 857059
			}
Packit 857059
			printf("showpacket(9b):dest lid 0x%08x\tsrc lid 0x%08x\tsvc lev %d\tpkey is 0x%04x\ttype is %s\n", dlid, slid, pkt->l.ServiceLevel, pkey, packetType);
Packit 857059
			if (isMAD(p)) {
Packit 857059
				m = getMAD(p);
Packit 857059
				if (m != NULL) {
Packit 857059
					printf("showpacket(9b):mgmt class 0x%02x\tAttributeID 0x%04x\n", m->MgmtClass, ntoh16(m->AttributeID));
Packit 857059
				}
Packit 857059
			}
Packit 857059
		} else if (is16BWfrPacket(p)) {
Packit 857059
			dlid = getDLID(p);
Packit 857059
			slid = getSLID(p);
Packit 857059
			printf("showpacket(16b):dest lid 0x%08x\tsrc lid 0x%08x\t", dlid, slid);
Packit 857059
			if (isMAD(p)) {
Packit 857059
				m = getMAD(p);
Packit 857059
				if (m != NULL) {
Packit 857059
					printf("mgmt class 0x%02x\tAttributeID 0x%04x\t", m->MgmtClass, ntoh16(m->AttributeID));
Packit 857059
				}
Packit 857059
			}
Packit 857059
			printf("\n");
Packit 857059
		}
Packit 857059
		if (in) {
Packit 857059
			break;
Packit 857059
		} else {
Packit 857059
			p = p->next;
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	return;
Packit 857059
}
Packit 857059
Packit 857059
void writePacketData()
Packit 857059
{
Packit 857059
	packet	*p;
Packit 857059
	int		fd;
Packit 857059
Packit 857059
	if (gotoutfile) {
Packit 857059
		fd = open(out_file, O_RDWR|O_CREAT|O_TRUNC, 00644);
Packit 857059
	} else {
Packit 857059
		fd = open(PACKET_OUT_FILE, O_RDWR|O_CREAT|O_TRUNC, 00644);
Packit 857059
	}
Packit 857059
	if (fd < 0) {
Packit 857059
		fprintf(stderr, "Error opening output file %s\n", strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
	if (initPcapHeader(fd) < 0) {
Packit 857059
		fprintf(stderr, "Error writing pcap header - %s\n", strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
Packit 857059
	p = oldestPacket;
Packit 857059
Packit 857059
	while (p != NULL) {
Packit 857059
		writePCAP(fd, (unsigned short) p->size, p->ts_sec, p->ts_nsec, &blocks[p->blockNum * BLOCKSIZE]);
Packit 857059
		p = p->next;
Packit 857059
	}
Packit 857059
Packit 857059
	close(fd);
Packit 857059
Packit 857059
	return;
Packit 857059
}
Packit 857059
int debugtool_capture_device_filter(const struct dirent *d) {
Packit 857059
	int hfi = -1;
Packit 857059
	int port = -1;
Packit 857059
Packit 857059
	if (2 == sscanf(d->d_name,  "ipath_capture_%02d_%02d", &hfi, &port)) {
Packit 857059
		return (hfi != -1 && port != -1 ? 1 : 0);
Packit 857059
	}
Packit 857059
	return 0;
Packit 857059
}
Packit 857059
int wfr_capture_device_filter(const struct dirent *d) {
Packit 857059
	int gen = -1;
Packit 857059
	int hfi = -1;
Packit 857059
Packit 857059
	if (2 == sscanf(d->d_name, "hfi%d_diagpkt%d", &gen, &hfi)) {
Packit 857059
		return (gen == 1 && hfi != -1 ? 1 : 0);
Packit 857059
	}
Packit 857059
	return 0;
Packit 857059
}
Packit 857059
int all_capture_device_filter(const struct dirent *d) {
Packit 857059
	int gen = -1;
Packit 857059
	int hfi = -1;
Packit 857059
	int port = -1;
Packit 857059
Packit 857059
	if (2 == sscanf(d->d_name, "hfi%d_diagpkt%d", &gen, &hfi)) {
Packit 857059
		return ((gen == 1) && hfi != -1 ? 1 : 0);
Packit 857059
Packit 857059
	}
Packit 857059
	if (2 == sscanf(d->d_name,  "ipath_capture_%02d_%02d", &hfi, &port)) {
Packit 857059
		return (hfi != -1 && port != -1 ? 1 : 0);
Packit 857059
	}
Packit 857059
	return 0;
Packit 857059
}
Packit 857059
Packit 857059
static char *modeToText(uint8 mode){
Packit 857059
	switch (mode) {
Packit 857059
	case 0: return "All";
Packit 857059
	case DEBUG_TOOL_MODE: return "DebugTool";
Packit 857059
	case WFR_MODE: return "WFR";
Packit 857059
	default: return "Unknown";
Packit 857059
	}
Packit 857059
}
Packit 857059
Packit 857059
static void Usage(int exitcode)
Packit 857059
{
Packit 857059
	fprintf(stderr, "Usage: opapacketcapture [-o outfile] [-d devfile] [-f filterfile] [-t triggerfile] [-l triggerlag]\n");
Packit 857059
	fprintf(stderr, "                          [-a alarm] [-p packets] [-s maxblocks] [-v [-v]]\n");
Packit 857059
	fprintf(stderr, "            or\n");
Packit 857059
	fprintf(stderr, "       opapacketcapture --help\n");
Packit 857059
	fprintf(stderr, "   --help - produce full help text\n");
Packit 857059
	fprintf(stderr, "   -o - output file for captured packets - default is "PACKET_OUT_FILE"\n");
Packit 857059
	fprintf(stderr, "   -d - device file for capturing packets\n");
Packit 857059
	fprintf(stderr, "   -f - filter file used for filtering - if absent, no filtering\n");
Packit 857059
	fprintf(stderr, "   -t - trigger file used for triggering a stop capture - if absent, normal triggering \n");
Packit 857059
	fprintf(stderr, "   -l - trigger lag: number of packets to collect after trigger condition met before dump and exit (default is 10)\n");
Packit 857059
	fprintf(stderr, "   -a - number of seconds for alarm trigger to dump capture and exit\n");
Packit 857059
	fprintf(stderr, "   -p - number of packets for alarm trigger to dump capture and exit\n");
Packit 857059
	fprintf(stderr, "   -s - number of blocks to allocate for ring buffer (in Millions) [block = 64 Bytes] - default is 2 (128 MiB)\n");
Packit 857059
//	fprintf(stderr, "   -m - protocol mode: 0=All, 1=DebugTool, 2=WFR; default is All\n");
Packit 857059
	fprintf(stderr, "   -v - verbose output (Use verbose Level 1+ to show levels)\n");
Packit 857059
	if (verbose) {
Packit 857059
		fprintf(stderr, "        Level 1: Live Packet Count\n");
Packit 857059
		fprintf(stderr, "        Level 2: Basic Packet read info \n");
Packit 857059
		fprintf(stderr, "        Level 3: HEX Dump of packet going into output file\n");
Packit 857059
		fprintf(stderr, "        Level 4: HEX Dump of data coming over snoop device\n");
Packit 857059
	}
Packit 857059
	fprintf(stderr, "\n");
Packit 857059
	fprintf(stderr, "To stop capture and trigger dump, kill with SIGINT or SIGUSR1.\n");
Packit 857059
	fprintf(stderr, "Program will dump packets to file and exit\n");
Packit 857059
Packit 857059
	exit(exitcode);
Packit 857059
}
Packit 857059
Packit 857059
int main (int argc, char *argv[])
Packit 857059
{
Packit 857059
	int	    	numRead;
Packit 857059
	int	    	numDevs = 0;
Packit 857059
	int		    i;
Packit 857059
	int		    c;
Packit 857059
	packet	    *newPacket;
Packit 857059
	char	    strArg[64] = {0};
Packit 857059
	const char  *opts="o:d:f:t:l:a:p:s:m:v";
Packit 857059
	const struct option longopts[] = {{"help", 0, 0, '$'},
Packit 857059
						{0, 0, 0, 0}};
Packit 857059
	FILE	    *fp = NULL;
Packit 857059
	int		    fd = 0;
Packit 857059
	struct timespec ts = {0};
Packit 857059
	uint64      numblocks = DEFAULT_NUMBLOCKS;
Packit 857059
	unsigned    lasttime=0;
Packit 857059
	struct dirent **d;
Packit 857059
	char deviceCmpStr[80] = {0};
Packit 857059
Packit 857059
	while (-1 != (c = getopt_long(argc, argv, opts, longopts, NULL))) {
Packit 857059
		switch (c) {
Packit 857059
		case 'a':
Packit 857059
			strncpy(strArg, optarg, sizeof(strArg)-1);
Packit 857059
			strArg[sizeof(strArg)-1]=0;
Packit 857059
			gotAlarmArg = 1;
Packit 857059
			break;
Packit 857059
		case 'p':
Packit 857059
			if (FSUCCESS != StringToUint64(&numPacketsMax, optarg, NULL, 0, TRUE)) {
Packit 857059
				fprintf(stderr, "opapacketcapture: Invalid size: %s\n", optarg);
Packit 857059
				Usage(2);
Packit 857059
			}
Packit 857059
			break;
Packit 857059
		case 'm':
Packit 857059
			if (FSUCCESS != StringToUint8(&mode, optarg, NULL, 0, TRUE)) {
Packit 857059
				fprintf(stderr, "opapacketcapture: Invalid mode: %s\n", optarg);
Packit 857059
				Usage(2);
Packit 857059
			}
Packit 857059
			gotModeArg = 1;
Packit 857059
			break;
Packit 857059
		case 'f':
Packit 857059
			strncpy(filterFileArg, optarg, sizeof(filterFileArg)-1);
Packit 857059
			filterFileArg[sizeof(filterFileArg)-1]=0;
Packit 857059
			gotFilterFileArg = 1;
Packit 857059
			break;
Packit 857059
		case 't':
Packit 857059
			strncpy(triggerFileArg, optarg, sizeof(triggerFileArg)-1);
Packit 857059
			triggerFileArg[sizeof(triggerFileArg)-1]=0;
Packit 857059
			gotTriggerFileArg = 1;
Packit 857059
			break;
Packit 857059
		case 'd':
Packit 857059
			strncpy(devfile, optarg, sizeof(devfile)-1);
Packit 857059
			devfile[sizeof(devfile)-1]=0;
Packit 857059
			gotdevfile = 1;
Packit 857059
			break;
Packit 857059
		case 'o':
Packit 857059
			strncpy(out_file, optarg, sizeof(out_file)-1);
Packit 857059
			out_file[sizeof(out_file)-1]=0;
Packit 857059
			gotoutfile = 1;
Packit 857059
			break;
Packit 857059
		case 'l':
Packit 857059
			sscanf(optarg, "%d", &triggerLag);
Packit 857059
			gotTriggerLagArg = 1;
Packit 857059
			break;
Packit 857059
		case 's':
Packit 857059
			if (FSUCCESS != StringToUint64(&numblocks, optarg, NULL, 0, TRUE)) {
Packit 857059
				fprintf(stderr, "opapacketcapture: Invalid size: %s\n", optarg);
Packit 857059
				Usage(2);
Packit 857059
			}
Packit 857059
			numblocks *= (1024 * 1024);
Packit 857059
			break;
Packit 857059
		case 'v':
Packit 857059
			verbose++;
Packit 857059
			break;
Packit 857059
		case '$':
Packit 857059
			Usage(0);
Packit 857059
		default:
Packit 857059
			fprintf(stderr, "opapacketcapture: Invalid option -%c\n", c);
Packit 857059
			Usage(2);
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	if (gotAlarmArg) {
Packit 857059
		char *p;
Packit 857059
		int alarmMult = 1;
Packit 857059
		if ((p = strchr(strArg, 'm')) != NULL) {
Packit 857059
			alarmMult = 60;
Packit 857059
		} else if ((p = strchr(strArg, 'h')) != NULL) {
Packit 857059
			alarmMult = 60*60;
Packit 857059
		} else if ((p = strchr(strArg, 'd')) != NULL) {
Packit 857059
			alarmMult = 60*60*24;
Packit 857059
		}
Packit 857059
		sscanf(strArg, "%u", &alarmArg);
Packit 857059
		alarmArg *= alarmMult;
Packit 857059
	}
Packit 857059
Packit 857059
	/* Scan "/dev/" directory for capture devices */
Packit 857059
	if (gotModeArg) {
Packit 857059
		switch (mode) {
Packit 857059
		case DEBUG_TOOL_MODE:
Packit 857059
			numDevs = scandir("/dev/", &d, debugtool_capture_device_filter, alphasort);
Packit 857059
			break;
Packit 857059
		case WFR_MODE:
Packit 857059
			numDevs = scandir("/dev/", &d, wfr_capture_device_filter, alphasort);
Packit 857059
			break;
Packit 857059
		default:
Packit 857059
			numDevs = scandir("/dev/", &d, all_capture_device_filter, alphasort);
Packit 857059
		}
Packit 857059
	} else {
Packit 857059
		numDevs = scandir("/dev/", &d, all_capture_device_filter, alphasort);
Packit 857059
	}
Packit 857059
	if (numDevs == 0) {
Packit 857059
		fprintf(stderr, "opapacketcapture: Packet capture not supported by installed hfi driver. No capture devices found on system\n");
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
Packit 857059
	/* Check if supplied devfile matches one of the possible found devices */
Packit 857059
	if (gotdevfile) {
Packit 857059
		boolean isFound = FALSE;
Packit 857059
		for (i = 0; i < numDevs; i++) {
Packit 857059
			snprintf(deviceCmpStr, sizeof(deviceCmpStr), "/dev/%s", d[i]->d_name);
Packit 857059
			if (strncmp(devfile, deviceCmpStr, sizeof(deviceCmpStr)) == 0) {
Packit 857059
				isFound = TRUE;
Packit 857059
				break;
Packit 857059
			}
Packit 857059
		}
Packit 857059
		if (!isFound) {
Packit 857059
			fprintf(stderr, "opapacketcapture: Error %s does not match 1 of %u devices found on system: mode %s\n", devfile, numDevs, modeToText(mode));
Packit 857059
			for (i = 0; verbose && i < numDevs; i++) {
Packit 857059
				fprintf(stderr, "  /dev/%s\n", d[i]->d_name);
Packit 857059
			}
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
	} else if (numDevs > 1) {
Packit 857059
		fprintf(stderr, "opapacketcapture: Error %u devices found on system, please choose one: mode %s\n", numDevs, modeToText(mode));
Packit 857059
		for (i = 0; verbose && i < numDevs; i++) {
Packit 857059
			fprintf(stderr, "  /dev/%s\n", d[i]->d_name);
Packit 857059
		}
Packit 857059
		exit(1);
Packit 857059
	} else {
Packit 857059
		snprintf(devfile, sizeof(devfile), "/dev/%s", d[0]->d_name);
Packit 857059
	}
Packit 857059
Packit 857059
	/* now that devfile is known try to determine operating mode */
Packit 857059
	if (!gotModeArg) {
Packit 857059
		int gen = -1;
Packit 857059
		int hfi = -1;
Packit 857059
		int port = -1;
Packit 857059
		if (2 == sscanf(devfile, "/dev/hfi%d_diagpkt%d", &gen, &hfi)) {
Packit 857059
			switch (gen) {
Packit 857059
			case 1:
Packit 857059
				mode = WFR_MODE;
Packit 857059
				break;
Packit 857059
			default:
Packit 857059
				fprintf(stderr, "opapacketcapture: Error could not determine operating mode from devfile: %s\n", devfile);
Packit 857059
				exit(1);
Packit 857059
			}
Packit 857059
		} else if (2 == sscanf(devfile, "/dev/ipath_capture_%02d_%02d", &hfi, &port) && (hfi != -1 && port != -1)) {
Packit 857059
			mode = DEBUG_TOOL_MODE;
Packit 857059
		} else {
Packit 857059
			fprintf(stderr, "opapacketcapture: Error could not determine operating mode from devfile: %s\n", devfile);
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	printf("opapacketcapture: Capturing from %s using %s mode\n", devfile, modeToText(mode));
Packit 857059
Packit 857059
	blocksTableSize = BLOCKSIZE * numblocks;
Packit 857059
	blocks = (uint8 *)malloc(blocksTableSize);
Packit 857059
	if (blocks == NULL) {
Packit 857059
		fprintf(stderr, "opapacketcapture: Error allocating blocks array: %s\n", strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
Packit 857059
	numpackets = (numblocks/3);
Packit 857059
	packets = (packet *)malloc(numpackets * sizeof(packet));
Packit 857059
	if (packets == NULL) {
Packit 857059
		fprintf(stderr, "opapacketcapture: Error allocating packets array: %s\n", strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
	for (i = 0; i < (numpackets-1); i++)
Packit 857059
		packets[i].next = &packets[i+1];
Packit 857059
	packets[numpackets-1].next = NULL;
Packit 857059
Packit 857059
	currentBlock = blocks;
Packit 857059
	freePackets = packets;
Packit 857059
	oldestPacket = NULL;
Packit 857059
	newestPacket = NULL;
Packit 857059
	stopcapture = 0;
Packit 857059
	retryCount = 0;
Packit 857059
Packit 857059
	filterCondition = COND_TYPE_AND;
Packit 857059
Packit 857059
	signal(SIGINT, my_handler);
Packit 857059
	signal(SIGUSR1, my_handler);
Packit 857059
	signal(SIGALRM, my_handler);
Packit 857059
Packit 857059
	if (gotFilterFileArg)
Packit 857059
		setupFilters(filterFileArg);
Packit 857059
Packit 857059
	if (gotTriggerFileArg)
Packit 857059
		setupTriggers(triggerFileArg);
Packit 857059
Packit 857059
	/* open file */
Packit 857059
	fdIn = open(devfile, O_RDONLY);
Packit 857059
Packit 857059
	if (fdIn < 0) {
Packit 857059
		if (errno == ENOENT)
Packit 857059
			fprintf(stderr, "opapacketcapture: Packet capture not supported by installed hfi driver\n");
Packit 857059
		else
Packit 857059
			fprintf(stderr, "opapacketcapture: Unable to open: %s: mode %u: %s\n",
Packit 857059
				devfile, mode, strerror(errno));
Packit 857059
		free(packets);
Packit 857059
		return -1;
Packit 857059
	}
Packit 857059
Packit 857059
	if (alarmArg)
Packit 857059
		alarm(alarmArg);
Packit 857059
Packit 857059
	if (writethrough) {
Packit 857059
		unlink(out_file);
Packit 857059
		fp = fopen(out_file, "a+");
Packit 857059
		if (fp == NULL) {
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
		fd = fileno(fp);
Packit 857059
		if (initPcapHeader(fd) < 0) {
Packit 857059
			fprintf(stderr, "opapacketcapture: Error writing pcap header: %s\n", strerror(errno));
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
Packit 857059
	}
Packit 857059
Packit 857059
	if (ioctlConfigured) {
Packit 857059
		if (ioctl(fdIn, QIB_SNOOP_IOCSETFILTER, &filterCmd) < 0) {
Packit 857059
			fprintf(stderr, "opapacketcapture: Error issuing ioctl to QIB driver to set filter: %s\n", strerror(errno));
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
	}
Packit 857059
Packit 857059
	if (!clock_getres(CLOCK_REALTIME, &ts)) {
Packit 857059
		if (verbose)
Packit 857059
			printf("opapacketcapture: Clock precision: %ldns\n", ts.tv_nsec);
Packit 857059
		if (ts.tv_nsec != 1)
Packit 857059
			fprintf(stderr, "opapacketcapture: Error clock precision not 1ns: %ldns\n", ts.tv_nsec );
Packit 857059
	} else {
Packit 857059
		fprintf(stderr, "opapacketcapture: Error getting clock precision: %s\n", strerror(errno));
Packit 857059
		exit(1);
Packit 857059
	}
Packit 857059
Packit 857059
	printf("opapacketcapture: Capturing packets using %llu MiB buffer\n", (long long unsigned int)blocksTableSize/(1024*1024));
Packit 857059
Packit 857059
	while (!stopcapture) {
Packit 857059
		numRead = read(fdIn, (char *)currentBlock , STL_MAX_PACKET_SIZE);
Packit 857059
Packit 857059
		if (numRead == 0) {
Packit 857059
			stopcapture = 1;
Packit 857059
			continue;
Packit 857059
		}
Packit 857059
Packit 857059
		if (numRead < 0) {
Packit 857059
			if (errno == EAGAIN) {
Packit 857059
				if (++retryCount <= 25)
Packit 857059
					continue;
Packit 857059
			}
Packit 857059
			if (errno != EINTR)
Packit 857059
				fprintf(stderr, "opapacketcapture: Error reading packet: %s\n", strerror(errno));
Packit 857059
			stopcapture = 1;
Packit 857059
			continue;
Packit 857059
		}
Packit 857059
Packit 857059
		retryCount = 0;
Packit 857059
Packit 857059
		clock_gettime(CLOCK_REALTIME, &ts);
Packit 857059
		numPacketsRead++;
Packit 857059
		if (verbose > 1) {
Packit 857059
			fprintf(stderr, "Packet %u", numPacketsRead);
Packit 857059
		}
Packit 857059
		if (verbose > 3) {
Packit 857059
			fprintf(stderr," numRead: %u 0x%x", numRead, numRead);
Packit 857059
			for ( i = 0; i < numRead; i++) {
Packit 857059
				if (i % 8 == 0) fprintf(stderr, "\n0x%04x ", i);
Packit 857059
				fprintf(stderr,"%02x ", currentBlock[i]);
Packit 857059
				if (i % 8 == 3) fprintf(stderr, " ");
Packit 857059
			}
Packit 857059
		}
Packit 857059
		if (verbose > 1) fprintf(stderr, "\n");
Packit 857059
Packit 857059
		/* get next packet and fill it */
Packit 857059
		newPacket = getPacket();
Packit 857059
		newPacket->blockNum = (currentBlock - blocks) / BLOCKSIZE;
Packit 857059
		newPacket->size = numRead;
Packit 857059
		newPacket->numBlocks = (numRead / BLOCKSIZE) + ((numRead % BLOCKSIZE) ? 1 : 0);
Packit 857059
		newPacket->ts_sec = ts.tv_sec;
Packit 857059
		newPacket->ts_nsec = ts.tv_nsec;
Packit 857059
		newPacket->next = NULL;
Packit 857059
Packit 857059
		addNewPacket(newPacket);
Packit 857059
Packit 857059
		// Print some parsed content of the new packet
Packit 857059
		if (verbose >= 2) {
Packit 857059
			showPackets(newPacket);
Packit 857059
		}
Packit 857059
Packit 857059
		if (triggerSeen) {
Packit 857059
			if (afterTriggerPackets++ == triggerLag)
Packit 857059
				stopcapture = 1;
Packit 857059
		}
Packit 857059
Packit 857059
		advanceCurrentBlock(newPacket);
Packit 857059
Packit 857059
		if (verbose == 1 && ts.tv_sec > lasttime+5) {
Packit 857059
			lasttime = ts.tv_sec;
Packit 857059
			printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%10u packets", numPacketsRead);
Packit 857059
			fflush(stdout);
Packit 857059
		}
Packit 857059
Packit 857059
		if (numPacketsStored >= numPacketsMax) {
Packit 857059
			stopcapture = 1;
Packit 857059
		}
Packit 857059
	}
Packit 857059
	if (verbose)
Packit 857059
		printf("\n");
Packit 857059
Packit 857059
	/* clear filter if nec. and close */
Packit 857059
	if (ioctlConfigured) {
Packit 857059
		if (ioctl(fdIn, QIB_SNOOP_IOCCLEARFILTER, NULL) < 0) {
Packit 857059
			fprintf(stderr, "opapacketcapture: Error issuing ioctl to QIB driver to clear filter: %s\n", strerror(errno));
Packit 857059
			exit(1);
Packit 857059
		}
Packit 857059
	}
Packit 857059
	close(fdIn);
Packit 857059
Packit 857059
	/*showPackets(NULL);*/
Packit 857059
	printf("Number of packets stored is %d\n", numPacketsStored);
Packit 857059
Packit 857059
	writePacketData();
Packit 857059
Packit 857059
	exit(0);
Packit 857059
}