int connect_server() { int fd; struct sockaddr_un sun; /* Setup for abstract unix socket */ memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; sun.sun_path[0] = 0; sprintf(sun.sun_path+1, "ifstat%dv" VERSION, getuid()); if((fd = socket(AF_UNIX, SOCK_STREAM, 0))==-1) return -1; if(connect(fd, (struct sockaddr*)&sun, sizeof(sun))) { strcpy(sun.sun_path+1, "ifstat0"); if(connect(fd, (struct sockaddr*)&sun, sizeof(sun))) { close(fd); return -1; } } if(verify_forging(fd)) { printf("Forged server!\n"); close(fd); exit(1); } return fd; }
int main(int argc, char *argv[]) { struct sockaddr_un sun; int ch; int fd; while ((ch = getopt(argc, argv, "h?vVd:t:er")) != EOF) { switch(ch) { case 'e': show_errors = 1; break; case 'd': scan_interval = 1000*atoi(optarg); break; case 't': if (sscanf(optarg, "%d", &time_constant) != 1 || time_constant <= 0) { fprintf(stderr, "ifstat: invalid time constant divisor\n"); exit(-1); } break; case 'r' : show_rtstat = 1; break; case 'v': case 'V': printf("ifstat2 utility, %s\n", VERSION); exit(0); case 'h': case '?': default: usage(); } } argc -= optind; argv += optind; /* Setup for abstract unix socket */ sun.sun_family = AF_UNIX; sun.sun_path[0] = 0; sprintf(sun.sun_path+1, "ifstat%d", getuid()); if (scan_interval > 0) { if (time_constant == 0) time_constant = 60; time_constant *= 1000; W = 1 - 1/exp(log(10)*(double)scan_interval/time_constant); if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("ifstat: socket"); exit(-1); } if (bind(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) < 0) { perror("ifstat: bind"); exit(-1); } if (listen(fd, 5) < 0) { perror("ifstat: listen"); exit(-1); } if (fork()) exit(0); chdir("/"); close(0); close(1); close(2); setsid(); signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); exit(0); } /* Client section */ patterns = argv; npatterns = argc; if(show_rtstat) { dump_rtstat_db(stdout); exit(0); } if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 && (connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0 || (strcpy(sun.sun_path+1, "ifstat0"), connect(fd, (struct sockaddr*)&sun, 2+1+strlen(sun.sun_path+1)) == 0)) && verify_forging(fd) == 0) { FILE *sfp = fdopen(fd, "r"); /* Read from daemon */ load_raw_table(sfp); fclose(sfp); dump_kern_db(stdout); exit(0); } perror("socket "); exit(-1); }
int main(int argc, char *argv[]) { char hist_name[128]; struct sockaddr_un sun; FILE *hist_fp = NULL; int ch; int fd; while ((ch = getopt_long(argc, argv, "hjpvVzrnasd:t:e", longopts, NULL)) != EOF) { switch (ch) { case 'z': dump_zeros = 1; break; case 'r': reset_history = 1; break; case 'a': ignore_history = 1; break; case 's': no_update = 1; break; case 'n': no_output = 1; break; case 'e': show_errors = 1; break; case 'j': json_output = 1; break; case 'p': pretty = 1; break; case 'd': scan_interval = atoi(optarg) * 1000; if (scan_interval <= 0) { fprintf(stderr, "ifstat: invalid scan interval\n"); exit(-1); } break; case 't': time_constant = atoi(optarg); if (time_constant <= 0) { fprintf(stderr, "ifstat: invalid time constant divisor\n"); exit(-1); } break; case 'v': case 'V': printf("ifstat utility, iproute2-ss%s\n", SNAPSHOT); exit(0); case 'h': case '?': default: usage(); } } argc -= optind; argv += optind; sun.sun_family = AF_UNIX; sun.sun_path[0] = 0; sprintf(sun.sun_path+1, "ifstat%d", getuid()); if (scan_interval > 0) { if (time_constant == 0) time_constant = 60; time_constant *= 1000; W = 1 - 1/exp(log(10)*(double)scan_interval/time_constant); if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("ifstat: socket"); exit(-1); } if (bind(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) < 0) { perror("ifstat: bind"); exit(-1); } if (listen(fd, 5) < 0) { perror("ifstat: listen"); exit(-1); } if (daemon(0, 0)) { perror("ifstat: daemon"); exit(-1); } signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); exit(0); } patterns = argv; npatterns = argc; if (getenv("IFSTAT_HISTORY")) snprintf(hist_name, sizeof(hist_name), "%s", getenv("IFSTAT_HISTORY")); else snprintf(hist_name, sizeof(hist_name), "%s/.ifstat.u%d", P_tmpdir, getuid()); if (reset_history) unlink(hist_name); if (!ignore_history || !no_update) { struct stat stb; fd = open(hist_name, O_RDWR|O_CREAT|O_NOFOLLOW, 0600); if (fd < 0) { perror("ifstat: open history file"); exit(-1); } if ((hist_fp = fdopen(fd, "r+")) == NULL) { perror("ifstat: fdopen history file"); exit(-1); } if (flock(fileno(hist_fp), LOCK_EX)) { perror("ifstat: flock history file"); exit(-1); } if (fstat(fileno(hist_fp), &stb) != 0) { perror("ifstat: fstat history file"); exit(-1); } if (stb.st_nlink != 1 || stb.st_uid != getuid()) { fprintf(stderr, "ifstat: something is so wrong with history file, that I prefer not to proceed.\n"); exit(-1); } if (!ignore_history) { FILE *tfp; long uptime = -1; if ((tfp = fopen("/proc/uptime", "r")) != NULL) { if (fscanf(tfp, "%ld", &uptime) != 1) uptime = -1; fclose(tfp); } if (uptime >= 0 && time(NULL) >= stb.st_mtime+uptime) { fprintf(stderr, "ifstat: history is aged out, resetting\n"); if (ftruncate(fileno(hist_fp), 0)) perror("ifstat: ftruncate"); } } load_raw_table(hist_fp); hist_db = kern_db; kern_db = NULL; } if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 && (connect(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) == 0 || (strcpy(sun.sun_path+1, "ifstat0"), connect(fd, (struct sockaddr *)&sun, 2+1+strlen(sun.sun_path+1)) == 0)) && verify_forging(fd) == 0) { FILE *sfp = fdopen(fd, "r"); load_raw_table(sfp); if (hist_db && source_mismatch) { fprintf(stderr, "ifstat: history is stale, ignoring it.\n"); hist_db = NULL; } fclose(sfp); } else { if (fd >= 0) close(fd); if (hist_db && info_source[0] && strcmp(info_source, "kernel")) { fprintf(stderr, "ifstat: history is stale, ignoring it.\n"); hist_db = NULL; info_source[0] = 0; } load_info(); if (info_source[0] == 0) strcpy(info_source, "kernel"); } if (!no_output) { if (ignore_history || hist_db == NULL) dump_kern_db(stdout); else dump_incr_db(stdout); } if (!no_update) { if (ftruncate(fileno(hist_fp), 0)) perror("ifstat: ftruncate"); rewind(hist_fp); json_output = 0; dump_raw_db(hist_fp, 1); fclose(hist_fp); } exit(0); }