|
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 |
}
|