#include #include #define DEVICE "ppp0" #define COUNT_VAR "ppp0_bytes" #define UPDATE_VAR "ppp0_updated" void read_procnet(char *device, int *bytesrx, int *bytestx) { FILE *file = fopen("/proc/net/dev", "r"); char linebuf[256]; while (fgets(linebuf, 256, file)) { char *pos = strstr(linebuf, ":"); if (!pos) continue; if (memcmp(pos - strlen(device), device, strlen(device)) != 0) continue; *bytesrx = get_field(pos + 1, 0); *bytestx = get_field(pos + 1, 8); fclose(file); return; } fclose(file); return; } long long get_nvram(char *varname) { char command[64]; snprintf(command, 64, "/usr/sbin/nvram get %s", varname); FILE *pipe; pipe = popen(command, "r"); char value[64]; fgets(value, 64, pipe); pclose(pipe); return atoll(value); } void set_nvram(char *varname, long long value) { char command[128]; snprintf(command, 128, "/usr/sbin/nvram set %s=%lld", varname, value); system(command); } int period_changed(time_t oldtime, time_t newtime) { struct tm period_s; time_t period_t; /* Find the next period change after oldtime */ localtime_r(&oldtime, &period_s); const int change_day = 24; if (period_s.tm_mday >= change_day) period_s.tm_mon++; period_s.tm_mday = change_day; period_s.tm_hour = period_s.tm_min = period_s.tm_sec = 0; period_t = mktime(&period_s); /* Is newtime after the change? */ if (period_t < newtime) return 1; else return 0; } void update_counter() { static int last_count = 0; int now_ifrx = 0, now_iftx = 0; read_procnet(DEVICE, &now_ifrx, &now_iftx); int now_count = now_ifrx + now_iftx; if (now_count < last_count) // Interface counter has reset last_count = 0; long long total = get_nvram(COUNT_VAR); time_t old_update = get_nvram(UPDATE_VAR); if (period_changed(old_update, time(NULL))) // Period has changed total = 0; total += now_count - last_count; last_count = now_count; set_nvram(COUNT_VAR, total); set_nvram(UPDATE_VAR, time(NULL)); } int main() { }