/** * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * http://www.ntop.org * * Copyright (C) 2003 Dinesh G. Dutt * Copyright (C) 2003-04 Luca Deri * * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ntop.h" #include #include #include "fcUtils.h" #include "globals-report.h" /* **************************************** */ /* ******************* */ char* makeFcHostLink (HostTraffic *el, short mode, short cutName, short compactWWN, char *buf, int buflen) { char *tmpStr, tmpbuf[64], colorSpec[64], *linkStr; char noLink = FALSE; /* don't create link for certain spl addr */ char *devTypeStr, *vendorStr, *vendorName; if(el == NULL) { traceEvent (CONST_TRACE_ERROR, "makeFcHostLink: Received NULL el\n"); return(" "); } accessAddrResMutex("makeHostLink"); tmpStr = NULL; devTypeStr = ""; vendorStr = ""; if(!cutName) { if(strncmp (el->fcCounters->hostNumFcAddress, "ff.ff.fd", strlen ("ff.ff.fd")) == 0) { tmpStr = "Fabric
Controller"; noLink = TRUE; } else if(strncmp (el->fcCounters->hostNumFcAddress, "ff.fc", strlen ("ff.fc")) == 0) { safe_snprintf(__FILE__, __LINE__, tmpbuf, 64, "Domain Controller
for %s", &el->fcCounters->hostNumFcAddress[6]); tmpStr = tmpbuf; noLink = TRUE; } else if(strncmp (el->fcCounters->hostNumFcAddress, "ff.ff.fe", sizeof ("ff.ff.fe")) == 0) { tmpStr = "F_Port
Server"; noLink = TRUE; } else if(strncmp (el->fcCounters->hostNumFcAddress, "ff.ff.fc", sizeof ("ff.ff.fc")) == 0) { tmpStr = "Directory
Server"; noLink = TRUE; } else if(strncmp (el->fcCounters->hostNumFcAddress, "00.00.00", strlen ("00.00.00")) == 0) { tmpStr = el->fcCounters->hostNumFcAddress; noLink = TRUE; } else { /* Introduce maybe a picture or string based on HBA's vendor */ if(el->hostResolvedNameType == FLAG_HOST_SYM_ADDR_TYPE_FC_WWN) { safe_snprintf(__FILE__, __LINE__, tmpbuf, sizeof (tmpbuf), "%.12s
%.12s", el->hostResolvedName, &el->hostResolvedName[12]); tmpStr = tmpbuf; } else tmpStr = el->hostResolvedName; if(strncmp(el->fcCounters->hostNumFcAddress, "ff", 2) == 0) noLink = TRUE; linkStr = el->fcCounters->hostNumFcAddress; } } else { if(el->fcCounters->hostFcAddress.domain != FC_ID_SYSTEM_DOMAIN) { if(el->hostResolvedNameType == FLAG_HOST_SYM_ADDR_TYPE_FC_WWN) { safe_snprintf(__FILE__, __LINE__, tmpbuf, sizeof (tmpbuf), "%.12s
%.12s", el->hostResolvedName, &el->hostResolvedName[12]); tmpStr = tmpbuf; } else tmpStr = el->hostResolvedName; } else { tmpStr = el->fcCounters->hostNumFcAddress; noLink = TRUE; } linkStr = el->fcCounters->hostNumFcAddress; } if(el->fcCounters->hostFcAddress.domain && (el->fcCounters->hostFcAddress.domain != FC_ID_SYSTEM_DOMAIN)) { if(el->fcCounters->devType == SCSI_DEV_INITIATOR) { devTypeStr = " " CONST_IMG_SCSI_INITIATOR; } else if(el->fcCounters->devType == SCSI_DEV_BLOCK) { devTypeStr = " " CONST_IMG_SCSI_DISK; } else { devTypeStr = ""; } vendorName = getVendorInfo(&el->fcCounters->pWWN.str[2], 1); if(vendorName[0] != '\0') { if(!strncasecmp (vendorName, "EMULEX CORPORATION", strlen ("EMULEX CORPORATION"))) { vendorStr = " " CONST_IMG_FC_VEN_EMULEX; } else if(!strcasecmp (vendorName, "JNI Corporation")) { vendorStr = " " CONST_IMG_FC_VEN_JNI; } else if(!strcasecmp (vendorName, "BROCADE COMMUNICATIONS SYSTEMS, Inc.")) { vendorStr = " " CONST_IMG_FC_VEN_BROCADE; } else if(!strncmp (vendorName, "EMC", strlen ("EMC"))) { vendorStr = " " CONST_IMG_FC_VEN_EMC; } else if(!strcasecmp (vendorName, "SEAGATE TECHNOLOGY")) { vendorStr = " " CONST_IMG_FC_VEN_SEAGATE; } else { vendorStr = ""; } } else { vendorStr = ""; } } else { devTypeStr = ""; vendorStr = ""; } if(mode == FLAG_HOSTLINK_HTML_FORMAT) { if(noLink) { safe_snprintf(__FILE__, __LINE__, buf, buflen, "%s-%d ", tmpStr, el->fcCounters->vsanId); } else { safe_snprintf(__FILE__, __LINE__, buf, buflen, "" "%s%s%s", linkStr, el->fcCounters->vsanId, el->fcCounters->hostNumFcAddress, tmpStr, devTypeStr, vendorStr); } } else if(mode == FLAG_HOSTLINK_TEXT_FORMAT) { if(noLink) { safe_snprintf(__FILE__, __LINE__, buf, buflen, "%s-%d", tmpStr, el->fcCounters->vsanId); } else { safe_snprintf(__FILE__, __LINE__, buf, buflen, "%s", linkStr, el->fcCounters->vsanId, makeHostAgeStyleSpec(el, colorSpec, sizeof(colorSpec)), el->fcCounters->hostNumFcAddress, tmpStr); } } else { safe_snprintf(__FILE__, __LINE__, buf, buflen, "%s-%d", tmpStr, el->fcCounters->vsanId); } releaseAddrResMutex (); return(buf); } /* ******************************* */ char *makeVsanLink (u_short vsanId, short mode, char *buf, int buflen) { accessAddrResMutex("makeHostLink"); if(vsanId) { safe_snprintf(__FILE__, __LINE__, buf, buflen, "%s%d%s", (mode == FLAG_HOSTLINK_HTML_FORMAT) ? "" : "", vsanId, vsanId, (mode == FLAG_HOSTLINK_HTML_FORMAT) ? "" : ""); } else { safe_snprintf(__FILE__, __LINE__, buf, buflen, "%s-%s", (mode == FLAG_HOSTLINK_HTML_FORMAT) ? "" : "", (mode == FLAG_HOSTLINK_HTML_FORMAT) ? "" : ""); } releaseAddrResMutex (); return (buf); } /* ******************************* */ void printFcHostHeader(HostTraffic *el, char *url, int revertOrder, int column, int hostInfoPage) { char buf[LEN_GENERAL_WORK_BUFFER]; char theLink[256]; safe_snprintf(__FILE__, __LINE__, theLink, sizeof(theLink), "/%s.html?col=%s%d&showF=", url, revertOrder ? "-" : "", column); switch(hostInfoPage) { case showHostLunStats: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } break; case showHostLunGraphs: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } break; case showHostScsiSessionBytes: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink); } break; case showHostScsiSessionTimes: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink); } break; case showHostScsiSessionStatus: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink); } break; case showHostScsiSessionTMInfo: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink); } break; case showHostFcSessions: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink); } break; case showHostMainPage: default: if((el->fcCounters->devType != SCSI_DEV_INITIATOR) && (el->fcCounters->devType != SCSI_DEV_UNINIT)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ LUN Statistics ] " "[ LUN Graphs ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Main Page ] " "[ SCSI Session (Bytes) ] " "[ SCSI Session (Times) ] " "[ SCSI Session (Status) ] " "[ SCSI Session (Task Mgmt) ] " "[ FC Sessions

", theLink, theLink, theLink, theLink, theLink); } break; } sendString(buf); } /* ******************************* */ int cmpFcFctn(const void *_a, const void *_b) { HostTraffic **a = (HostTraffic **)_a; HostTraffic **b = (HostTraffic **)_b; Counter a_=0, b_=0, a_val, b_val; float fa_=0, fb_=0; short floatCompare=0, columnProtoId; if((a == NULL) && (b != NULL)) { traceEvent(CONST_TRACE_WARNING, "cmpFcFctn() error (1)"); return(1); } else if((a != NULL) && (b == NULL)) { traceEvent(CONST_TRACE_WARNING, "cmpFcFctn() error (2)"); return(-1); } else if((a == NULL) && (b == NULL)) { traceEvent(CONST_TRACE_WARNING, "cmpFcFctn() error (3)"); return(0); } if(myGlobals.columnSort == FLAG_HOST_DUMMY_IDX) { int rc; /* Host name */ accessAddrResMutex("cmpFctn"); CMP_FC_PORT ((*a), (*b)) releaseAddrResMutex(); return(rc); } else if(myGlobals.columnSort == FLAG_DOMAIN_DUMMY_IDX) { int rc; accessAddrResMutex("cmpFctn"); a_ = (*a)->fcCounters->vsanId, b_ = (*b)->fcCounters->vsanId; rc = (a_ < b_) ? -1 : (a_ > b_) ? 1 : 0; releaseAddrResMutex(); return(rc); } #ifdef DEBUG traceEvent(CONST_TRACE_INFO, "reportKind=%d/columnSort=%d/numIpProtosToMonitor=%d\n", myGlobals.reportKind, myGlobals.columnSort, myGlobals.numIpProtosToMonitor); #endif switch(myGlobals.reportKind) { case SORT_DATA_RECEIVED_PROTOS: switch(myGlobals.columnSort) { case 0: a_ = (*a)->fcCounters->fcBytesRcvd.value, b_ = (*b)->fcCounters->fcBytesRcvd.value; break; case 1: a_ = (*a)->fcCounters->fcFcpBytesRcvd.value; b_ = (*b)->fcCounters->fcFcpBytesRcvd.value; break; case 2: a_ = (*a)->fcCounters->fcElsBytesRcvd.value; b_ = (*b)->fcCounters->fcElsBytesRcvd.value; break; case 3: a_ = (*a)->fcCounters->fcDnsBytesRcvd.value; b_ = (*b)->fcCounters->fcDnsBytesRcvd.value; break; case 4: a_ = (*a)->fcCounters->fcIpfcBytesRcvd.value; b_ = (*b)->fcCounters->fcIpfcBytesRcvd.value; break; case 5: a_ = (*a)->fcCounters->fcSwilsBytesRcvd.value; b_ = (*b)->fcCounters->fcSwilsBytesRcvd.value; break; case 6: a_ = (*a)->fcCounters->otherFcBytesRcvd.value; b_ = (*b)->fcCounters->otherFcBytesRcvd.value; break; } break; case SORT_DATA_RECEIVED_IP: columnProtoId = myGlobals.columnSort - 1; if((columnProtoId != -1) && (columnProtoId <= myGlobals.numIpProtosToMonitor)) { if(columnProtoId <= 0) { a_ = b_ = 0; } else { if((*a)->protoIPTrafficInfos[columnProtoId-1] != NULL) a_ = (*a)->protoIPTrafficInfos[columnProtoId-1]->rcvdLoc.value+ (*a)->protoIPTrafficInfos[columnProtoId-1]->rcvdFromRem.value; else a_ = 0; if((*b)->protoIPTrafficInfos[columnProtoId-1] != NULL) b_ = (*b)->protoIPTrafficInfos[columnProtoId-1]->rcvdLoc.value+ (*b)->protoIPTrafficInfos[columnProtoId-1]->rcvdFromRem.value; else b_ = 0; } } else { a_ = (*a)->ipBytesRcvd.value, b_ = (*b)->ipBytesRcvd.value; if(myGlobals.numIpProtosToMonitor == (columnProtoId-1)) { /* other IP */ int i; for(i=0; iprotoIPTrafficInfos[i] != NULL) a_val = ((*a)->protoIPTrafficInfos[i]->rcvdLoc.value +(*a)->protoIPTrafficInfos[i]->rcvdFromRem.value); else a_val = 0; if((*b)->protoIPTrafficInfos[i] != NULL) b_val = ((*b)->protoIPTrafficInfos[i]->rcvdLoc.value +(*b)->protoIPTrafficInfos[i]->rcvdFromRem.value); else b_val = 0; /* Better be safe... */ if(a_ > a_val) a_ -= a_val; else a_ = 0; if(b_ > b_val) b_ -= b_val; else b_ = 0; } } } break; case SORT_DATA_RECEIVED_THPT: switch(myGlobals.columnSort) { case 1: fa_ = (*a)->actualRcvdThpt, fb_ = (*b)->actualRcvdThpt, floatCompare = 1; break; case 2: fa_ = (*a)->averageRcvdThpt, fb_ = (*b)->averageRcvdThpt, floatCompare = 1; break; case 3: fa_ = (*a)->peakRcvdThpt, fb_ = (*b)->peakRcvdThpt, floatCompare = 1; break; case 4: fa_ = (*a)->actualRcvdPktThpt, fb_ = (*b)->actualRcvdPktThpt, floatCompare = 1; break; case 5: fa_ = (*a)->averageRcvdPktThpt, fb_ = (*b)->averageRcvdPktThpt, floatCompare = 1; break; case 6: fa_ = (*a)->peakRcvdPktThpt, fb_ = (*b)->peakRcvdPktThpt, floatCompare = 1; break; } break; case SORT_DATA_RCVD_HOST_TRAFFIC: case SORT_DATA_SENT_HOST_TRAFFIC: case SORT_DATA_HOST_TRAFFIC: /* Nothing */ break; case SORT_DATA_SENT_PROTOS: switch(myGlobals.columnSort) { case 0: a_ = (*a)->fcCounters->fcBytesSent.value, b_ = (*b)->fcCounters->fcBytesSent.value; break; case 1: a_ = (*a)->fcCounters->fcFcpBytesSent.value; b_ = (*b)->fcCounters->fcFcpBytesSent.value; break; case 2: a_ = (*a)->fcCounters->fcElsBytesSent.value; b_ = (*b)->fcCounters->fcElsBytesSent.value; break; case 3: a_ = (*a)->fcCounters->fcDnsBytesSent.value; b_ = (*b)->fcCounters->fcDnsBytesSent.value; break; case 4: a_ = (*a)->fcCounters->fcIpfcBytesSent.value; b_ = (*b)->fcCounters->fcIpfcBytesSent.value; break; case 5: a_ = (*a)->fcCounters->fcSwilsBytesSent.value; b_ = (*b)->fcCounters->fcSwilsBytesSent.value; break; case 6: a_ = (*a)->fcCounters->otherFcBytesSent.value; b_ = (*b)->fcCounters->otherFcBytesSent.value; break; } break; case SORT_DATA_SENT_IP: columnProtoId = myGlobals.columnSort - 1; if((columnProtoId != -1) && (columnProtoId <= myGlobals.numIpProtosToMonitor)) { if(columnProtoId <= 0) { a_ = b_ = 0; } else { if((*a)->protoIPTrafficInfos[columnProtoId-1] != NULL) a_ = (*a)->protoIPTrafficInfos[columnProtoId-1]->sentLoc.value +(*a)->protoIPTrafficInfos[columnProtoId-1]->sentRem.value; else a_ = 0; if((*b)->protoIPTrafficInfos[columnProtoId-1] != NULL) b_ = (*b)->protoIPTrafficInfos[columnProtoId-1]->sentLoc.value +(*b)->protoIPTrafficInfos[columnProtoId-1]->sentRem.value; else b_ = 0; } } else { a_ = (*a)->ipBytesSent.value, b_ = (*b)->ipBytesSent.value; if(myGlobals.numIpProtosToMonitor == (columnProtoId-1)) { /* other IP */ int i; for(i=0; iprotoIPTrafficInfos[i] != NULL) a_val = ((*a)->protoIPTrafficInfos[i]->sentLoc.value +(*a)->protoIPTrafficInfos[i]->sentRem.value); else a_val = 0; if((*b)->protoIPTrafficInfos[i] != NULL) b_val = ((*b)->protoIPTrafficInfos[i]->sentLoc.value +(*b)->protoIPTrafficInfos[i]->sentRem.value); else b_val = 0; /* Better be safe... */ if(a_ > a_val) a_ -= a_val; else a_ = 0; if(b_ > b_val) b_ -= b_val; else b_ = 0; } } } break; case SORT_DATA_SENT_THPT: switch(myGlobals.columnSort) { case 1: fa_ = (*a)->actualSentThpt, fb_ = (*b)->actualSentThpt, floatCompare = 1; break; case 2: fa_ = (*a)->averageSentThpt, fb_ = (*b)->averageSentThpt, floatCompare = 1; break; case 3: fa_ = (*a)->peakSentThpt, fb_ = (*b)->peakSentThpt, floatCompare = 1; break; case 4: fa_ = (*a)->actualSentPktThpt, fb_ = (*b)->actualSentPktThpt, floatCompare = 1; break; case 5: fa_ = (*a)->averageSentPktThpt, fb_ = (*b)->averageSentPktThpt, floatCompare = 1; break; case 6: fa_ = (*a)->peakSentPktThpt, fb_ = (*b)->peakSentPktThpt, floatCompare = 1; break; } break; case TRAFFIC_STATS: /* Nothing */ break; case SORT_DATA_PROTOS: switch(myGlobals.columnSort) { case 0: a_ = (*a)->fcCounters->fcBytesSent.value + (*a)->fcCounters->fcBytesRcvd.value; b_ = (*b)->fcCounters->fcBytesSent.value + (*b)->fcCounters->fcBytesRcvd.value; break; case 1: a_ = (*a)->fcCounters->fcFcpBytesSent.value + (*a)->fcCounters->fcFcpBytesRcvd.value; b_ = (*b)->fcCounters->fcFcpBytesSent.value + (*b)->fcCounters->fcFcpBytesRcvd.value; break; case 2: a_ = (*a)->fcCounters->fcElsBytesSent.value + (*a)->fcCounters->fcElsBytesRcvd.value; b_ = (*b)->fcCounters->fcElsBytesSent.value + (*b)->fcCounters->fcElsBytesRcvd.value; break; case 3: a_ = (*a)->fcCounters->fcDnsBytesSent.value + (*a)->fcCounters->fcDnsBytesRcvd.value; b_ = (*b)->fcCounters->fcDnsBytesSent.value + (*b)->fcCounters->fcDnsBytesRcvd.value; break; case 4: a_ = (*a)->fcCounters->fcIpfcBytesSent.value + (*a)->fcCounters->fcIpfcBytesRcvd.value; b_ = (*b)->fcCounters->fcIpfcBytesSent.value + (*b)->fcCounters->fcIpfcBytesRcvd.value; break; case 5: a_ = (*a)->fcCounters->fcSwilsBytesSent.value + (*a)->fcCounters->fcSwilsBytesRcvd.value; b_ = (*b)->fcCounters->fcSwilsBytesSent.value + (*b)->fcCounters->fcSwilsBytesRcvd.value; break; case 6: a_ = (*a)->fcCounters->otherFcBytesSent.value + (*a)->fcCounters->otherFcBytesRcvd.value; b_ = (*b)->fcCounters->otherFcBytesSent.value + (*b)->fcCounters->otherFcBytesRcvd.value; break; } break; case SORT_DATA_IP: columnProtoId = myGlobals.columnSort - 1; if((columnProtoId != -1) && (columnProtoId <= myGlobals.numIpProtosToMonitor)) { if(columnProtoId <= 0) { a_ = b_ = 0; } else { if((*a)->protoIPTrafficInfos[columnProtoId-1] != NULL) a_ = (*a)->protoIPTrafficInfos[columnProtoId-1]->rcvdLoc.value+ (*a)->protoIPTrafficInfos[columnProtoId-1]->rcvdFromRem.value+ (*a)->protoIPTrafficInfos[columnProtoId-1]->sentLoc.value+ (*a)->protoIPTrafficInfos[columnProtoId-1]->sentRem.value; else a_ = 0; if((*b)->protoIPTrafficInfos[columnProtoId-1] != NULL) b_ = (*b)->protoIPTrafficInfos[columnProtoId-1]->rcvdLoc.value+ (*b)->protoIPTrafficInfos[columnProtoId-1]->rcvdFromRem.value+ (*b)->protoIPTrafficInfos[columnProtoId-1]->sentLoc.value+ (*b)->protoIPTrafficInfos[columnProtoId-1]->sentRem.value; else b_ = 0; } } else { a_ = (*a)->ipBytesRcvd.value+(*a)->ipBytesSent.value; b_ = (*b)->ipBytesRcvd.value+(*b)->ipBytesSent.value; if(myGlobals.numIpProtosToMonitor == (columnProtoId-1)) { /* other IP */ int i; for(i=0; iprotoIPTrafficInfos[i] != NULL) a_val = ((*a)->protoIPTrafficInfos[i]->rcvdLoc.value +(*a)->protoIPTrafficInfos[i]->rcvdFromRem.value +(*a)->protoIPTrafficInfos[i]->sentLoc.value +(*a)->protoIPTrafficInfos[i]->sentRem.value); else a_val = 0; if((*b)->protoIPTrafficInfos[i] != NULL) b_val = ((*b)->protoIPTrafficInfos[i]->rcvdLoc.value +(*b)->protoIPTrafficInfos[i]->rcvdFromRem.value +(*b)->protoIPTrafficInfos[i]->sentLoc.value +(*b)->protoIPTrafficInfos[i]->sentRem.value); else b_val = 0; /* Better be safe... */ if(a_ > a_val) a_ -= a_val; else a_ = 0; if(b_ > b_val) b_ -= b_val; else b_ = 0; } } } break; case SORT_DATA_THPT: switch(myGlobals.columnSort) { case 1: fa_ = (*a)->actualTThpt; fb_ = (*b)->actualTThpt; floatCompare = 1; break; case 2: fa_ = (*a)->averageTThpt; fb_ = (*b)->averageTThpt; floatCompare = 1; break; case 3: fa_ = (*a)->peakTThpt; fb_ = (*b)->peakTThpt; floatCompare = 1; break; case 4: fa_ = (*a)->actualTPktThpt; fb_ = (*b)->actualTPktThpt; floatCompare = 1; break; case 5: fa_ = (*a)->averageTPktThpt; fb_ = (*b)->averageTPktThpt; floatCompare = 1; break; case 6: fa_ = (*a)->peakTPktThpt; fb_ = (*b)->peakTPktThpt; floatCompare = 1; break; } break; } /* traceEvent(CONST_TRACE_INFO, "%s=%u - %s=%u", (*a)->hostResolvedName, (unsigned long)a_, (*b)->hostResolvedName, (unsigned long)b_); */ if(floatCompare == 0) { if(a_ < b_) { return(1); } else if(a_ > b_) { return(-1); } else { return(0); } } else { if(fa_ < fb_) { return(1); } else if(fa_ > fb_) { return(-1); } else { return(0); } } } /* ******************************* */ int cmpFcSessionsFctn (const void *_a, const void *_b) { FCSession **a = (FCSession **)_a; FCSession **b = (FCSession **)_b; int a_, b_; int actualDeviceId, rc; switch (myGlobals.columnSort) { case 1: /* VSAN */ actualDeviceId = (*a)->deviceId; /* for macro checkSession */ a_ = (*a)->initiator->fcCounters->vsanId; actualDeviceId = (*b)->deviceId; b_ = (*b)->initiator->fcCounters->vsanId; return ( (a_ > b_) ? 1 : (a_ < b_) ? -1 : 0 ); break; case 2: /* Initiator Alias, pWWN or FC Addr */ CMP_FC_PORT (((*a)->initiator), ((*b)->initiator)) return (rc); break; case 3: /* Target Alias, pWWN or FC Addr */ CMP_FC_PORT (((*a)->remotePeer), ((*b)->remotePeer)) return (rc); break; case 4: /* Data Sent */ return ( ((*a)->bytesSent.value > (*b)->bytesSent.value) ? 1 : ((*a)->bytesSent.value < (*b)->bytesSent.value) ? -1 : 0); break; case 5: /* Data Rcvd */ return ( ((*a)->bytesRcvd.value > (*b)->bytesRcvd.value) ? 1 : ((*a)->bytesRcvd.value < (*b)->bytesRcvd.value) ? -1 : 0); break; case 6: return (((*a)->fcpBytesSent.value > (*b)->fcpBytesSent.value) ? 1 : ((*a)->fcpBytesSent.value < (*b)->fcpBytesSent.value) ? -1 : 0); break; case 7: return (((*a)->fcpBytesRcvd.value > (*b)->fcpBytesRcvd.value) ? 1 : ((*a)->fcpBytesRcvd.value < (*b)->fcpBytesRcvd.value) ? -1 : 0); break; case 8: return (((*a)->fcElsBytesSent.value > (*b)->fcElsBytesSent.value) ? 1 : ((*a)->fcElsBytesSent.value < (*b)->fcElsBytesSent.value) ? -1 : 0); break; case 9: return (((*a)->fcElsBytesRcvd.value > (*b)->fcElsBytesRcvd.value) ? 1 : ((*a)->fcElsBytesRcvd.value < (*b)->fcElsBytesRcvd.value) ? -1 : 0); break; case 10: return (((*a)->fcDnsBytesSent.value > (*b)->fcDnsBytesSent.value) ? 1 : ((*a)->fcDnsBytesSent.value < (*b)->fcDnsBytesSent.value) ? -1 : 0); break; case 11: return (((*a)->fcDnsBytesRcvd.value > (*b)->fcDnsBytesRcvd.value) ? 1 : ((*a)->fcDnsBytesRcvd.value < (*b)->fcDnsBytesRcvd.value) ? -1 : 0); break; case 12: return (((*a)->ipfcBytesSent.value > (*b)->ipfcBytesSent.value) ? 1 : ((*a)->ipfcBytesSent.value < (*b)->ipfcBytesSent.value) ? -1 : 0); break; case 13: return (((*a)->ipfcBytesRcvd.value > (*b)->ipfcBytesRcvd.value) ? 1 : ((*a)->ipfcBytesRcvd.value < (*b)->ipfcBytesRcvd.value) ? -1 : 0); break; case 14: return (((*a)->fcSwilsBytesSent.value > (*b)->fcSwilsBytesSent.value) ? 1 : ((*a)->fcSwilsBytesSent.value < (*b)->fcSwilsBytesSent.value) ? -1 : 0); break; case 15: return (((*a)->fcSwilsBytesRcvd.value > (*b)->fcSwilsBytesRcvd.value) ? 1 : ((*a)->fcSwilsBytesRcvd.value < (*b)->fcSwilsBytesRcvd.value) ? -1 : 0); break; case 16: return (((*a)->otherBytesSent.value > (*b)->otherBytesSent.value) ? 1 : ((*a)->otherBytesSent.value < (*b)->otherBytesSent.value) ? -1 : 0); break; case 17: return (((*a)->otherBytesRcvd.value > (*b)->otherBytesRcvd.value) ? 1 : ((*a)->otherBytesRcvd.value < (*b)->otherBytesRcvd.value) ? -1 : 0); break; case 18: return (CMPTV ((*a)->firstSeen, (*b)->firstSeen)); break; case 19: return (CMPTV ((*a)->lastSeen, (*b)->lastSeen)); break; default: break; } return(-1); } /* ************************** */ int cmpScsiSessionsFctn (const void *_a, const void *_b) { ScsiSessionSortEntry *a = (ScsiSessionSortEntry *)_a; ScsiSessionSortEntry *b = (ScsiSessionSortEntry *)_b; int a_, b_, rc; switch (myGlobals.columnSort) { case 1: /* VSAN */ a_ = a->initiator->fcCounters->vsanId; b_ = b->initiator->fcCounters->vsanId; return ( (a_ > b_) ? 1 : (a_ < b_) ? -1 : 0 ); break; case 2: /* Initiator FC Address */ CMP_FC_PORT ((a->initiator), (b->initiator)) return (rc); break; case 3: /* Target FC Address */ CMP_FC_PORT ((a->target), (b->target)) return (rc); break; case 4: /* Data Sent */ /* The first three entries account for the unknown LUN entry */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return ( (((FCSession *)a->stats)->unknownLunBytesSent.value > b->stats->bytesSent.value) ? 1 : (((FCSession *)a->stats)->unknownLunBytesSent.value < b->stats->bytesSent.value) ? -1 : 0); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return ( (a->stats->bytesSent.value > ((FCSession *)b->stats)->unknownLunBytesSent.value) ? 1 : (a->stats->bytesSent.value < ((FCSession *)b->stats)->unknownLunBytesSent.value) ? -1 : 0); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return ( (((FCSession *)a->stats)->unknownLunBytesSent.value > ((FCSession *)b->stats)->unknownLunBytesSent.value) ? 1 : (((FCSession *)a->stats)->unknownLunBytesSent.value < ((FCSession *)b->stats)->unknownLunBytesSent.value) ? -1 : 0); } return ( (a->stats->bytesSent.value > b->stats->bytesSent.value) ? 1 : (a->stats->bytesSent.value < b->stats->bytesSent.value) ? -1 : 0); break; case 5: /* Data Rcvd */ /* The first three entries account for the unknown LUN entry */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return ( (((FCSession *)a->stats)->unknownLunBytesRcvd.value > b->stats->bytesRcvd.value) ? 1 : (((FCSession *)a->stats)->unknownLunBytesRcvd.value < b->stats->bytesRcvd.value) ? -1 : 0); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return ( (a->stats->bytesRcvd.value > ((FCSession *)b->stats)->unknownLunBytesRcvd.value) ? 1 : (a->stats->bytesRcvd.value < ((FCSession *)b->stats)->unknownLunBytesRcvd.value) ? -1 : 0); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return ( (((FCSession *)a->stats)->unknownLunBytesRcvd.value > ((FCSession *)b->stats)->unknownLunBytesRcvd.value) ? 1 : (((FCSession *)a->stats)->unknownLunBytesRcvd.value < ((FCSession *)b->stats)->unknownLunBytesRcvd.value) ? -1 : 0); } return ( (a->stats->bytesRcvd.value > b->stats->bytesRcvd.value) ? 1 : (a->stats->bytesRcvd.value < b->stats->bytesRcvd.value) ? -1 : 0); break; case 6: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->scsiRdBytes.value > b->stats->scsiRdBytes.value) ? 1 : (a->stats->scsiRdBytes.value < b->stats->scsiRdBytes.value) ? -1 : 0); break; case 7: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->scsiWrBytes.value > b->stats->scsiWrBytes.value) ? 1 : (a->stats->scsiWrBytes.value < b->stats->scsiWrBytes.value) ? -1 : 0); break; case 8: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->scsiOtBytes.value > b->stats->scsiOtBytes.value) ? 1 : (a->stats->scsiOtBytes.value < b->stats->scsiOtBytes.value) ? -1 : 0); break; case 9: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->minRdSize > b->stats->minRdSize) ? 1: (a->stats->minRdSize < b->stats->minRdSize) ? -1 : 0); break; case 10: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->maxRdSize > b->stats->maxRdSize) ? 1: (a->stats->maxRdSize < b->stats->maxRdSize) ? -1 : 0); break; case 11: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->minWrSize > b->stats->minWrSize) ? 1: (a->stats->minWrSize < b->stats->minWrSize) ? -1 : 0); break; case 12: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->maxWrSize > b->stats->maxWrSize) ? 1: (a->stats->maxWrSize < b->stats->maxWrSize) ? -1 : 0); break; case 13: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->minXferRdySize > b->stats->minXferRdySize) ? 1: (a->stats->minXferRdySize < b->stats->minXferRdySize) ? -1 : 0); break; case 14: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->maxXferRdySize > b->stats->maxXferRdySize) ? 1: (a->stats->maxXferRdySize < b->stats->maxXferRdySize) ? -1 : 0); break; case 15: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->minIops > b->stats->minIops) ? 1: (a->stats->minIops < b->stats->minIops) ? -1 : 0); break; case 16: /* Unknown LUNs don't have any valid info to compare for this field. So * we dump them at the end of the list */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->maxIops > b->stats->maxIops) ? 1: (a->stats->maxIops < b->stats->maxIops) ? -1 : 0); break; case 17: /* # Failed Commands */ /* The first three entries account for the unknown LUN entry */ if((a->lun == 0xFFFF) && (b->lun != 0xFFFF)) { return (1); } else if((a->lun != 0xFFFF) && (b->lun == 0xFFFF)) { return (-1); } else if((a->lun == 0xFFFF) && (b->lun == 0xFFFF)) { return (0); } return ( (a->stats->numFailedCmds > b->stats->numFailedCmds) ? 1 : (a->stats->numFailedCmds < b->stats->numFailedCmds) ? -1 : 0); break; case 18: return (CMPTV (a->stats->minRTT, b->stats->minRTT)); break; case 19: return (CMPTV (a->stats->maxRTT, b->stats->maxRTT)); break; case 20: return (CMPTV (a->stats->minXfrRdyRTT, b->stats->minXfrRdyRTT)); break; case 21: return (CMPTV (a->stats->maxXfrRdyRTT, b->stats->maxXfrRdyRTT)); break; case 22: return (CMPTV (a->stats->minRdFrstDataRTT, b->stats->minRdFrstDataRTT)); break; case 23: return (CMPTV (a->stats->maxRdFrstDataRTT, b->stats->maxRdFrstDataRTT)); break; case 24: return (CMPTV (a->stats->minWrFrstDataRTT, b->stats->minWrFrstDataRTT)); break; case 25: return (CMPTV (a->stats->maxWrFrstDataRTT, b->stats->maxWrFrstDataRTT)); break; case 26: return (CMPTV (a->stats->firstSeen, b->stats->firstSeen)); break; case 27: return (CMPTV (a->stats->lastSeen, b->stats->lastSeen)); break; case 28: return ( (a->stats->chkCondCnt > b->stats->chkCondCnt) ? 1 : (a->stats->chkCondCnt < b->stats->chkCondCnt) ? -1 : 0); break; case 29: return ( (a->stats->busyCnt > b->stats->busyCnt) ? 1 : (a->stats->busyCnt < b->stats->busyCnt) ? -1 : 0); break; case 30: return ( (a->stats->resvConflictCnt > b->stats->resvConflictCnt) ? 1 : (a->stats->resvConflictCnt < b->stats->resvConflictCnt) ? -1 : 0); break; case 31: return ( (a->stats->taskSetFullCnt > b->stats->taskSetFullCnt) ? 1 : (a->stats->taskSetFullCnt < b->stats->taskSetFullCnt) ? -1 : 0); break; case 32: return ( (a->stats->taskAbrtCnt > b->stats->taskAbrtCnt) ? 1 : (a->stats->taskAbrtCnt < b->stats->taskAbrtCnt) ? -1 : 0); break; case 33: return ( (a->stats->abrtTaskSetCnt > b->stats->abrtTaskSetCnt) ? 1 : (a->stats->abrtTaskSetCnt < b->stats->abrtTaskSetCnt) ? -1 : 0); break; case 34: return ( (a->stats->clearTaskSetCnt > b->stats->clearTaskSetCnt) ? 1 : (a->stats->clearTaskSetCnt < b->stats->clearTaskSetCnt) ? -1 : 0); break; case 35: return ( (a->stats->tgtRstCnt > b->stats->tgtRstCnt) ? 1 : (a->stats->tgtRstCnt < b->stats->tgtRstCnt) ? -1 : 0); break; case 36: return ( (a->stats->lunRstCnt > b->stats->lunRstCnt) ? 1 : (a->stats->lunRstCnt < b->stats->lunRstCnt) ? -1 : 0); break; case 37: return ( (a->stats->lastTgtRstTime > b->stats->lastTgtRstTime) ? 1 : (a->stats->lastTgtRstTime < b->stats->lastTgtRstTime) ? -1 : 0); break; case 38: return ( (a->stats->lastLunRstTime > b->stats->lastLunRstTime) ? 1 : (a->stats->lastLunRstTime < b->stats->lastLunRstTime) ? -1 : 0); break; default: break; } return(-1); } int cmpLunFctn (const void *_a, const void *_b) { LunStatsSortedEntry *a = (LunStatsSortedEntry *)_a; LunStatsSortedEntry *b = (LunStatsSortedEntry *)_b; Counter a_=0, b_=0; switch(myGlobals.columnSort) { case 1: /* LU number i.e. LUN */ return (a->lun > b->lun ? 1 : a->lun < b->lun ? -1 : 0); break; case 2: /* Data Sent.value */ a_ = a->stats->bytesSent.value; b_ = b->stats->bytesSent.value; if(a_ < b_) return(-1); else if(a_ > b_) return(1); else return(0); break; case 3: /* Data Rcvd.value */ a_ = a->stats->bytesRcvd.value; b_ = b->stats->bytesRcvd.value; if(a_ < b_) return(-1); else if(a_ > b_) return(1); else return(0); break; case 4: a_ = a->stats->bytesSent.value + a->stats->bytesRcvd.value; b_ = b->stats->bytesSent.value + b->stats->bytesRcvd.value; if(a_ < b_) return(-1); else if(a_ > b_) return(1); else return(0); break; case 5: a_ = a->stats->pktSent + a->stats->pktRcvd; b_ = b->stats->pktSent + b->stats->pktRcvd; if(a_ < b_) return(-1); else if(a_ > b_) return(1); else return(0); break; default: /* LU number i.e. LUN */ return (a->lun > b->lun ? 1 : a->lun < b->lun ? -1 : 0); break; } } int cmpVsanFctn (const void *_a, const void *_b) { FcFabricElementHash **a = (FcFabricElementHash **)_a; FcFabricElementHash **b = (FcFabricElementHash **)_b; Counter a_=0, b_=0; switch(myGlobals.columnSort) { case 1: /* VSAN */ return ((*a)->vsanId > (*b)->vsanId ? 1 : (*a)->vsanId < (*b)->vsanId ? -1 : 0); break; case 2: /* Principal Switch */ return (memcmp ((void *)&(*a)->principalSwitch.str, (void *)&(*b)->principalSwitch.str, 8)); break; case 3: /* Total bytes */ a_ = (*a)->totBytes.value; b_ = (*b)->totBytes.value; if(a_ < b_) return(-1); else if(a_ > b_) return(1); else return(0); break; case 4: /* Total Frames */ a_ = (*a)->totPkts.value; b_ = (*b)->totPkts.value; if(a_ < b_) return(-1); else if(a_ > b_) return(1); else return(0); break; } return(-1); } /* ************************************ */ int cmpFcDomainFctn (const void *_a, const void *_b) { SortedFcDomainStatsEntry *a = (SortedFcDomainStatsEntry *)_a; SortedFcDomainStatsEntry *b = (SortedFcDomainStatsEntry *)_b; switch(myGlobals.columnSort) { case 0: /* Rcvd */ return (a->stats->rcvdBytes.value > b->stats->rcvdBytes.value ? 1 : a->stats->rcvdBytes.value < b->stats->rcvdBytes.value ? -1 : 0); break; case 2: /* Sent */ default: return (a->stats->sentBytes.value > b->stats->sentBytes.value ? 1 : a->stats->sentBytes.value < b->stats->sentBytes.value ? -1 : 0); break; } } /* ************************************ */ void printFcHostTrafficStats(HostTraffic *el, int actualDeviceId) { Counter totalSent, totalRcvd; Counter actTotalSent, actTotalRcvd; char buf[LEN_GENERAL_WORK_BUFFER]; char linkName[LEN_GENERAL_WORK_BUFFER/2]; totalSent = el->fcCounters->fcBytesSent.value; totalRcvd = el->fcCounters->fcBytesRcvd.value; printHostHourlyTraffic(el); /* printPacketStats(el, actualDeviceId); */ if((totalSent == 0) && (totalRcvd == 0)) return; printSectionTitle("Protocol Distribution"); sendString("
\n" ""TABLE_ON"" "" "\n"); actTotalSent = el->fcCounters->fcFcpBytesSent.value; actTotalRcvd = el->fcCounters->fcFcpBytesRcvd.value; printTableDoubleEntry(buf, sizeof(buf), "SCSI", CONST_COLOR_1, (float)actTotalSent/1024, 100*((float)SD(actTotalSent, totalSent)), (float)actTotalRcvd/1024, 100*((float)SD(actTotalRcvd, totalRcvd))); actTotalSent = el->fcCounters->fcElsBytesSent.value; actTotalRcvd = el->fcCounters->fcElsBytesRcvd.value; printTableDoubleEntry(buf, sizeof(buf), "ELS", CONST_COLOR_1, (float)actTotalSent/1024, 100*((float)SD(actTotalSent, totalSent)), (float)actTotalRcvd/1024, 100*((float)SD(actTotalRcvd, totalRcvd))); actTotalSent = el->fcCounters->fcDnsBytesSent.value; actTotalRcvd = el->fcCounters->fcDnsBytesRcvd.value; printTableDoubleEntry(buf, sizeof(buf), "NS", CONST_COLOR_1, (float)actTotalSent/1024, 100*((float)SD(actTotalSent, totalSent)), (float)actTotalRcvd/1024, 100*((float)SD(actTotalRcvd, totalRcvd))); actTotalSent = el->fcCounters->fcSwilsBytesSent.value; actTotalRcvd = el->fcCounters->fcSwilsBytesRcvd.value; printTableDoubleEntry(buf, sizeof(buf), "SWILS", CONST_COLOR_1, (float)actTotalSent/1024, 100*((float)SD(actTotalSent, totalSent)), (float)actTotalRcvd/1024, 100*((float)SD(actTotalRcvd, totalRcvd))); actTotalSent = el->fcCounters->fcIpfcBytesSent.value; actTotalRcvd = el->fcCounters->fcIpfcBytesRcvd.value; printTableDoubleEntry(buf, sizeof(buf), "IP/FC", CONST_COLOR_1, (float)actTotalSent/1024, 100*((float)SD(actTotalSent, totalSent)), (float)actTotalRcvd/1024, 100*((float)SD(actTotalRcvd, totalRcvd))); actTotalSent = el->fcCounters->otherFcBytesSent.value; actTotalRcvd = el->fcCounters->otherFcBytesRcvd.value; printTableDoubleEntry(buf, sizeof(buf), "Others", CONST_COLOR_1, (float)actTotalSent/1024, 100*((float)SD(actTotalSent, totalSent)), (float)actTotalRcvd/1024, 100*((float)SD(actTotalRcvd, totalRcvd))); { totalSent = el->fcCounters->fcBytesSent.value; totalRcvd = el->fcCounters->fcBytesRcvd.value; if((totalSent > 0) || (totalRcvd > 0)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", getRowColor()); sendString(buf); if(el->fcCounters->hostNumFcAddress[0] != '\0') { strncpy (linkName, fc_to_str ((u_int8_t *)&el->fcCounters->hostFcAddress), sizeof (linkName)); } if(totalSent > 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", linkName, fc_to_str ((u_int8_t *)&el->fcCounters->hostFcAddress)); sendString(buf); } else { sendString(""); } if(totalRcvd > 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", linkName, fc_to_str ((u_int8_t *)&el->fcCounters->hostFcAddress)); sendString(buf); } else { sendString(""); } sendString(""); #ifdef NOT_YET if((el->fcCounters->fcFcpBytesSent.value + el->fcCounters->fcElsBytesSent.value + el->fcCounters->fcDnsBytesSent.value + el->otherFcBytesSent.value) > 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", getRowColor()); sendString(buf); if((el->fcCounters->fcFcpBytesSent.value + el->fcCounters->fcElsBytesSent.value + el->fcCounters->fcDnsBytesSent.value + el->otherFcBytesSent.value) > 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", fc_to_str(&el->fcCounters->hostFcAddress), fc_to_str (&el->fcCounters->hostFcAddress)); sendString(buf); } else sendString(""); if((el->fcCounters->fcFcpBytesRcvd.value + el->fcCounters->fcElsBytesRcvd.value + el->fcCounters->fcDnsBytesRcvd.value + el->otherFcBytesRcvd.value) > 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", fc_to_str(&el->fcCounters->hostFcAddress), fc_to_str (&el->fcCounters->hostFcAddress)); sendString(buf); } else sendString(""); sendString(""); } #endif /* NOT_YET */ } } sendString("
ProtocolTotal Bytes SentTotal Bytes Rcvd
Protocol Distribution" " \"Received 
Traffic Distribution" " 
 
"TABLE_OFF"

\n"); sendString("

\n"); } /* ************************************ */ void printFcHostContactedPeers(HostTraffic *el, int actualDeviceId) { u_int i, titleSent = 0; char buf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf[LEN_GENERAL_WORK_BUFFER]; HostTraffic tmpEl; if((el->pktSent.value != 0) || (el->pktRcvd.value != 0)) { int ok =0; /* Also allocate space for FC info structure */ tmpEl.fcCounters = NULL; if(allocFcScsiCounters(&tmpEl) == NULL) return; tmpEl.l2Family = FLAG_HOST_TRAFFIC_AF_FC; tmpEl.fcCounters->devType = SCSI_DEV_UNINIT; tmpEl.magic = CONST_MAGIC_NUMBER; for(i=0; icontactedSentPeers.peersSerials[i]) && (!cmpSerial(&el->contactedSentPeers.peersSerials[i], &myGlobals.otherHostEntry->hostSerial))) || ((!emptySerial(&el->contactedRcvdPeers.peersSerials[i]) && (!cmpSerial(&el->contactedRcvdPeers.peersSerials[i], &myGlobals.otherHostEntry->hostSerial)))))) { ok = 1; break; } if(ok) { HostTraffic *el2; int numEntries; for(numEntries = 0, i=0; icontactedSentPeers.peersSerials[i]) && (!cmpSerial(&el->contactedSentPeers.peersSerials[i], &myGlobals.otherHostEntry->hostSerial))) { if((el2 = quickHostLink(el->contactedSentPeers.peersSerials[i], myGlobals.actualReportDeviceId, &tmpEl)) != NULL) { if(numEntries == 0) { printSectionTitle("Last Contacted Peers"); titleSent = 1; sendString("
\n" "
\n"); sendString(""TABLE_ON"" "" "\n"); } safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "\n", getRowColor(), makeFcHostLink(el2, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), el2->fcCounters->hostNumFcAddress); sendString(buf); numEntries++; } } if(numEntries > 0) { sendString("
Sent ToAddress
%s%s 
"TABLE_OFF"
\n"); } else { sendString(" \n"); } /* ***************************************************** */ for(numEntries = 0, i=0; icontactedRcvdPeers.peersSerials[i])) && (!cmpSerial(&el->contactedRcvdPeers.peersSerials[i], &myGlobals.otherHostEntry->hostSerial))) { if((el2 = quickHostLink(el->contactedRcvdPeers.peersSerials[i], myGlobals.actualReportDeviceId, &tmpEl)) != NULL) { if(numEntries == 0) { if(!titleSent) printSectionTitle("Last Contacted Peers"); sendString("
"TABLE_ON"" "" "\n"); } safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "\n", getRowColor(), makeFcHostLink(el2, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), el2->fcCounters->hostNumFcAddress); sendString(buf); numEntries++; } } if(numEntries > 0) { sendString("
Received FromAddress
%s%s
"TABLE_OFF"\n"); } sendString("
"TABLE_OFF"

\n"); sendString("

\n"); } /* ok */ if(tmpEl.fcCounters != NULL) { free (tmpEl.fcCounters); } } else { traceEvent (CONST_TRACE_ALWAYSDISPLAY, "printFcHostContactedPeers: else part\n"); } } /* ************************************ */ void printFcHostDetailedInfo(HostTraffic *el, int actualDeviceId) { char buf[LEN_GENERAL_WORK_BUFFER], buf1[64]; float percentage; Counter total, tot1; char *vendorName; char formatBuf[32], formatBuf1[32], formatBuf2[32]; accessAddrResMutex("printFcHostDetailedInfo"); buf1[0]=0; safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Info about %s\n", el->hostResolvedName); releaseAddrResMutex(); printSectionTitle(buf); sendString("
\n"); sendString("

"TABLE_ON"\n"); accessAddrResMutex("printAllSessions-2"); if(el->fcCounters->vsanId) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "VSAN", el->fcCounters->vsanId, myGlobals.separator /* it avoids empty cells not to be rendered */); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "VSAN", myGlobals.separator /* it avoids empty cells not to be rendered */); } sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "FC_ID", el->fcCounters->hostNumFcAddress, myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); if(el->fcCounters->pWWN.str[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Port WWN", fcwwn_to_str ((u_int8_t *)&el->fcCounters->pWWN), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } if(el->fcCounters->nWWN.str[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Node WWN", fcwwn_to_str ((u_int8_t *)&el->fcCounters->nWWN), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } vendorName = getVendorInfo(&el->fcCounters->pWWN.str[2], 1); if(vendorName[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Nw Board Vendor", vendorName, myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } sendString("
%s" "%d%s
%s" "N/A%s
%s" "%s%s
%s" "%s%s
%s" "%s%s
%s" "%s%s
"TABLE_OFF"

\n"); sendString("

\n"); sendString("
\n"); sendString("

"TABLE_ON"\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "\n", getRowColor(), "First/Last Seen", formatTime(&(el->firstSeen), formatBuf, sizeof (formatBuf)), formatTime(&(el->lastSeen), formatBuf1, sizeof (formatBuf1)), formatSeconds(el->lastSeen - el->firstSeen, formatBuf2, sizeof (formatBuf2))); sendString(buf); if(el->fcCounters->numOffline.value) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Number Of Times Offline", formatPkts(el->fcCounters->numOffline.value, formatBuf, sizeof (formatBuf)), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString (buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Last Offline Time", formatTime(&el->fcCounters->lastOfflineTime, formatBuf, sizeof (formatBuf)), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString (buf); if(el->fcCounters->lastOnlineTime) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Last Online Time", formatTime(&el->fcCounters->lastOnlineTime, formatBuf, sizeof (formatBuf)), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString (buf); } } sendString("
%s" "%s  -  %s [%s]
%s" "%s%s
%s" "%s%s
%s" "%s%s
"TABLE_OFF"

\n"); sendString("

\n"); sendString("
\n"); sendString("

"TABLE_ON"\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "\n", getRowColor(), "MTU", el->fcCounters->fcRecvSize); sendString(buf); if(el->fcCounters->devType != SCSI_DEV_UNINIT) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "SCSI Device Type", el->fcCounters->devType == SCSI_DEV_BLOCK ? "Target, Block" : el->fcCounters->devType == SCSI_DEV_SSC ? "Target, Tape" : el->fcCounters->devType == SCSI_DEV_UNKNOWN ? "Target, Unknown" : el->fcCounters->devType == SCSI_DEV_INITIATOR ? "Initiator" : "Other", myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } if((el->fcCounters->devType != SCSI_DEV_UNINIT) && (el->fcCounters->devType != SCSI_DEV_INITIATOR)) { if(el->fcCounters->vendorId[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Device Vendor", el->fcCounters->vendorId, myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } if(el->fcCounters->productId[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Product Name", el->fcCounters->productId, myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } if(el->fcCounters->productRev[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Product Revision", el->fcCounters->productRev, myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } } sendString("
%s%d 
%s" "%s%s
%s" "%s%s
%s" "%s%s
%s" "%s%s
"TABLE_OFF"

\n"); sendString("

\n"); sendString("
\n"); sendString("

"TABLE_ON"\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Total Data Rcvd", formatBytes(el->fcCounters->fcBytesRcvd.value, 1, formatBuf, sizeof (formatBuf)), formatPkts(el->pktRcvd.value, formatBuf1, sizeof (formatBuf1))); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Total Data Sent", formatBytes(el->fcCounters->fcBytesSent.value, 1, formatBuf, sizeof (formatBuf)), formatPkts(el->pktSent.value, formatBuf1, sizeof (formatBuf1))); sendString(buf); total = el->pktSent.value+el->pktRcvd.value; if(total > 0) { percentage = ((float)el->pktSent.value*100)/((float)total); printTableEntryPercentage(buf, sizeof(buf), "Sent vs. Rcvd Pkts", "Sent", "Rcvd", -1, percentage, 0, 0); } total = el->fcCounters->fcBytesSent.value+el->fcCounters->fcBytesRcvd.value; if(total > 0) { percentage = ((float)el->fcCounters->fcBytesSent.value*100)/((float)total); printTableEntryPercentage(buf, sizeof(buf), "Sent vs. Rcvd Data", "Sent", "Rcvd", -1, percentage, 0, 0); } tot1 = el->fcCounters->class3Sent.value + el->fcCounters->class3Rcvd.value; if((total > 0) && (tot1 > 0)) { percentage = (((float)tot1*100)/total); printTableEntryPercentage(buf, sizeof(buf), "Class 3 vs. Other Traffic", "Class 3", "Other Classes", -1, percentage, 0, 0); } tot1 = el->fcCounters->fcFcpBytesRcvd.value + el->fcCounters->fcFcpBytesSent.value; if((total > 0) && (tot1 > 0)) { percentage = (((float)tot1*100)/total); printTableEntryPercentage(buf, sizeof(buf), "SCSI vs. Others Traffic", "SCSI", "Others", -1, percentage, 0, 0); } tot1 = el->fcCounters->scsiReadBytes.value + el->fcCounters->scsiWriteBytes.value; if(tot1 > 0) { percentage = (((float)el->fcCounters->scsiReadBytes.value*100)/tot1); printTableEntryPercentage(buf, sizeof(buf), "SCSI Read vs. Write Bytes", "SCSI Read", "SCSI Write", -1, percentage, 0, 0); } /* RRD */ if(el->fcCounters->hostNumFcAddress[0] != '\0') { if(strcmp(myGlobals.device[0].name, "pcap-file")) { struct stat statbuf; char key[128]; safe_snprintf(__FILE__, __LINE__, key, sizeof (key), "%s-%d", el->fcCounters->hostNumFcAddress, el->fcCounters->vsanId); /* Do NOT add a '/' at the end of the path because Win32 will complain about it */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "%s/interfaces/%s/hosts/%s", myGlobals.rrdPath != NULL ? myGlobals.rrdPath : ".", myGlobals.device[myGlobals.actualReportDeviceId].uniqueIfName, dotToSlash(key)); if(stat(buf, &statbuf) == 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n" "\n", getRowColor(), myGlobals.device[myGlobals.actualReportDeviceId].uniqueIfName, dotToSlash(key), el->hostResolvedName[0] != '\0' ? el->hostResolvedName : el->fcCounters->hostNumFcAddress); sendString(buf); } } } /* **************************** */ sendString("
%s" "" "%s/%s Pkts
%s" "" "%s/%s Pkts
Historical Data" "[ " "\"view ]" "
"TABLE_OFF"

\n"); sendString("

\n"); } void printScsiLunStats (HostTraffic *el, int actualDeviceId, int sortedColumn, int revertOrder, int pageNum, char *url) { u_int idx, numEntries, skipEntries = 0; int printedEntries=0; int duration; LunStatsSortedEntry sortedLunTbl[MAX_LUNS_SUPPORTED]; LunStatsSortedEntry *entry; char buf[LEN_GENERAL_WORK_BUFFER], *sign; char formatBuf[32], formatBuf1[32], formatBuf2[32], formatBuf3[32], formatBuf4[32], formatBuf5[32]; char *arrowGif, *arrow[48], *theAnchor[48]; char htmlAnchor[64], htmlAnchor1[64], pageUrl[64]; char pcapFilename[128]; Counter dataSent, dataRcvd; if((el->fcCounters->devType == SCSI_DEV_UNINIT) || (el->fcCounters->devType == SCSI_DEV_INITIATOR)) { printNoDataYet(); return; } printSectionTitle("LUN Statistics"); memset(buf, 0, sizeof(buf)); memset(sortedLunTbl, 0, sizeof (sortedLunTbl)); myGlobals.columnSort = sortedColumn; for (idx=0, numEntries=0; idx < MAX_LUNS_SUPPORTED; idx++) { if(el->fcCounters->activeLuns[idx] != NULL) { sortedLunTbl[numEntries].lun = idx; sortedLunTbl[numEntries++].stats = el->fcCounters->activeLuns[idx]; } } if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } if(numEntries > 0) { myGlobals.columnSort = sortedColumn; qsort(sortedLunTbl, numEntries, sizeof(LunStatsSortedEntry), cmpLunFctn); /* Need to add info about page in Hosts Info mode */ safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), " */ #ifdef WIN32 safe_snprintf(__FILE__, __LINE__, pcapFilename, sizeof(pcapFilename), "file:%s\ntop-suspicious-pkts.none.pcap", myGlobals.runningPref.pcapLogBasePath); #else safe_snprintf(__FILE__, __LINE__, pcapFilename, sizeof(pcapFilename), "file://%s/ntop-suspicious-pkts.none.pcap", myGlobals.runningPref.pcapLogBasePath); #endif sendString("
\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), ""TABLE_ON"" "" "" "" "" "" "" "" "" "" "\n", theAnchor[1], arrow[1]); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), theAnchor[2], arrow[2], theAnchor[3], arrow[3]); sendString(buf); for(idx=0; idxstats->bytesSent.value; dataRcvd = entry->stats->bytesRcvd.value; duration = entry->stats->lastSeen.tv_sec-entry->stats->firstSeen.tv_sec; if(entry != NULL) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), entry->lun, formatBytes (dataSent, 1, formatBuf, sizeof (formatBuf)), formatBytes (dataRcvd, 1, formatBuf1, sizeof (formatBuf1)), formatBytes (entry->stats->scsiRdBytes.value, 1, formatBuf2, sizeof (formatBuf2)), formatBytes (entry->stats->scsiWrBytes.value, 1, formatBuf3, sizeof (formatBuf3)), formatBytes (entry->stats->scsiOtBytes.value, 1, formatBuf4, sizeof (formatBuf4)), entry->stats->minRdSize, entry->stats->maxRdSize, entry->stats->minWrSize, entry->stats->maxWrSize, entry->stats->minXferRdySize, entry->stats->maxXferRdySize, entry->stats->numFailedCmds, duration, formatTime((time_t *)&(entry->stats->lastSeen), formatBuf5, sizeof (formatBuf5)) ); sendString(buf); /* Avoid huge tables */ if(printedEntries++ > myGlobals.runningPref.maxNumLines) break; } } sendString("
%s1>LUN%sTotal BytesData BytesRead SizeWrite SizeXfer Rdy Size# Failed CmdsDuration(secs)Last Seen

%s2>Sent%s%s3>Rcvd%sReadWriteOtherMinMaxMinMaxMinMax


%d%s%s%s%s%s%d%d%d%d%d%d%d%d%s
"TABLE_OFF"\n"); sendString("
\n"); addPageIndicator(pageUrl, pageNum, numEntries, myGlobals.runningPref.maxNumLines, revertOrder, sortedColumn, -1); printFooterHostLink(); } else printNoDataYet(); } void printScsiLunGraphs (HostTraffic *el, int actualDeviceId) { char buf[LEN_GENERAL_WORK_BUFFER], buf1[64]; buf[0] = buf1[0] = '\0'; if((el->fcCounters->devType == SCSI_DEV_UNINIT) || (el->fcCounters->devType == SCSI_DEV_INITIATOR)) { printNoDataYet(); return; } //printHTMLheader ("LUN Traffic Graphs (Top 25)", 0, 0); printSectionTitle("LUN Traffic (Total Bytes)"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "", el->fcCounters->hostNumFcAddress, el->fcCounters->hostNumFcAddress); sendString(buf); printSectionTitle("LUN Traffic (Total Frames)"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "", el->fcCounters->hostNumFcAddress, el->fcCounters->hostNumFcAddress); sendString(buf); } void printVsanDetailedInfo (u_int vsanId, int actualDeviceId) { char buf[LEN_GENERAL_WORK_BUFFER], buf1[64]; char formatBuf[32], formatBuf1[32]; int i; char *vendorName; u_int idx; FcFabricElementHash *hash, **theHash; FcDomainList *domListEntry; accessAddrResMutex("printAllSessionsHTML"); buf1[0]=0; if(vsanId) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Info about VSAN %d\n", vsanId); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Info about VSAN\n"); } releaseAddrResMutex(); printSectionTitle(buf); if((theHash = myGlobals.device[actualDeviceId].vsanHash) == NULL) { printNoDataYet (); return; } /* Locate the entry belonging to the VSAN */ idx = vsanId % MAX_ELEMENT_HASH; if(theHash[idx] == NULL) { printNoDataYet (); return; } while (1) { if(theHash[idx]->vsanId == vsanId) break; idx = (idx+1) % MAX_ELEMENT_HASH; if(++idx == MAX_ELEMENT_HASH) { printNoDataYet (); return; } } hash = theHash[idx]; sendString("
\n"); sendString("

"TABLE_ON"\n"); accessAddrResMutex("printAllSessions-2"); if(hash->principalSwitch.str[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Principal Switch", fcwwn_to_str (&hash->principalSwitch.str[0]), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); vendorName = getVendorInfo(&hash->principalSwitch.str[2], 1); if(vendorName[0] != '\0') { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Principal Switch Vendor", vendorName, myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } } if(hash->fabricConfStartTime) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Last Fabric Configuration Started At", formatTime(&hash->fabricConfStartTime, formatBuf, sizeof (formatBuf)), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } if(hash->zoneConfStartTime) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", getRowColor(), "Last Zone Configuration Started At", formatTime(&hash->zoneConfStartTime, formatBuf, sizeof (formatBuf)), myGlobals.separator /* it avoids empty cells not to be rendered */); sendString(buf); } sendString("" "
%s" "%s%s
%s" "%s%s
%s" "%s%s
%s" "%s%s
Switches In Fabric"); sendString(""TABLE_ON"\n" "" "\n"); i = hash->domainListLen; domListEntry = hash->domainList; if(domListEntry != NULL) { while ((i > 0) && (domListEntry != NULL)) { if(domListEntry->recordType == 1 /* TBD: Change 01 to meaningful * define */) { safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "" "" "", getRowColor(), domListEntry->domainId, fcwwn_to_str ((u_int8_t *)&domListEntry->switchWWN.str), getVendorInfo (&domListEntry->switchWWN.str[2], 1), formatBytes (hash->domainStats[domListEntry->domainId].sentBytes.value, 1, formatBuf, sizeof (formatBuf)), formatBytes (hash->domainStats[domListEntry->domainId].rcvdBytes.value, 1, formatBuf1, sizeof (formatBuf1)) ); sendString (buf); } i -= 16; domListEntry = (FcDomainList *)((char *)domListEntry + 16); } } else { /* Print just the stats, without more switch information */ for (i = 1; i < MAX_FC_DOMAINS; i++) { if((hash->domainStats[i].sentBytes.value != 0) || (hash->domainStats[i].rcvdBytes.value != 0)) { safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "" "" "", getRowColor(), i, "N/A", "N/A", formatBytes (hash->domainStats[i].sentBytes.value, 1, formatBuf, sizeof (formatBuf)), formatBytes (hash->domainStats[i].rcvdBytes.value, 1, formatBuf1, sizeof (formatBuf1)) ); sendString (buf); } } } sendString("\n"); sendString("
DomainWWNSwitch VendorBytes SentBytes Rcvd
%x%s%s%s%s
%x%s%s%s%s
"TABLE_OFF"

\n"); sendString("

"TABLE_OFF"

\n"); /* **************************** */ printSectionTitle("Top Domain Traffic Distribution (Sent)"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "", vsanId, vsanId); sendString(buf); printSectionTitle("Top Domain Traffic Distribution (Received)"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "", vsanId, vsanId); sendString(buf); printVsanProtocolStats (hash, actualDeviceId); #ifdef NOT_YET printFcTrafficMatrix (vsanId, TRUE); printSectionTitle("Control Traffic Distribution"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "", vsanId, vsanId); sendString(buf); #endif sendString("

\n"); } /* ************************************ */ static char* formatFcElementData (FcFabricElementHash *hash, u_char printBytes, char *buf, int bufLen) { char formatBuf[32]; if((printBytes && (hash->totBytes.value == 0)) || (!printBytes && (hash->totPkts.value == 0))) return(" "); if(printBytes) { safe_snprintf(__FILE__, __LINE__, buf, bufLen, "%s", formatBytes(hash->totBytes.value, 1, formatBuf, sizeof (formatBuf))); } else { safe_snprintf(__FILE__, __LINE__, buf, bufLen, "%s", formatPkts(hash->totPkts.value, formatBuf, sizeof (formatBuf))); } return(buf); } /* ******************************** */ void dumpFcFabricElementHash (FcFabricElementHash **theHash, char* label, u_char dumpLoopbackTraffic, u_char vsanHash) { u_char entries[MAX_HASHDUMP_ENTRY]; char buf[LEN_GENERAL_WORK_BUFFER], buf1[96], buf3[96], hostLinkBuf[LEN_GENERAL_WORK_BUFFER], formatBuf[32], vsanBuf[32]; int i; HostTraffic *el; if(theHash == NULL) return; /* *********** */ #ifdef FC_DEBUG for(i=0; ivsanId); hash = theHash[i]->next; while(hash != NULL) { printf("%d ", hash->vsanId); hash = hash->next; } printf("\n"); } #endif /* *********** */ memset(entries, 0, sizeof(entries)); for (i=0; ivsanId < MAX_HASHDUMP_ENTRY) && (theHash[i]->vsanId < MAX_USER_VSAN)) { if(theHash[i]->totPkts.value) entries[theHash[i]->vsanId] = 1; } } sendString("
\n\n\n\n" "\n"); sendString("\n"); if(vsanHash) sendString("\n"); sendString("\n"); /* ****************** */ for(i=0; i\n" "\n\n\n\n", makeVsanLink (i, FLAG_HOSTLINK_TEXT_FORMAT, vsanBuf, sizeof (vsanBuf)), i, fcwwn_to_str ((u_int8_t *)&theHash[i]->principalSwitch.str), formatFcElementData(theHash[i], 1, buf1, sizeof(buf1)), formatFcElementData(theHash[i], 0, buf3, sizeof(buf3)), formatTime(&theHash[i]->fabricConfStartTime, formatBuf, sizeof (formatBuf))); sendString(buf); sendString("\n\n"); } } sendString("\n
"); sendString(label); sendString("Principal Switch"); sendString("Total Traffic (Bytes)Total Traffic (Frames)Last Fabric Conf TimeNx_Ports
%s\">%d%s%s%s%s "); if(vsanHash) { int iEntryCount=0; for(el = getFirstHost(myGlobals.actualReportDeviceId); el != NULL; el = getNextHost (myGlobals.actualReportDeviceId, el)) { if((el->fcCounters->vsanId == i) && isValidFcNxPort (&el->fcCounters->hostFcAddress) && (el->fcCounters->fcBytesSent.value || el->fcCounters->fcBytesRcvd.value)) { if(++iEntryCount == 1) sendString("
    "); sendString("
  • "); sendString (makeFcHostLink (el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf))); sendString("
  • \n"); } } if(iEntryCount > 0) sendString("
\n"); } sendString("
\n
\n"); } /* ************************************ */ void printFcDisplayOptions (void) { sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("FC Host Display Options ", 0, 0); } /* ******************************************************** */ void printVsanProtocolStats (FcFabricElementHash *hash, int actualDeviceId) { Counter total; char buf[LEN_GENERAL_WORK_BUFFER]; if(hash == NULL) { return; } if((total = hash->totBytes.value) == 0) { return; } printSectionTitle("VSAN Protocol Distribution"); sendString("
\n" ""TABLE_ON"" "\n"); if(hash->fcFcpBytes.value) { printTableEntry(buf, sizeof(buf), "SCSI", CONST_COLOR_1, (float)hash->fcFcpBytes.value/1024, 100*((float)SD(hash->fcFcpBytes.value, total)), 0, 0, 0); } if(hash->fcElsBytes.value) { printTableEntry(buf, sizeof(buf), "ELS", CONST_COLOR_1, (float)hash->fcElsBytes.value/1024, 100*((float)SD(hash->fcElsBytes.value, total)), 0, 0, 0); } if(hash->fcDnsBytes.value) { printTableEntry(buf, sizeof (buf), "NS", CONST_COLOR_1, (float)hash->fcDnsBytes.value/1024, 100*((float)SD(hash->fcDnsBytes.value, total)), 0, 0, 0); } if(hash->fcIpfcBytes.value) { printTableEntry(buf, sizeof (buf), "IP/FC", CONST_COLOR_1, (float)hash->fcIpfcBytes.value/1024, 100*((float)SD(hash->fcIpfcBytes.value, total)), 0, 0, 0); } if(hash->fcSwilsBytes.value) { printTableEntry(buf, sizeof (buf), "SWILS", CONST_COLOR_1, (float)hash->fcSwilsBytes.value/1024, 100*((float)SD(hash->fcSwilsBytes.value, total)), 0, 0, 0); } if(hash->otherFcBytes.value) { printTableEntry(buf, sizeof (buf), "Others", CONST_COLOR_1, (float)hash->otherFcBytes.value/1024, 100*((float)SD(hash->otherFcBytes.value, total)), 0, 0, 0); } sendString("
ProtocolTotal Bytes
"TABLE_OFF"

\n"); sendString("

\n"); } /* ******************************* */ void printFcHostsInfo(int sortedColumn, int revertOrder, int pageNum, int showBytes, int vsanId) { u_int idx, numEntries, maxHosts; int printedEntries=0, i; unsigned short maxBandwidthUsage=1 /* avoid divisions by zero */; struct hostTraffic *el; struct hostTraffic** tmpTable; char buf[2*LEN_GENERAL_WORK_BUFFER], *arrowGif, *sign, *arrow[12], *theAnchor[12]; char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER]; char htmlAnchor[64], htmlAnchor1[64], tmpbuf[LEN_FC_ADDRESS_DISPLAY]; u_char *vsanList, foundVsan = 0, vsanStr[16]; vsanList = calloc(1, MAX_USER_VSAN); if(vsanList == NULL) return; vsanId = abs(vsanId); printSectionTitle("FibreChannel Hosts Information"); maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */ tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcHostsInfo"); if(tmpTable == NULL) { free (vsanList); return; } memset(buf, 0, sizeof(buf)); if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } myGlobals.columnSort = sortedColumn; numEntries = 0; for(el=getFirstHost(myGlobals.actualReportDeviceId); el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) { unsigned short actUsage, actUsageS, actUsageR; if (!isFcHost (el) || (el->fcCounters->vsanId > MAX_USER_VSAN)) continue; if (isValidVsanId (el->fcCounters->vsanId)) { vsanList[el->fcCounters->vsanId] = 1; foundVsan = 1; } if ((vsanId > 0) && (vsanId != el->fcCounters->vsanId)) continue; if((el->fcCounters->hostNumFcAddress[0] != '\0') && el->fcCounters->fcBytesSent.value) { if(showBytes) { actUsage = (unsigned short)(0.5+100.0*(((float)el->fcCounters->fcBytesSent.value+(float)el->fcCounters->fcBytesRcvd.value)/ (float)myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value)); actUsageS = (unsigned short)(0.5+100.0*((float)el->fcCounters->fcBytesSent.value/ (float)myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value)); actUsageR = (unsigned short)(0.5+100.0*((float)el->fcCounters->fcBytesRcvd.value/ (float)myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value)); } else { actUsage = (unsigned short)(0.5+100.0*(((float)el->fcCounters->fcPktsSent.value+(float)el->fcCounters->fcPktsRcvd.value)/ (float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value)); actUsageS = (unsigned short)(0.5+100.0*((float)el->fcCounters->fcPktsSent.value/ (float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value)); actUsageR = (unsigned short)(0.5+100.0*((float)el->fcCounters->fcPktsRcvd.value/ (float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value)); } el->actBandwidthUsage = actUsage; if(el->actBandwidthUsage > maxBandwidthUsage) maxBandwidthUsage = actUsage; el->actBandwidthUsageS = actUsageS; el->actBandwidthUsageR = actUsageR; } tmpTable[numEntries++]=el; if(numEntries >= maxHosts) break; } if(numEntries <= 0) { printNoDataYet(); free(vsanList); free(tmpTable); return; } qsort(tmpTable, numEntries, sizeof(struct hostTraffic*), sortHostFctn); safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), "
"); if(vsanId > 0) safe_snprintf(__FILE__, __LINE__, (char*)vsanStr, sizeof(vsanStr), "&VSAN=%d", vsanId); else vsanStr[0] = '\0'; if(showBytes) safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Traffic Unit: [ Bytes ] " "[ Packets ] ", CONST_FC_HOSTS_INFO_HTML, myGlobals.columnSort, vsanStr); else safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Traffic Unit: [ Bytes ] " "[ Packets ] ", CONST_FC_HOSTS_INFO_HTML, myGlobals.columnSort, vsanStr); sendString(buf); sendString("

\n"); if(foundVsan) { u_char found = 0; sendString("

VSAN: "); for(i=0; i< MAX_USER_VSAN; i++) if(vsanList[i] == 1) { if(i == vsanId) safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "[ %d ] ", i), found = 1; else safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "[ %d ] ", CONST_FC_HOSTS_INFO_HTML, showBytes, i, i); sendString(buf); } if(!found) safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "[ All ] "); else safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "[ All ] ", CONST_FC_HOSTS_INFO_HTML, showBytes); sendString(buf); } safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

"TABLE_ON"\n" "" "" "\n" "" "" "" "\n", theAnchor[3], arrow[3], theAnchor[1], arrow[1], theAnchor[2], arrow[2], theAnchor[4], arrow[4], theAnchor[9], arrow[9] ); sendString(buf); for(idx=pageNum*myGlobals.runningPref.maxNumLines; idxfcCounters->hostFcAddress), LEN_FC_ADDRESS_DISPLAY); tmpName1 = tmpbuf; if((tmpName1[0] == '\0') || (strcmp(tmpName1, "0.0.0.0") == 0)) tmpName1 = myGlobals.separator; tmpName2 = getVendorInfo (&el->fcCounters->pWWN.str[2], 0); if(tmpName2[0] == '\0') { tmpName2 = "N/A"; } #ifdef FC_DEBUG traceEvent(CONST_TRACE_INFO, "FC_DEBUG: %s <=> %s [%s/%s]", el->hostNumIpAddress, sniffedName, el->hostResolvedName, el->hostNumIpAddress); #endif safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", getRowColor()); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "", makeVsanLink (el->fcCounters->vsanId, 0, vsanBuf, sizeof (vsanBuf))); sendString (buf); sendString(makeFcHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf))); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", tmpName1); sendString(buf); printBar(buf, sizeof(buf), el->actBandwidthUsageS, el->actBandwidthUsageR, maxBandwidthUsage, 3); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", tmpName2); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", formatSeconds(el->lastSeen - el->firstSeen, formatBuf, sizeof (formatBuf))); sendString(buf); sendString("\n"); printedEntries++; /* Avoid huge tables */ if(printedEntries > myGlobals.runningPref.maxNumLines) break; } else { traceEvent(CONST_TRACE_WARNING, "quicksort() problem!"); } } sendString("
%s3>VSAN%s%s1>FC_Port%s%s2>FC Address%s%s4>Bandwidth%sNw Board Vendor%s9>Age%s
%s%s%s%s
"TABLE_OFF"

\n"); sendString("

\n"); printFooterHostLink(); printBandwidthFooter(); addPageIndicator(CONST_HOSTS_INFO_HTML, pageNum, numEntries, myGlobals.runningPref.maxNumLines, revertOrder, abs(sortedColumn), -1); free(vsanList); free(tmpTable); } /* ************************************ */ void printFcAccounting(int remoteToLocal, int sortedColumn, int revertOrder, int pageNum) { u_int idx, numEntries = 0, maxHosts, i; int printedEntries=0; HostTraffic *el, **tmpTable; char buf[LEN_GENERAL_WORK_BUFFER], *sign; char tmpbuf[LEN_WWN_ADDRESS_DISPLAY+1]; char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[2][32]; char hostLinkBuf[LEN_GENERAL_WORK_BUFFER]; Counter totalBytesSent, totalBytesRcvd, totalBytes, a=0, b=0; float sentpct, rcvdpct; time_t timeDiff = time(NULL)-myGlobals.initialSniffTime; char *arrowGif, *arrow[8], *theAnchor[8]; char htmlAnchor[64], htmlAnchor1[64]; printSectionTitle("FibreChannel Per Port Traffic"); maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */ tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcAccounting"); if(tmpTable == NULL) return; if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } totalBytesSent=0, totalBytesRcvd=0; for(el=getFirstHost(myGlobals.actualReportDeviceId); el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) { if(!isFcHost (el)) continue; /* Skip Control VSAN traffic */ if(el->fcCounters->vsanId > MAX_USER_VSAN) continue; if((el->fcCounters->fcBytesSent.value > 0) || (el->fcCounters->fcBytesRcvd.value > 0)) { tmpTable[numEntries++]=el; totalBytesSent += el->fcCounters->fcBytesSent.value; totalBytesRcvd += el->fcCounters->fcBytesRcvd.value; } if(numEntries >= maxHosts) break; } if(numEntries <= 0) { printNoDataYet(); free(tmpTable); return; } myGlobals.columnSort = sortedColumn; qsort(tmpTable, numEntries, sizeof(struct hostTraffic*), cmpHostsFctn); safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), "\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), ""TABLE_ON"\n" "" "" "\n" "" "\n", theAnchor[5], arrow[5], theAnchor[1], arrow[1], theAnchor[2], arrow[2], theAnchor[3], arrow[3], theAnchor[4], arrow[4]); sendString(buf); for(idx=pageNum*myGlobals.runningPref.maxNumLines; idxfcCounters->hostNumFcAddress, LEN_FC_ADDRESS_DISPLAY); tmpName1 = tmpbuf; a = el->fcCounters->fcBytesSent.value; b = el->fcCounters->fcBytesRcvd.value; if(a < 100) /* Avoid very small decimal values */ sentpct = 0; else sentpct = (100*(float)a)/totalBytesSent; if(b < 100) /* Avoid very small decimal values */ rcvdpct = 0; else rcvdpct = (100*(float)b)/totalBytesRcvd; safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "%s" "%s" "" "\n", getRowColor(), makeVsanLink (el->fcCounters->vsanId, FLAG_HOSTLINK_HTML_FORMAT, vsanBuf, sizeof (vsanBuf)), makeFcHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), tmpName1, formatBytes(a, 1, formatBuf[0], 32), sentpct, myGlobals.separator, formatBytes(b, 1, formatBuf[1], 32), rcvdpct, myGlobals.separator); sendString(buf); /* Avoid huge tables */ if(printedEntries++ > myGlobals.runningPref.maxNumLines) break; } } sendString("
%s5\">VSAN%s%s1\">FC_Port%s%s2\">FC_ID%s%s3\">Bytes Sent%s%s4\">Bytes Rcvd%s
%s%s%.1f%s%%%s%.1f%s%%
"TABLE_OFF"\n"); addPageIndicator(CONST_FC_TRAFFIC_HTML, pageNum, numEntries, myGlobals.runningPref.maxNumLines, revertOrder, abs(sortedColumn), -1); sendString("

"TABLE_ON"\n" "" "\n"); totalBytes = totalBytesSent+totalBytesRcvd; safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "\n", formatBytes(totalBytes, 1, formatBuf[0], 32), formatThroughput((float)(totalBytes/timeDiff), 1, formatBuf[1], 32)); sendString(buf); sendString("
Total TrafficUsed Bandwidth
%s%s
"TABLE_OFF"\n"); sendString("
\n"); printFooterHostLink(); free(tmpTable); } /* ********************************** */ int printScsiSessionBytes (int actualDeviceId, int sortedColumn, int revertOrder, int pageNum, char *url, HostTraffic *el) { int idx, j, i; int numSessions, printedSessions, skipSessions; ScsiSessionSortEntry *tmpTable, *entry; FCSession *session; char buf[LEN_GENERAL_WORK_BUFFER*2], *sign; char *arrowGif, *arrow[48], *theAnchor[48]; char htmlAnchor[64], htmlAnchor1[64]; char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[7][32]; char hostLinkBuf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf1[LEN_GENERAL_WORK_BUFFER]; char pageUrl[64]; printSectionTitle("SCSI Sessions"); if(!myGlobals.runningPref.enableSessionHandling) { printNotAvailable("-z or --disable-sessions"); return 0; } /* We have to allocate as many entries as there are sessions and LUNs * within a session. */ tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); if(tmpTable == NULL) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n"); return 0; } memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); for(i=strlen(url); i>0; i--) if(url[i] == '?') { url[i] = '\0'; break; } urlFixupToRFC1945Inplace(url); accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionBytes"); /* Let's count sessions first */ for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) { session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx]; while (session != NULL) { if(session->magic != CONST_MAGIC_NUMBER) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n"); break; } if(session->fcpBytesSent.value || session->fcpBytesRcvd.value) { if((el && ((session->initiator == el) || (session->remotePeer == el))) || (el == NULL)) { for (j = 0; j < MAX_LUNS_SUPPORTED; j++) { if(session->activeLuns[j] != NULL) { if((session->activeLuns[j]->invalidLun && !myGlobals.runningPref.noInvalidLunDisplay) || (!session->activeLuns[j]->invalidLun)) { tmpTable[numSessions].initiator = session->initiator; tmpTable[numSessions].target = session->remotePeer; tmpTable[numSessions].lun = j; tmpTable[numSessions++].stats = session->activeLuns[j]; } if(j > session->lunMax) break; } } if((session->unknownLunBytesSent.value || session->unknownLunBytesRcvd.value)) { if((el && ((session->initiator == el) || (session->remotePeer == el))) || (el == NULL)) { tmpTable[numSessions].initiator = session->initiator; tmpTable[numSessions].target = session->remotePeer; tmpTable[numSessions].lun = 0xFFFF; tmpTable[numSessions++].stats = (ScsiLunTrafficInfo *)session; } } } } session = session->next; } } if(numSessions > 0) { if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } myGlobals.columnSort = sortedColumn; qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn); if(el == NULL) { if(strcmp (url, CONST_SCSI_BYTES_HTML) == 0) { safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), "
initiator != el) && (entry->target != el)) { continue; } if((skipSessions++) < pageNum*myGlobals.runningPref.maxNumLines) { continue; } if(printedSessions == 0) { sendString("
\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), ""TABLE_ON"" "" "" "" "" "" "" "" "" "" "" "\n", theAnchor[1], arrow[1], theAnchor[2], arrow[2], theAnchor[3], arrow[3]); sendString (buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), theAnchor[4], arrow[4], theAnchor[5], arrow[5], theAnchor[6], arrow[6], theAnchor[7], arrow[7], theAnchor[8], arrow[8], theAnchor[9], arrow[9], theAnchor[10], arrow[10], theAnchor[11], arrow[11], theAnchor[12], arrow[12], theAnchor[13], arrow[13], theAnchor[14], arrow[14], theAnchor[15], arrow[15], theAnchor[16], arrow[16]); sendString(buf); } if(entry->lun != 0xFFFF) { dataSent = entry->stats->bytesSent.value; dataRcvd = entry->stats->bytesRcvd.value; /* Sanity check */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), makeVsanLink (entry->initiator->fcCounters->vsanId, 0, vsanBuf, sizeof (vsanBuf)), makeFcHostLink(entry->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), makeFcHostLink(entry->target, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof (hostLinkBuf1)), entry->lun, formatBytes(dataSent, 1, formatBuf[0], 32), formatBytes(dataRcvd, 1, formatBuf[1], 32), formatBytes (entry->stats->scsiRdBytes.value, 1, formatBuf[2], 32), formatBytes (entry->stats->scsiWrBytes.value, 1, formatBuf[3], 32), formatBytes (entry->stats->scsiOtBytes.value, 1, formatBuf[4], 32), entry->stats->minRdSize, entry->stats->maxRdSize, entry->stats->minWrSize, entry->stats->maxWrSize, formatBytes (entry->stats->minXferRdySize, 1, formatBuf[5], 32), formatBytes (entry->stats->maxXferRdySize, 1, formatBuf[6], 32), entry->stats->minIops, entry->stats->maxIops ); } else { /* Unknown LUN data */ session = (FCSession *)entry->stats; /* Sanity check */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), makeVsanLink (entry->initiator->fcCounters->vsanId, 0, vsanBuf, sizeof (vsanBuf)), makeFcHostLink(entry->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), makeFcHostLink(entry->target, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof (hostLinkBuf1)), "N/A", formatBytes(session->unknownLunBytesSent.value, 1, formatBuf[0], 32), formatBytes(session->unknownLunBytesRcvd.value, 1, formatBuf[1], 32), "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" ); } sendString(buf); printedSessions++; } } if(printedSessions > 0) { sendString("
%s1>VSAN%s%s2>Initiator%s%s3>Target%sLUNTotal BytesData BytesRd Size(Blks)Wr Size(Blks)Xfer Rdy SizeIOPS
%s4>Sent%s%s5>Rcvd%s%s6>Read%s%s7>Write%s%s8>Other%s%s9>Min%s%s10>Max%s%s11>Min%s%s12>Max%s%s13>Min%s%s14>Max%s%s15>Min%s%s16>Max%s
%s%s%s%d%s%s%s%s%s%d%d%d%d%s%s%.1f%.1f
%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s
"TABLE_OFF"

\n"); sendString("

\n"); sendString("

Note: Entries with LUN as N/A indicate traffic for which no command frame was seen

\n"); addPageIndicator(pageUrl, pageNum, numSessions-1, myGlobals.runningPref.maxNumLines, revertOrder, sortedColumn, -1); printFooterHostLink(); } else { if(el == NULL) { printFlagedWarning("No SCSI Sessions"); } } free (tmpTable); return (printedSessions); } /* ********************************** */ int printScsiSessionTimes (int actualDeviceId, int sortedColumn, int revertOrder, int pageNum, char *url, HostTraffic *el) { int idx, j, i; int numSessions, printedSessions, skipSessions; ScsiSessionSortEntry *tmpTable, *entry; FCSession *session; char buf[LEN_GENERAL_WORK_BUFFER], *sign; char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[10][32]; char hostLinkBuf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf1[LEN_GENERAL_WORK_BUFFER]; char *arrowGif, *arrow[48], *theAnchor[48]; char htmlAnchor[64], htmlAnchor1[64], pageUrl[64]; printSectionTitle("SCSI Sessions: Latencies"); if(!myGlobals.runningPref.enableSessionHandling) { printNotAvailable("-z or --disable-sessions"); return 0; } /* We have to allocate as many entries as there are sessions and LUNs * within a session. */ tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); if(tmpTable == NULL) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n"); return 0; } memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); for(i=strlen(url); i>0; i--) if(url[i] == '?') { url[i] = '\0'; break; } urlFixupFromRFC1945Inplace(url); accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionTimes"); /* Let's count sessions first */ for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) { session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx]; while (session != NULL) { if(session->magic != CONST_MAGIC_NUMBER) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n"); break; } if(session->fcpBytesSent.value || session->fcpBytesRcvd.value) { if((el && ((session->initiator == el) || (session->remotePeer == el))) || (el == NULL)) { for (j = 0; j < MAX_LUNS_SUPPORTED; j++) { if(session->activeLuns[j] != NULL) { if((session->activeLuns[j]->invalidLun && !myGlobals.runningPref.noInvalidLunDisplay) || (!session->activeLuns[j]->invalidLun)) { tmpTable[numSessions].initiator = session->initiator; tmpTable[numSessions].target = session->remotePeer; tmpTable[numSessions].lun = j; tmpTable[numSessions++].stats = session->activeLuns[j]; } if(j > session->lunMax) break; } } /* Don't care about unknown LUN info as we don't gather * anything but bytes for such traffic. */ } } session = session->next; } } if(numSessions > 0) { if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } myGlobals.columnSort = sortedColumn; qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn); if(el == NULL) { if(strcmp (url, CONST_SCSI_TIMES_HTML) == 0) { safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), "
initiator != el) && (entry->target != el)) { continue; } if((skipSessions++) < pageNum*myGlobals.runningPref.maxNumLines) { continue; } if(printedSessions == 0) { sendString("
\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), ""TABLE_ON"" "" "" "" "" "" "" "" "" "" "" "\n", theAnchor[1], arrow[1], theAnchor[2], arrow[2], theAnchor[3], arrow[3], theAnchor[26], arrow[26], theAnchor[27], arrow[27]); sendString (buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "" "" "" "" "" "" "" "" "" "\n", getRowColor(), theAnchor[18], arrow[18], theAnchor[19], arrow[19], theAnchor[20], arrow[20], theAnchor[21], arrow[21], theAnchor[22], arrow[22], theAnchor[23], arrow[23], theAnchor[24], arrow[24], theAnchor[25], arrow[25]); sendString(buf); } /* Sanity check */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), makeVsanLink (entry->initiator->fcCounters->vsanId, 0, vsanBuf, sizeof (vsanBuf)), makeFcHostLink(entry->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), makeFcHostLink(entry->target, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof (hostLinkBuf1)), entry->lun, formatLatency (entry->stats->minRTT, FLAG_STATE_ACTIVE, formatBuf[0], sizeof(formatBuf[0])), formatLatency (entry->stats->maxRTT, FLAG_STATE_ACTIVE, formatBuf[1], sizeof(formatBuf[1])), formatLatency (entry->stats->minXfrRdyRTT, FLAG_STATE_ACTIVE, formatBuf[2], sizeof(formatBuf[2])), formatLatency (entry->stats->maxXfrRdyRTT, FLAG_STATE_ACTIVE, formatBuf[3], sizeof(formatBuf[3])), formatLatency (entry->stats->minRdFrstDataRTT, FLAG_STATE_ACTIVE, formatBuf[4], sizeof(formatBuf[4])), formatLatency (entry->stats->maxRdFrstDataRTT, FLAG_STATE_ACTIVE, formatBuf[5], sizeof(formatBuf[5])), formatLatency (entry->stats->minWrFrstDataRTT, FLAG_STATE_ACTIVE, formatBuf[6], sizeof(formatBuf[6])), formatLatency (entry->stats->maxWrFrstDataRTT, FLAG_STATE_ACTIVE, formatBuf[7], sizeof(formatBuf[7])), formatTime((time_t *)&(entry->stats->firstSeen), formatBuf[8], sizeof(formatBuf[8])), formatTime((time_t *)&(entry->stats->lastSeen), formatBuf[9], sizeof(formatBuf[9])) ); sendString(buf); printedSessions++; } } if(printedSessions > 0) { sendString("
%s1>VSAN%s%s2>Initiator%s%s3>Target%sLUNCmd-Status RTTCmd-XFR_RDY RTTCmd-Data RTT(Rd)Cmd-Data RTT(Wr)%s26>Active Since%s%s27>Last Seen%s
%s18>Min%s%s19>Max%s%s20>Min%s%s21>Max%s%s22>Min%s%s23>Max%s%s24>Min%s%s25>Max%s
%s%s%s%d%s%s%s%s%s%s%s%s%s%s
"TABLE_OFF"

\n"); sendString("

\n"); addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.runningPref.maxNumLines, revertOrder, sortedColumn, -1); printFooterHostLink(); } else { if(el == NULL) { printFlagedWarning("No SCSI Sessions"); } } free (tmpTable); return (printedSessions); } /* ********************************** */ int printScsiSessionStatusInfo(int actualDeviceId, int sortedColumn, int revertOrder, int pageNum, char *url, HostTraffic *el) { int idx, j, i; int numSessions, printedSessions, skipSessions; ScsiSessionSortEntry *tmpTable, *entry; FCSession *session; char buf[LEN_GENERAL_WORK_BUFFER], *sign; char *arrowGif, *arrow[48], *theAnchor[48]; char htmlAnchor[64], htmlAnchor1[64], pageUrl[64]; char vsanBuf[LEN_MEDIUM_WORK_BUFFER]; char hostLinkBuf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf1[LEN_GENERAL_WORK_BUFFER]; printSectionTitle("SCSI Sessions: Status Info"); if(!myGlobals.runningPref.enableSessionHandling) { printNotAvailable("-z or --disable-sessions"); return 0; } /* We have to allocate as many entries as there are sessions and LUNs * within a session. */ tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); if(tmpTable == NULL) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n"); return 0; } memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); for(i=strlen(url); i>0; i--) if(url[i] == '?') { url[i] = '\0'; break; } urlFixupFromRFC1945Inplace(url); accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionStatusInfo"); /* Let's count sessions first */ for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) { session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx]; while (session != NULL) { if(session->magic != CONST_MAGIC_NUMBER) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n"); break; } if(session->fcpBytesSent.value || session->fcpBytesRcvd.value) { if((el && ((session->initiator == el) || (session->remotePeer == el))) || (el == NULL)) { for (j = 0; j < MAX_LUNS_SUPPORTED; j++) { if(session->activeLuns[j] != NULL) { if((session->activeLuns[j]->invalidLun && !myGlobals.runningPref.noInvalidLunDisplay) || (!session->activeLuns[j]->invalidLun)) { tmpTable[numSessions].initiator = session->initiator; tmpTable[numSessions].target = session->remotePeer; tmpTable[numSessions].lun = j; tmpTable[numSessions++].stats = session->activeLuns[j]; } if(j > session->lunMax) break; } } } } session = session->next; } } if(numSessions > 0) { if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } myGlobals.columnSort = sortedColumn; qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn); if(el == NULL) { if(strcmp (url, CONST_SCSI_STATUS_HTML) == 0) { safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), "
initiator != el) && (entry->target != el)) { continue; } if((skipSessions++) < pageNum*myGlobals.runningPref.maxNumLines) { continue; } if(printedSessions == 0) { sendString("
\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), ""TABLE_ON"" "" "" "" "" "" "" "" "" "" "" "\n", theAnchor[1], arrow[1], theAnchor[2], arrow[2], theAnchor[3], arrow[3], theAnchor[17], arrow[17], theAnchor[28], arrow[28], theAnchor[29], arrow[29], theAnchor[30], arrow[30], theAnchor[31], arrow[31], theAnchor[32], arrow[32]); sendString (buf); } /* Sanity check */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), makeVsanLink (entry->initiator->fcCounters->vsanId, 0, vsanBuf, sizeof (vsanBuf)), makeFcHostLink(entry->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), makeFcHostLink(entry->target, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof (hostLinkBuf1)), entry->lun, entry->stats->numFailedCmds, entry->stats->chkCondCnt, entry->stats->busyCnt, entry->stats->resvConflictCnt, entry->stats->taskSetFullCnt, entry->stats->taskAbrtCnt); sendString(buf); printedSessions++; } } if(printedSessions > 0) { sendString("
%s1>VSAN%s%s2>Initiator%s%s3>Target%sLUN%s17># Failed Cmds%s%s28># Check Condition%s%s29># Busy%s%s30># Reservation Conflict%s%s31># Task Set Full%s%s32># Task Aborts%s
%s%s%s%d%d%d%d%d%d%d
"TABLE_OFF"

\n"); sendString("

\n"); addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.runningPref.maxNumLines, revertOrder, sortedColumn, -1); printFooterHostLink(); } else { if(el == NULL) printFlagedWarning("No SCSI Sessions"); } free (tmpTable); return (printedSessions); } /* ********************************** */ int printScsiSessionTmInfo (int actualDeviceId, int sortedColumn, int revertOrder, int pageNum, char *url, HostTraffic *el) { int idx, j, i; int numSessions, printedSessions, skipSessions; ScsiSessionSortEntry *tmpTable, *entry; FCSession *session; char buf[LEN_GENERAL_WORK_BUFFER], *sign; char *arrowGif, *arrow[48], *theAnchor[48]; char htmlAnchor[64], htmlAnchor1[64], pageUrl[64]; char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[2][32]; char hostLinkBuf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf1[LEN_GENERAL_WORK_BUFFER]; printSectionTitle("SCSI Sessions: Task Management Info"); if(!myGlobals.runningPref.enableSessionHandling) { printNotAvailable("-z or --disable-sessions"); return 0; } /* We have to allocate as many entries as there are sessions and LUNs * within a session. */ tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); if(tmpTable == NULL) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n"); return 0; } memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry)); for(i=strlen(url); i>0; i--) if(url[i] == '?') { url[i] = '\0'; break; } urlFixupFromRFC1945Inplace(url); accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionTmInfo"); /* Let's count sessions first */ for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) { session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx]; while (session != NULL) { if(session->magic != CONST_MAGIC_NUMBER) { traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n"); break; } if((session->fcpBytesRcvd.value) || (session->fcpBytesSent.value)) { if((el && ((session->initiator == el) || (session->remotePeer == el))) || (el == NULL)) { for (j = 0; j < MAX_LUNS_SUPPORTED; j++) { if(session->activeLuns[j] != NULL) { if((session->activeLuns[j]->invalidLun && !myGlobals.runningPref.noInvalidLunDisplay) || (!session->activeLuns[j]->invalidLun)) { tmpTable[numSessions].initiator = session->initiator; tmpTable[numSessions].target = session->remotePeer; tmpTable[numSessions].lun = j; tmpTable[numSessions++].stats = session->activeLuns[j]; } if(j > session->lunMax) break; } } } } session = session->next; } } if(numSessions > 0) { if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } myGlobals.columnSort = sortedColumn; qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn); if(el == NULL) { if(strcmp (url, CONST_SCSI_TM_HTML) == 0) { safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), "
initiator != el) && (entry->target != el)) { continue; } if((skipSessions++) < pageNum*myGlobals.runningPref.maxNumLines) { continue; } if(printedSessions == 0) { sendString("
\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), ""TABLE_ON"" "" "" "" "", theAnchor[1], arrow[1], theAnchor[2], arrow[2], theAnchor[3], arrow[3]); sendString (buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "" "" "" "" "" "" "" "\n", theAnchor[33], arrow[33], theAnchor[34], arrow[34], theAnchor[35], arrow[35], theAnchor[36], arrow[36], theAnchor[37], arrow[37], theAnchor[38], arrow[38], theAnchor[39], arrow[39]); sendString (buf); } /* Sanity check */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), makeVsanLink (entry->initiator->fcCounters->vsanId, 0, vsanBuf, sizeof (vsanBuf)), makeFcHostLink(entry->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), makeFcHostLink(entry->target, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof (hostLinkBuf1)), entry->lun, entry->stats->abrtTaskSetCnt, entry->stats->clearTaskSetCnt, entry->stats->clearAcaCnt, entry->stats->tgtRstCnt, entry->stats->lunRstCnt, formatTime((time_t *)&(entry->stats->lastTgtRstTime), formatBuf[0], 32), formatTime((time_t *)&(entry->stats->lastLunRstTime), formatBuf[1], 32)); sendString(buf); printedSessions++; } } if(printedSessions > 0) { sendString("
%s1>VSAN%s%s2>Initiator%s%s3>Target%sLUN%s33># Abort Task Set%s%s34># Clear Task Set%s%s35># Clear ACA%s%s36># Target Reset%s%s37># LUN Reset%s%s38>Last Target Reset Time%s%s39>Last LUN Reset Time%s
%s%s%s%d%d%d%d%d%d%s%s
"TABLE_OFF"

\n"); sendString("

\n"); addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.runningPref.maxNumLines, revertOrder, sortedColumn, -1); printFooterHostLink(); } else { if(el == NULL) { printFlagedWarning("No SCSI Sessions"); } } free (tmpTable); return (printedSessions); } /* ********************************** */ void printFCSessions (int actualDeviceId, int sortedColumn, int revertOrder, int pageNum, char *url, HostTraffic *el) { int idx, i; int numSessions, printedSessions, skipSessions; unsigned long duration; char buf[LEN_GENERAL_WORK_BUFFER], *sign; char *arrowGif, *arrow[48], *theAnchor[48]; char htmlAnchor[64], htmlAnchor1[64]; char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[7][32]; char hostLinkBuf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf1[LEN_GENERAL_WORK_BUFFER]; FCSession **tmpTable, *session; printSectionTitle("FibreChannel Sessions"); if(!myGlobals.runningPref.enableSessionHandling) { printNotAvailable("-z or --disable-sessions"); return; } tmpTable = (FCSession**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numFcSessions*sizeof(FCSession *), "printFCSessions"); if(tmpTable == NULL) return; for(i=strlen(url); i>0; i--) if(url[i] == '?') { url[i] = '\0'; break; } urlFixupFromRFC1945Inplace(url); /* Due to the way sessions are handled, sessions before those to display need to be skipped */ accessMutex(&myGlobals.fcSessionsMutex, "printFCSessions"); /* Let's count sessions first */ for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) { session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx]; while (session != NULL) { if((session->bytesSent.value || session->bytesRcvd.value) && (session->initiator->fcCounters->vsanId < MAX_USER_VSAN)) { if((el && ((session->initiator == el) || (session->remotePeer == el))) || (el == NULL)) { tmpTable[numSessions++] = session; } } session = session->next; } } releaseMutex(&myGlobals.fcSessionsMutex); if(numSessions <= 0) { printNoDataYet (); return; } if(revertOrder) { sign = ""; arrowGif = " " CONST_IMG_ARROW_UP; } else { sign = "-"; arrowGif = " " CONST_IMG_ARROW_DOWN; } myGlobals.columnSort = sortedColumn; qsort (tmpTable, numSessions, sizeof (FCSession **), cmpFcSessionsFctn); if(strcmp (url, CONST_FC_SESSIONS_HTML) == 0) { safe_snprintf(__FILE__, __LINE__, htmlAnchor, sizeof(htmlAnchor), "
initiator != el) && (session->remotePeer != el)) { continue; } if((skipSessions++) < pageNum*myGlobals.runningPref.maxNumLines) { continue; } if(printedSessions == 0) { sendString("
\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), ""TABLE_ON"" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "" "\n", theAnchor[1], arrow[1], theAnchor[2], arrow[2], theAnchor[3], arrow[3], theAnchor[18], arrow[18], theAnchor[19], arrow[19]); sendString (buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n", theAnchor[4], arrow[4], theAnchor[5], arrow[5], theAnchor[6], arrow[6], theAnchor[7], arrow[7], theAnchor[8], arrow[8], theAnchor[9], arrow[9], theAnchor[10], arrow[10], theAnchor[11], arrow[11]); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof (buf), "\n" "\n" "\n" "\n" "\n" "" "\n", theAnchor[12], arrow[12], theAnchor[13], arrow[13], theAnchor[14], arrow[14], theAnchor[15], arrow[15], theAnchor[16], arrow[16], theAnchor[17], arrow[17]); sendString (buf); } dataSent = session->bytesSent.value; dataRcvd = session->bytesRcvd.value; duration = session->lastSeen.tv_sec - session->firstSeen.tv_sec; /* Sanity check */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "\n", getRowColor(), makeVsanLink (session->initiator->fcCounters->vsanId, 0, vsanBuf, sizeof (vsanBuf)), makeFcHostLink(session->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof (hostLinkBuf)), makeFcHostLink(session->remotePeer, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof (hostLinkBuf1)), formatBytes(dataSent, 1, formatBuf[0], 32), formatBytes(dataRcvd, 1, formatBuf[1], 32), formatBytes(session->fcpBytesSent.value, 1, formatBuf[2], 32), formatBytes(session->fcpBytesRcvd.value, 1, formatBuf[3], 32), formatBytes(session->fcElsBytesSent.value, 1, formatBuf[4], 32), formatBytes(session->fcElsBytesRcvd.value, 1, formatBuf[5], 32), formatBytes(session->fcDnsBytesSent.value, 1, formatBuf[6], 32), formatBytes(session->fcDnsBytesRcvd.value, 1, formatBuf[7], 32), formatBytes(session->ipfcBytesSent.value, 1, formatBuf[8], 32), formatBytes(session->ipfcBytesRcvd.value, 1, formatBuf[9], 32), formatBytes(session->fcSwilsBytesSent.value, 1, formatBuf[10], 32), formatBytes(session->fcSwilsBytesRcvd.value, 1, formatBuf[11], 32), formatBytes(session->otherBytesSent.value, 1, formatBuf[12], 32), formatBytes(session->otherBytesRcvd.value, 1, formatBuf[13], 32), formatTime((time_t *)&(session->firstSeen), formatBuf[14], 32), formatTime((time_t *)&(session->lastSeen), formatBuf[15], 32) ); sendString(buf); printedSessions++; } } if(printedSessions > 0) { sendString("
%s1>VSAN%s%s2>Sender%s%s3>Receiver%sTotalSCSIELSNSIP/FCSWILSOthers%s18>Active Since%s%s19>Last Seen%s
%s4>Sent%s%s5>Rcvd%s%s6>Sent%s%s7>Rcvd%s%s8>Sent%s%s9>Rcvd%s%s10>Sent%s%s11>Rcvd%s%s12>Sent%s%s13>Rcvd%s%s14>Sent%s%s15>Rcvd%s%s16>Sent%s%s17>Rcvd%s
%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s
"TABLE_OFF"

\n"); sendString("

\n"); addPageIndicator(url, pageNum, numSessions, myGlobals.runningPref.maxNumLines, revertOrder, sortedColumn, -1); printFooterHostLink(); } else { if(el == NULL) { printFlagedWarning("No FibreChannel Sessions"); } } free (tmpTable); } /* ********************************** */ void printFcProtocolDistribution(int mode, int revertOrder, int printGraph) { char buf[2*LEN_GENERAL_WORK_BUFFER], *sign; float total, partialTotal, remainingTraffic; float percentage; if(revertOrder) sign = ""; else sign = "-"; total = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value; if(total == 0) return; else { int numProtosFound = 0; printSectionTitle("Global FibreChannel Protocol Distribution"); sendString("
\n"); sendString(""TABLE_ON"" "\n"); remainingTraffic = 0; partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcFcpBytes.value; if(partialTotal > 0) { remainingTraffic += partialTotal; percentage = ((float)(partialTotal*100))/((float)total); numProtosFound++; printTableEntry(buf, sizeof(buf), "SCSI", CONST_COLOR_1, partialTotal/1024, percentage, 0, 0, 0); } partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcFiconBytes.value; if(partialTotal > 0) { remainingTraffic += partialTotal; percentage = ((float)(partialTotal*100))/((float)total); numProtosFound++; printTableEntry(buf, sizeof(buf), "FICON", CONST_COLOR_1, partialTotal/1024, percentage, 0, 0, 0); } partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcElsBytes.value; if(partialTotal > 0) { remainingTraffic += partialTotal; percentage = ((float)(partialTotal*100))/((float)total); numProtosFound++; printTableEntry(buf, sizeof(buf), "ELS", CONST_COLOR_1, partialTotal/1024, percentage, 0, 0, 0); } partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcDnsBytes.value; if(partialTotal > 0) { remainingTraffic += partialTotal; percentage = ((float)(partialTotal*100))/((float)total); numProtosFound++; printTableEntry(buf, sizeof(buf), "NS", CONST_COLOR_1, partialTotal/1024, percentage, 0, 0, 0); } partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcIpfcBytes.value; if(partialTotal > 0) { remainingTraffic += partialTotal; percentage = ((float)(partialTotal*100))/((float)total); numProtosFound++; printTableEntry(buf, sizeof(buf), "IP/FC", CONST_COLOR_1, partialTotal/1024, percentage, 0, 0, 0); } partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcSwilsBytes.value; if(partialTotal > 0) { remainingTraffic += partialTotal; percentage = ((float)(partialTotal*100))/((float)total); numProtosFound++; printTableEntry(buf, sizeof(buf), "SWILS", CONST_COLOR_1, partialTotal/1024, percentage, 0, 0, 0); } partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].otherFcBytes.value; if(partialTotal > 0) { remainingTraffic += partialTotal; percentage = ((float)(partialTotal*100))/((float)total); numProtosFound++; printTableEntry(buf, sizeof(buf), "Others", CONST_COLOR_1, partialTotal/1024, percentage, 0, 0, 0); } if ((numProtosFound > 0) && printGraph) sendString("\n"); sendString("
" "FC ProtocolTotal Bytes" "Percentage
" "
"TABLE_OFF"

\n"); /* *********************** */ sendString("

Note:This report includes broadcast packets

\n"); sendString("
\n"); } } /* ************************ */ #ifdef NOT_YET void printFcTrafficMatrix (u_short vsanId, u_char sent) { int i, j, numEntries=0, numConsecutiveEmptyCells; char buf[LEN_GENERAL_WORK_BUFFER]; short *activeHosts; Counter minTraffic=(Counter)LONG_MAX, maxTraffic=0, avgTraffic; Counter avgTrafficLow, avgTrafficHigh, tmpCounter; TrafficEntry *entry; if(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix == NULL) { printFlagedWarning("Traffic matrix is not available for the selected network interface"); return; } /* Print a matrix, using just what the row/column header says: From -> To */ /* This is different from IP which prints a total */ if(vsanId) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "FibreChannel Traffic Matrix For VSAN %d", vsanId); } else { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "FibreChannel Traffic Matrix For VSAN"); } printSectionTitle(buf); activeHosts = (short*)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numHosts*sizeof(short), "printFcTrafficMatrix"); if(activeHosts == NULL) return; for(i=1; ifcCounters->hostNumFcAddress, "ff.ff.fd", sizeof ("ff.ff.fd")) != 0)) { } else if((entry != NULL) && (entry->fcCounters->vsanId == vsanId)) { if((entry->bytesSent.value) || (entry->bytesRcvd.value)) { activeHosts[i] = 1; numEntries++; break; } } } /* Print column header if there is traffic sent from another host to this * host */ if(activeHosts[i] == 1) { if(numEntries == 1) { sendString("
\n"); if(sent) sendString(""TABLE_ON"\n"); else sendString(""TABLE_ON"
 F " "  To
 r
 o
 m
\n"); } safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "", getHostName(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i], 1)); sendString(buf); } } if(numEntries == 0) { printNoDataYet(); free(activeHosts); return; } else sendString("\n"); /* Determine Min & Max values */ for(i=1; ifcCounters->vsanId == vsanId)) { if(sent && entry->bytesSent.value) { if(minTraffic > entry->bytesSent.value) minTraffic = entry->bytesSent.value; if(maxTraffic < entry->bytesSent.value) maxTraffic = entry->bytesSent.value; } else if(!sent && entry->bytesRcvd.value) { if(minTraffic > entry->bytesRcvd.value) minTraffic = entry->bytesRcvd.value; if(maxTraffic < entry->bytesRcvd.value) maxTraffic = entry->bytesRcvd.value; } } } } avgTraffic = (Counter)(((float)minTraffic+(float)maxTraffic)/2); avgTrafficLow = (avgTraffic*15)/100; /* 15% of the average */ avgTrafficHigh = 2*(maxTraffic/3); /* 75% of max traffic */ /* Print rows */ for(i=1; i", getRowColor(), makeFcHostLink(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i], FLAG_HOSTLINK_TEXT_FORMAT, 1, 1)); sendString(buf); for(j=1; jfcCounters->hostNumFcAddress, "ff.ff.fd", sizeof ("ff.ff.fd")) != 0)) { numConsecutiveEmptyCells++; } else if(activeHosts[j] == 1) { if(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx] == NULL) numConsecutiveEmptyCells++; else { if(numConsecutiveEmptyCells > 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", numConsecutiveEmptyCells); sendString(buf); numConsecutiveEmptyCells = 0; } if(sent) { tmpCounter = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx]->bytesSent.value; } else { tmpCounter = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx]->bytesRcvd.value; } /* Fix below courtesy of Danijel Doriae */ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "\n", numConsecutiveEmptyCells); sendString(buf); numConsecutiveEmptyCells = 0; } sendString("\n"); } sendString("
 B " "  From
 y
%s
%s " "%s\n", calculateCellColor(tmpCounter, avgTrafficLow, avgTrafficHigh), formatBytes(tmpCounter, 1)); sendString(buf); } } } if(numConsecutiveEmptyCells > 0) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), " 
"TABLE_OFF"\n

\n"); sendString("

\n"); printFooterHostLink(); free(activeHosts); } #endif /* ******************************************* */ void printVSANList(unsigned int deviceId) { printSectionTitle("VSAN Traffic Statistics"); if(deviceId > myGlobals.numDevices) { printFlagedWarning("Invalid device specified"); return; } else if(myGlobals.device[deviceId].vsanHash == NULL) { printFlagedWarning("No VSAN Traffic Information Available (yet)."); return; } dumpFcFabricElementHash(myGlobals.device[deviceId].vsanHash, "VSAN", 0, 1); } /* ********************************** */ void drawVsanStatsGraph (unsigned int deviceId) { char buf[LEN_GENERAL_WORK_BUFFER], vsanBuf[LEN_MEDIUM_WORK_BUFFER]; FcFabricElementHash **theHash; FcFabricElementHash *tmpTable[MAX_ELEMENT_HASH]; int i, numVsans, j; char vsanLabel[LEN_GENERAL_WORK_BUFFER]; if(deviceId > myGlobals.numDevices) { printFlagedWarning("Invalid device specified"); return; } else if((theHash = myGlobals.device[deviceId].vsanHash) == NULL) { printSectionTitle("VSAN Summary"); printNoDataYet(); return; } printSectionTitle("Top 10 VSANs"); numVsans = 0; memset (tmpTable, 0, sizeof (FcFabricElementHash *)*MAX_ELEMENT_HASH); for (i=0; ivsanId < MAX_HASHDUMP_ENTRY) && (theHash[i]->vsanId < MAX_USER_VSAN)) { if(theHash[i]->totBytes.value) tmpTable[numVsans++] = theHash[i]; } } myGlobals.columnSort = 3; qsort (tmpTable, numVsans, sizeof (FcFabricElementHash **), cmpVsanFctn); sendString("
\n"); sendString(""TABLE_ON"" "\n"); for (i = numVsans-1, j = 0; i >= 0; i--, j++) { if(tmpTable[i] != NULL) { safe_snprintf(__FILE__, __LINE__, vsanLabel, sizeof (vsanLabel), "%s", makeVsanLink (tmpTable[i]->vsanId, 0, vsanBuf, sizeof (vsanBuf))); printTableEntry(buf, sizeof (buf), vsanLabel, CONST_COLOR_1, (float) tmpTable[i]->totBytes.value/1024, 100*((float)SD(tmpTable[i]->totBytes.value, myGlobals.device[deviceId].fcBytes.value)), 0, 0, 0); } if(j >= MAX_VSANS_GRAPHED) break; } sendString("
" "VSANTotal Bytes" "Percentage
"TABLE_OFF"

\n"); printSectionTitle ("VSAN Traffic (Bytes)"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" "" ); sendString(buf); printSectionTitle ("VSAN Traffic (Frames)"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "" ""); sendString(buf); } /* ******************************************* */ void printFcTrafficSummary (u_short vsanId) { int deviceId = myGlobals.actualReportDeviceId; char buf[LEN_GENERAL_WORK_BUFFER], vsanBuf[LEN_MEDIUM_WORK_BUFFER]; FcFabricElementHash **theHash; FcFabricElementHash *tmpTable[MAX_ELEMENT_HASH]; int i, numVsans, j; char vsanLabel[LEN_GENERAL_WORK_BUFFER]; if((theHash = myGlobals.device[deviceId].vsanHash) == NULL) { return; } numVsans = 0; memset (tmpTable, 0, sizeof (FcFabricElementHash *)*MAX_ELEMENT_HASH); for (i=0; ivsanId < MAX_HASHDUMP_ENTRY) && (theHash[i]->vsanId < MAX_USER_VSAN)) { if(theHash[i]->totBytes.value) tmpTable[numVsans++] = theHash[i]; } } myGlobals.columnSort = 3; qsort (tmpTable, numVsans, sizeof (FcFabricElementHash **), cmpVsanFctn); sendString("

"); sendString(""TABLE_ON"" "\n"); for (i = numVsans-1, j = 0; i >= 0; i--, j++) { if(tmpTable[i] != NULL) { safe_snprintf(__FILE__, __LINE__, vsanLabel, sizeof (vsanLabel), "%s", makeVsanLink (tmpTable[i]->vsanId, 0, vsanBuf, sizeof (vsanBuf))); printTableEntry(buf, sizeof (buf), vsanLabel, CONST_COLOR_1, (float) tmpTable[i]->totBytes.value/1024, 100*((float)SD(tmpTable[i]->totBytes.value, myGlobals.device[deviceId].fcBytes.value)), 0, 0, 0); } if(j >= MAX_VSANS_GRAPHED) break; } sendString("
Top 10 VSANS
" "VSANTotal Bytes" "Percentage
"TABLE_OFF"

\n"); }