END_TEST START_TEST(ibwadd_single_success) { cfg.maxbw = 0; ck_assert_int_eq(ibwadd("newinterface", 1), 1); ck_assert_int_eq(ibwget("does_not_exist"), -1); ck_assert_int_eq(ibwget("newinterface"), 1); }
END_TEST START_TEST(ibwflush_success) { cfg.maxbw = 0; ck_assert_int_eq(ibwadd("name1", 1), 1); ck_assert_int_eq(ibwadd("name2", 2), 1); ck_assert_int_eq(ibwget("name1"), 1); ck_assert_int_eq(ibwget("name2"), 2); ck_assert_int_eq(ibwget("does_not_exist"), -1); ibwflush(); ck_assert_int_eq(ibwget("name1"), -1); ck_assert_int_eq(ibwget("name2"), -1); ck_assert_int_eq(ibwget("does_not_exist"), -1); ck_assert_int_eq(ibwadd("name1", 1), 1); ck_assert_int_eq(ibwadd("name2", 2), 1); ck_assert_int_eq(ibwget("name1"), 1); ck_assert_int_eq(ibwget("name2"), 2); ck_assert_int_eq(ibwget("does_not_exist"), -1); }
END_TEST START_TEST(ibwget_with_empty_list_and_maxbw) { cfg.maxbw = 10; ck_assert_int_eq(ibwget("does_not_exist"), 10); }
END_TEST START_TEST(ibwget_from_config) { ck_assert_int_eq(loadcfg("../cfg/vnstat.conf"), 1); ck_assert_int_eq(ibwloadcfg("../cfg/vnstat.conf"), 1); cfg.maxbw = 10; ck_assert_int_eq(ibwget("ethnone"), 8); }
END_TEST START_TEST(ibwadd_multi_success) { cfg.maxbw = 0; ck_assert_int_eq(ibwadd("name1", 1), 1); ck_assert_int_eq(ibwadd("name2", 2), 1); ck_assert_int_eq(ibwadd("name3", 3), 1); ck_assert_int_eq(ibwadd("name4", 2), 1); ck_assert_int_eq(ibwadd("name5", 1), 1); ck_assert_int_eq(ibwadd("name6", 10), 1); ck_assert_int_eq(ibwget("does_not_exist"), -1); ck_assert_int_eq(ibwget("name1"), 1); ck_assert_int_eq(ibwget("name3"), 3); ck_assert_int_eq(ibwget("name4"), 2); ck_assert_int_eq(ibwget("name6"), 10); ck_assert_int_eq(ibwget("name2"), 2); ck_assert_int_eq(ibwget("name5"), 1); ck_assert_int_eq(ibwget("name1"), 1); ck_assert_int_eq(ibwget("does_not_exist"), -1); }
END_TEST START_TEST(ibwadd_update_success) { cfg.maxbw = 0; ck_assert_int_eq(ibwadd("name1", 1), 1); ck_assert_int_eq(ibwadd("name2", 2), 1); ck_assert_int_eq(ibwget("does_not_exist"), -1); ck_assert_int_eq(ibwget("name1"), 1); ck_assert_int_eq(ibwget("name2"), 2); ck_assert_int_eq(ibwget("does_not_exist"), -1); ck_assert_int_eq(ibwadd("name2", 5), 1); ck_assert_int_eq(ibwadd("name1", 4), 1); ck_assert_int_eq(ibwget("name1"), 4); ck_assert_int_eq(ibwget("name2"), 5); ck_assert_int_eq(ibwget("does_not_exist"), -1); }
int addinterfaces(const char *dirname) { char *ifacelist, interface[32]; int index = 0, count = 0, bwlimit = 0; /* get list of currently visible interfaces */ if (getiflist(&ifacelist)==0) { free(ifacelist); return 0; } if (strlen(ifacelist)<2) { free(ifacelist); return 0; } if (debug) printf("Interface list: \"%s\"\n", ifacelist); while (sscanf(ifacelist+index, "%31s", interface)!=EOF) { if (debug) printf("Processing: \"%s\"\n", interface); index += strlen(interface)+1; /* skip local interfaces */ if ((strcmp(interface,"lo")==0) || (strcmp(interface,"lo0")==0) || (strcmp(interface,"sit0")==0)) { if (debug) printf("skip\n"); continue; } /* create database for interface */ initdb(); strncpy_nt(data.interface, interface, 32); strncpy_nt(data.nick, data.interface, 32); if (!getifinfo(interface)) { if (debug) printf("getifinfo failed, skip\n"); continue; } parseifinfo(1); if (!writedb(interface, dirname, 1)) { continue; } count++; bwlimit = ibwget(interface); if (bwlimit > 0) { printf("\"%s\" added with %d Mbit bandwidth limit.\n", interface, bwlimit); } else { printf("\"%s\" added. Warning: no bandwidth limit has been set.\n", interface); } } if (count==1) { printf("-> %d interface added.", count); } else { printf("-> %d interfaces added.", count); } if (count) { printf("\nLimits can be modified using the configuration file. See \"man vnstat.conf\".\n"); printf("Unwanted interfaces can be removed from monitoring with \"vnstat --delete\"."); } printf("\n"); free(ifacelist); return count; }
void parseifinfo(int newdb) { uint64_t rxchange=0, txchange=0, btime, cc; /* rxchange = rx change in MB */ uint64_t krxchange=0, ktxchange=0, maxtransfer; /* krxchange = rx change in kB */ time_t current, interval; struct tm *d; int day, month, year, hour, min, shift, maxbw; int rxkchange=0, txkchange=0; /* changes in the kB counters */ ifinfo.rxp = ifinfo.txp = 0; current=time(NULL); interval=current-data.lastupdated; btime=getbtime(); /* count traffic only if previous update wasn't too long ago */ if ( interval < (60*MAXUPDATEINTERVAL) ) { /* btime in /proc/stat seems to vary ±1 second so we use btime-BVAR just to be safe */ /* the variation is also slightly different between various kernels... */ if (data.btime < (btime-cfg.bvar)) { data.currx=0; data.curtx=0; if (debug) printf("System has been booted.\n"); } /* process rx & tx */ if (newdb!=1) { cc = countercalc(data.currx, ifinfo.rx); rxchange = cc/1048576; /* 1024/1024 */ rxkchange = (cc/1024)%1024; krxchange = cc/1024; ifinfo.rxp = cc%1024; cc = countercalc(data.curtx, ifinfo.tx); txchange = cc/1048576; /* 1024/1024 */ txkchange = (cc/1024)%1024; ktxchange = cc/1024; ifinfo.txp = cc%1024; } /* get bandwidth limit for current interface */ maxbw = ibwget(data.interface); if (maxbw > 0) { /* calculate maximum possible transfer since last update based on set maximum rate */ /* and add 10% in order to be on the safe side */ maxtransfer = ceil((maxbw/(float)8)*interval*(float)1.1); if (debug) printf("interval: %"PRIu64" maxbw: %d maxrate: %"PRIu64" rxc: %"PRIu64" txc: %"PRIu64"\n", (uint64_t)interval, maxbw, maxtransfer, rxchange, txchange); /* sync counters if traffic is greater than set maximum */ if ( (rxchange > maxtransfer) || (txchange > maxtransfer) ) { snprintf(errorstring, 512, "Traffic rate for \"%s\" higher than set maximum %d Mbit (%"PRIu64"->%"PRIu64", r%"PRIu64" t%"PRIu64"), syncing.", data.interface, maxbw, (uint64_t)interval, maxtransfer, rxchange, txchange); printe(PT_Info); rxchange = krxchange = rxkchange = txchange = ktxchange = txkchange = 0; ifinfo.rxp = ifinfo.txp = 0; } } } else { if (debug) printf("Too much time passed since previous update, syncing. (%"PRIu64" < %d)\n", (uint64_t)interval, 60*MAXUPDATEINTERVAL); } /* keep btime updated in case it drifts slowly */ data.btime = btime; data.currx = ifinfo.rx - ifinfo.rxp; data.curtx = ifinfo.tx - ifinfo.txp; addtraffic(&data.totalrx, &data.totalrxk, rxchange, rxkchange); addtraffic(&data.totaltx, &data.totaltxk, txchange, txkchange); /* update days and months */ addtraffic(&data.day[0].rx, &data.day[0].rxk, rxchange, rxkchange); addtraffic(&data.day[0].tx, &data.day[0].txk, txchange, txkchange); addtraffic(&data.month[0].rx, &data.month[0].rxk, rxchange, rxkchange); addtraffic(&data.month[0].tx, &data.month[0].txk, txchange, txkchange); /* fill some variables from current date & time */ d=localtime(¤t); day=d->tm_mday; month=d->tm_mon; year=d->tm_year; hour=d->tm_hour; min=d->tm_min; shift=hour; /* add traffic to previous hour when update happens at X:00 */ /* and previous update was during previous hour */ d=localtime(&data.lastupdated); if ((min==0) && (d->tm_hour!=hour) && ((current-data.lastupdated)<=3600)) { hour--; if (hour<0) { hour=23; } } /* clean and update hourly */ cleanhours(); data.hour[shift].date=current; /* avoid shifting timestamp */ data.hour[hour].rx+=krxchange; data.hour[hour].tx+=ktxchange; /* rotate days in database if needed */ d=localtime(&data.day[0].date); if ((d->tm_mday!=day) || (d->tm_mon!=month) || (d->tm_year!=year)) { /* make a new entry only if there's something to remember (configuration dependent) */ if ( (data.day[0].rx==0) && (data.day[0].tx==0) && (data.day[0].rxk==0) && (data.day[0].txk==0) && (cfg.traflessday==0) ) { data.day[0].date=current; } else { rotatedays(); } } /* rotate months in database if needed */ d=localtime(&data.month[0].month); if ((d->tm_mon!=month) && (day>=cfg.monthrotate)) { rotatemonths(); } }