int main( int argc, char** argv ) { command_t cmd; char line[MAXSTRLEN]; char fullpath[MAXSTRLEN]; int done = FALSE; while (!done) { printf(">> "); fgets(line, MAXSTRLEN, stdin); line[my_strlen(line)-1] = '\0'; // get rid of newline parse(line, &cmd); if (my_strequal(cmd.name, "exit")) { done = TRUE; } else if (is_builtin(&cmd)) { do_builtin(&cmd); } else if (find_fullpath(fullpath, &cmd)) { // NOTE: find_fullpath() is called again in execute execute(&cmd); } else if (line[0] != '\0') { // non-blank line entered printf("invalid command\n"); } cleanup(&cmd); } return 0; } // end main function
int strArrayEqual(UTStringArray *ar1, UTStringArray *ar2) { if(ar1->n != ar2->n) return NO; for(int i = 0; i < ar1->n; i++) { char *s1 = ar1->strs[i]; char *s2 = ar2->strs[i]; if(!my_strequal(s1, s2)) return NO; } return YES; }
SFLAdaptor *adaptorListGet(SFLAdaptorList *adList, char *dev) { for(uint32_t i = 0; i < adList->num_adaptors; i++) { SFLAdaptor *ad = adList->adaptors[i]; if(ad && my_strequal(ad->deviceName, dev)) { // return the one that was already there return ad; } } return NULL; }
int strArrayIndexOf(UTStringArray *ar, char *str) { //if(ar->sorted) { // char **ptr = (char **)bsearch(&str, ar->strs, ar->n, sizeof(char *), mysortcmp); // return ptr ? (ptr - ar->strs) : 0; //} //else for(int i = 0; i < ar->n; i++) { if(my_strequal(str, ar->strs[i])) return i; } return -1; }
static HSPApplicationSettings *getApplicationSettings(HSPSFlowSettings *settings, char *app, int create) { HSPApplicationSettings *appSettings = settings->applicationSettings; for(; appSettings; appSettings = appSettings->nxt) if(my_strequal(app, appSettings->application)) break; if(appSettings == NULL && create) { appSettings = (HSPApplicationSettings *)my_calloc(sizeof(HSPApplicationSettings)); appSettings->application = my_strdup(app); appSettings->nxt = settings->applicationSettings; settings->applicationSettings = appSettings; } return appSettings; }
int readInterfaces_kstat(HSP *sp) { int noErr = 1; kstat_ctl_t *kc = NULL; kstat_t *ksp; #ifndef KSNAME_BUFFER_SIZE #define KSNAME_BUFFER_SIZE 32 #endif char devName[KSNAME_BUFFER_SIZE]; int interfaces_found = 0; int fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { myLog(LOG_ERR, "error opening socket: %d (%s)\n", errno, strerror(errno)); noErr = 0; } struct lifreq lifr; memset(&lifr, 0, sizeof(lifr)); if (noErr) { kc = kstat_open(); if (NULL == kc) { noErr = 0; myLog(LOG_ERR, "readInterfaces kstat_open failed"); } } if (noErr) { for (ksp = kc->kc_chain; NULL != ksp; ksp = ksp->ks_next) { // Look for kstats of class "net" if (ksp->ks_class && ksp->ks_module && ksp->ks_name && !strncmp(ksp->ks_class, "net", 3)) { if(debug > 2) { myLog(LOG_INFO, "ksp class=%s, module=%s name=%s", ksp->ks_class ?: "NULL", ksp->ks_module ?: "NULL", ksp->ks_name ?: "NULL"); } #ifndef KSNAME_BUFFER_SIZE #define KSNAME_BUFFER_SIZE 32 #endif int includeDev = NO; // Concatenate the module name and instance number to create device name snprintf(devName, KSNAME_BUFFER_SIZE, "%s%d", ksp->ks_module, ksp->ks_instance); #if (HSP_SOLARIS >= 5011) // on solaris 11 we collect name=phys, module!=aggr,vnic for counter purposes. // and don't use any of the others for counters. if(my_strequal(ksp->ks_name, "phys") && !my_strequal(ksp->ks_module, "aggr") && !my_strequal(ksp->ks_module, "vnic")) { includeDev = YES; } #else // If device name equals the kstat's name, then we have a kstat the describes the device. if (!strncmp(ksp->ks_name, devName, KSNAME_BUFFER_SIZE)) { includeDev = YES; } #endif if(includeDev == NO) continue; // since we now rely on getifaddrs or lifrec to learn about IP/MAC details, // we are only interested in collecting interfaces to get counters-from here. // find or create the "adaptor" entry for this dev SFLAdaptor *adaptor = adaptorListAdd(sp->adaptorList, devName, NULL, sizeof(HSPAdaptorNIO)); // clear the mark so we don't free it below adaptor->marked = NO; interfaces_found++; // remember some useful flags in the userData structure HSPAdaptorNIO *adaptorNIO = (HSPAdaptorNIO *)adaptor->userData; adaptorNIO->forCounters = YES; adaptorNIO->vlan = HSP_VLAN_ALL; // may be modified below #if 0 kstat_t *ksp_tmp; kstat_named_t *knp; ksp_tmp = kstat_lookup(kc, ksp->ks_module, ksp->ks_instance, "mac"); if (NULL == ksp_tmp) { myLog(LOG_ERR, "kstat_lookup error (module: %s, inst: %d, name: mac): %s", ksp->ks_module, ksp->ks_instance, strerror(errno)); } else { if (-1 == kstat_read(kc, ksp_tmp, NULL)) { myLog(LOG_ERR, "kstat_read error (module: %s, name: %s, class: %s): %s", ksp->ks_module, ksp->ks_name, ksp->ks_class, strerror(errno)); } else { knp = kstat_data_lookup(ksp_tmp, "ifspeed"); if(knp) { adaptor->ifSpeed = knp->value.ui64; } knp = kstat_data_lookup(ksp_tmp, "link_up"); if(knp) { myLog(LOG_INFO, "kstat link_up = %d", knp->value.ui32); } uint32_t direction = 0; knp = kstat_data_lookup(ksp_tmp, "link_duplex"); if(knp) { // The full-duplex and half-duplex values are reversed between the // comment in sflow.h and link_duplex man page. if (knp->value.ui32 == 1) direction = 2; else if (knp->value.ui32 == 2) direction = 1; adaptor->ifDirection = direction; } } } #endif } } }
static int staticStringsIndexOf(const char **strings, char *search) { for(int ss = 0; strings[ss]; ss++) { if(my_strequal((char *)strings[ss],search)) return ss; } return -1; }
void updateBondCounters(HSP *sp, SFLAdaptor *bond) { char procFileName[256]; snprintf(procFileName, 256, "/proc/net/bonding/%s", bond->deviceName); FILE *procFile = fopen(procFileName, "r"); if(procFile) { // limit the number of chars we will read from each line // (there can be more than this - fgets will chop for us) #define MAX_PROC_LINE_CHARS 240 char line[MAX_PROC_LINE_CHARS]; SFLAdaptor *currentSlave = NULL; HSPAdaptorNIO *slave_nio = NULL; HSPAdaptorNIO *bond_nio = (HSPAdaptorNIO *)bond->userData; HSPAdaptorNIO *aggregator_slave_nio = NULL; bond_nio->lacp.attachedAggID = bond->ifIndex; uint32_t aggID = 0; // make sure we don't hold on to stale data - may need // to pick up actorSystemID from a slave port. memset(bond_nio->lacp.actorSystemID, 0, 6); memset(bond_nio->lacp.partnerSystemID, 0, 6); int readingMaster = YES; // bond master data comes first int gotActorID = NO; while(fgets(line, MAX_PROC_LINE_CHARS, procFile)) { char buf_var[MAX_PROC_LINE_CHARS]; char buf_val[MAX_PROC_LINE_CHARS]; // buf_var is up to first ':', buf_val is the rest if(sscanf(line, "%[^:]:%[^\n]", buf_var, buf_val) == 2) { char *tok_var = trimWhitespace(buf_var); char *tok_val = trimWhitespace(buf_val); if(readingMaster) { if(my_strequal(tok_var, "MII Status")) { if(my_strequal(tok_val, "up")) { bond_nio->lacp.portState.v.actorAdmin = 2; // dot3adAggPortActorAdminState bond_nio->lacp.portState.v.actorOper = 2; bond_nio->lacp.portState.v.partnerAdmin = 2; bond_nio->lacp.portState.v.partnerOper = 2; } else { bond_nio->lacp.portState.all = 0; } } if(my_strequal(tok_var, "System Identification")) { if(debug) { myLog(LOG_INFO, "updateBondCounters: %s system identification %s", bond->deviceName, tok_val); } char sys_mac[MAX_PROC_LINE_CHARS]; uint64_t code; if(sscanf(tok_val, "%"SCNu64" %s", &code, sys_mac) == 2) { if(hexToBinary((u_char *)sys_mac,bond_nio->lacp.actorSystemID, 6) != 6) { myLog(LOG_ERR, "updateBondCounters: system mac read error: %s", sys_mac); } else if(!isAllZero(bond_nio->lacp.actorSystemID, 6)) { gotActorID = YES; } } } if(my_strequal(tok_var, "Partner Mac Address")) { if(debug) { myLog(LOG_INFO, "updateBondCounters: %s partner mac is %s", bond->deviceName, tok_val); } if(hexToBinary((u_char *)tok_val,bond_nio->lacp.partnerSystemID, 6) != 6) { myLog(LOG_ERR, "updateBondCounters: partner mac read error: %s", tok_val); } } if(my_strequal(tok_var, "Aggregator ID")) { aggID = strtol(tok_val, NULL, 0); if(debug) { myLog(LOG_INFO, "updateBondCounters: %s aggID %u", bond->deviceName, aggID); } } } // initially the data is for the bond, but subsequently // we get info about each slave. So we started with // (readingMaster=YES,currentSlave=NULL), and now we // detect transitions to slave data: if(my_strequal(tok_var, "Slave Interface")) { readingMaster = NO; currentSlave = adaptorListGet(sp->adaptorList, trimWhitespace(tok_val)); slave_nio = currentSlave ? (HSPAdaptorNIO *)currentSlave->userData : NULL; if(debug) { myLog(LOG_INFO, "updateBondCounters: bond %s slave %s %s", bond->deviceName, tok_val, currentSlave ? "found" : "not found"); } if(slave_nio) { // initialize from bond slave_nio->lacp.attachedAggID = bond->ifIndex; memcpy(slave_nio->lacp.partnerSystemID, bond_nio->lacp.partnerSystemID, 6); memcpy(slave_nio->lacp.actorSystemID, bond_nio->lacp.actorSystemID, 6); // make sure the parent is going to export separate // counters if the slave is going to (because it was // marked as a switchPort): if(slave_nio->switchPort) { bond_nio->switchPort = YES; } // and vice-versa if(bond_nio->switchPort) { slave_nio->switchPort = YES; } } } if(readingMaster == NO && slave_nio) { if(my_strequal(tok_var, "MII Status")) { if(my_strequal(tok_val, "up")) { slave_nio->lacp.portState.v.actorAdmin = 2; // dot3adAggPortActorAdminState slave_nio->lacp.portState.v.actorOper = 2; slave_nio->lacp.portState.v.partnerAdmin = 2; slave_nio->lacp.portState.v.partnerOper = 2; } else { slave_nio->lacp.portState.all = 0; } } if(my_strequal(tok_var, "Permanent HW addr")) { if(!gotActorID) { // Still looking for our actorSystemID, so capture this here in case we // decide below that it is the one we want. Note that this mac may not be the // same as the mac associated with this port that we read back in readInterfaces.c. if(hexToBinary((u_char *)tok_val,slave_nio->lacp.actorSystemID, 6) != 6) { myLog(LOG_ERR, "updateBondCounters: permanent HW addr read error: %s", tok_val); } } } if(my_strequal(tok_var, "Aggregator ID")) { uint32_t slave_aggID = strtol(tok_val, NULL, 0); if(slave_aggID == aggID) { // remember that is the slave port that has the same aggregator ID as the bond aggregator_slave_nio = slave_nio; } } } } } if(aggregator_slave_nio && !gotActorID) { // go back and fill in the actorSystemID on all the slave ports shareActorIDFromSlave(sp, bond_nio, aggregator_slave_nio); } fclose(procFile); } }