/** * Scan a pid's file descriptors, looking for our * target socket. */ static void process_pid(char *buffer, size_t s, unsigned long pid, unsigned long inode) { DIR *dir; struct dirent *de; size_t len; char pathbuf[25], linkbuf[25], target[25]; /* Root through the process's fds */ snprintf(target, sizeof(target), "socket:[%lu]", inode); snprintf(pathbuf, sizeof(pathbuf), "/proc/%lu/fds", pid); if (!(dir = opendir(pathbuf))) return; while (!*buffer && (de = readdir(dir))) { snprintf(pathbuf, sizeof(pathbuf), "/proc/%lu/fds/%s", pid, de->d_name); len = readlink(pathbuf, linkbuf, sizeof(linkbuf)); if (len <= 0 || len > sizeof(linkbuf)) return; linkbuf[len] = '\0'; if (!strcmp(linkbuf, target)) get_procname(buffer, s, pid); } closedir(dir); }
static int check_procname(FILE *f_cmd, FILE *f_stat, const char *procname) { char *tmp = NULL, *p; size_t l; int ret = SUCCEED; if ('\0' == *procname) return SUCCEED; if (SUCCEED == get_procname(f_stat, &tmp)) { if (0 == strcmp(tmp, procname)) goto clean; } else if (SUCCEED == get_cmdline(f_cmd, &tmp, &l)) { if (NULL == (p = strrchr(tmp, '/'))) p = tmp; else p++; if (0 == strcmp(p, procname)) goto clean; } ret = FAIL; clean: zbx_free(tmp); return ret; }
// Print statistics of a single socket - used in case view mode is e_netstat_like void print_netstat_like(socket_stats_t* p_si_stats, mc_grp_info_t* , FILE* file, int pid) { static const int MAX_ADDR_LEN = strlen("123.123.123.123:12345"); // for max len of ip address and port together char process[PATH_MAX + 1]; if(! p_si_stats->inode) return; // shmem is not updated yet fprintf(file, "%-5s %-9s ", to_str_socket_type_netstat_like(p_si_stats->socket_type), p_si_stats->b_is_offloaded ? "Yes" : "No"); fprintf(file, "%-6d %-6d ", (int)p_si_stats->n_rx_ready_byte_count, (int)p_si_stats->n_tx_ready_byte_count); // // Bounded + Connected information // int len = 0; if (p_si_stats->bound_if || p_si_stats->bound_port) { /* cppcheck-suppress wrongPrintfScanfArgNum */ len = fprintf(file, "%d.%d.%d.%d:%-5d", NIPQUAD(p_si_stats->bound_if), ntohs(p_si_stats->bound_port)); if (len < 0) len = 0; // error } if (len < MAX_ADDR_LEN )fprintf(file, "%*s ", MAX_ADDR_LEN-len, ""); // pad and delimiter fprintf(file, " "); if (p_si_stats->connected_ip || p_si_stats->connected_port) { /* cppcheck-suppress wrongPrintfScanfArgNum */ len = fprintf(file, "%d.%d.%d.%d:%-5d", NIPQUAD(p_si_stats->connected_ip), ntohs(p_si_stats->connected_port)); } else { len = fprintf(file, "0.0.0.0:*"); } if (len < 0) len = 0; // error if (len < MAX_ADDR_LEN )fprintf(file, "%*s ", MAX_ADDR_LEN-len, ""); // pad and delimiter const char * tcp_state = ""; if (p_si_stats->socket_type == SOCK_STREAM) { tcp_state = tcp_state_str[((enum tcp_state)p_si_stats->tcp_state)]; } fprintf(file, "%-11s %-10lu %d/%s\n", tcp_state, (u_long)p_si_stats->inode, pid, (get_procname(pid, process, sizeof(process)) == 0 ? process : "-")); // max tcp state len is 11 characters = ESTABLISHED }
Process *get_process(pid_t pid) { /* TODO: Add test for invalid pid. Right now, we get a lot of errors and some * structure.*/ Process *retval = (Process *)calloc(1, sizeof(Process)); unsigned int *uids = NULL; unsigned int *gids = NULL; retval->pid = pid; retval->ppid = get_ppid(pid); retval->name = get_procname(pid); retval->exe = get_exe(pid); retval->cmdline = get_cmdline(pid); retval->create_time = get_create_time(pid); uids = get_ids(pid, "Uid:"); if (uids) { retval->uid = uids[0]; retval->euid = uids[1]; retval->suid = uids[2]; retval->username = get_username(retval->uid); /* Uses real uid and not euid */ } else { retval->uid = retval->euid = retval->suid = 0; retval->username = NULL; } gids = get_ids(pid, "Gid:"); if (uids) { retval->gid = gids[0]; retval->egid = gids[1]; retval->sgid = gids[2]; } else { retval->uid = retval->euid = retval->suid = 0; } retval->terminal = get_terminal(pid); free(uids); free(gids); return retval; }
Process * get_process(unsigned pid) { Process *retval = calloc(1, sizeof(Process)); unsigned int *uids = NULL; unsigned int *gids = NULL; retval->pid = pid; retval->ppid = get_ppid(pid); retval->name = get_procname(pid); retval->exe = get_exe(pid); retval->cmdline = get_cmdline(pid); retval->create_time = get_create_time(pid); uids = get_ids(pid, "Uid:"); if (uids) { retval->uid = uids[0]; retval->euid = uids[1]; retval->suid = uids[2]; retval->username = get_username(retval->uid); /* Uses real uid and not euid */ } else { retval->uid = retval->euid = retval->suid = 0; retval->username = NULL; } gids = get_ids(pid, "Gid:"); if (uids) { retval->gid = gids[0]; retval->egid = gids[1]; retval->sgid = gids[2]; } else { retval->uid = retval->euid = retval->suid = 0; } retval->terminal = get_terminal(pid); if (uids) free(uids); if (gids) free(gids); return retval; }