// SPDX-License-Identifier: GPL-3.0-or-later
#include "ebpf.h"
#include "ebpf_socket.h"
#include "ebpf_apps.h"
// ----------------------------------------------------------------------------
// internal flags
// handled in code (automatically set)
static int proc_pid_cmdline_is_needed = 0; // 1 when we need to read /proc/cmdline
/*****************************************************************
*
* FUNCTIONS USED TO READ HASH TABLES
*
*****************************************************************/
/**
* Read statistic hash table.
*
* @param ep the output structure.
* @param fd the file descriptor mapped from kernel ring.
* @param pid the index used to select the data.
* @param bpf_map_lookup_elem a pointer for the function used to read data.
*
* @return It returns 0 when the data was copied and -1 otherwise
*/
int ebpf_read_hash_table(void *ep, int fd, uint32_t pid)
{
if (!ep)
return -1;
if (!bpf_map_lookup_elem(fd, &pid, ep))
return 0;
return -1;
}
/**
* Read socket statistic
*
* Read information from kernel ring to user ring.
*
* @param ep the table with all process stats values.
* @param fd the file descriptor mapped from kernel
* @param ef a pointer for the functions mapped from dynamic library
* @param pids the list of pids associated to a target.
*
* @return
*/
size_t read_bandwidth_statistic_using_pid_on_target(ebpf_bandwidth_t **ep, int fd, struct pid_on_target *pids)
{
size_t count = 0;
while (pids) {
uint32_t current_pid = pids->pid;
if (!ebpf_read_hash_table(ep[current_pid], fd, current_pid))
count++;
pids = pids->next;
}
return count;
}
/**
* Read bandwidth statistic using hash table
*
* @param out the output tensor that will receive the information.
* @param fd the file descriptor that has the data
* @param bpf_map_lookup_elem a pointer for the function to read the data
* @param bpf_map_get_next_key a pointer fo the function to read the index.
*/
size_t read_bandwidth_statistic_using_hash_table(ebpf_bandwidth_t **out, int fd)
{
size_t count = 0;
uint32_t key = 0;
uint32_t next_key = 0;
while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
ebpf_bandwidth_t *eps = out[next_key];
if (!eps) {
eps = callocz(1, sizeof(ebpf_process_stat_t));
out[next_key] = eps;
}
ebpf_read_hash_table(eps, fd, next_key);
}
return count;
}
/*****************************************************************
*
* FUNCTIONS CALLED FROM COLLECTORS
*
*****************************************************************/
/**
* Am I running as Root
*
* Verify the user that is running the collector.
*
* @return It returns 1 for root and 0 otherwise.
*/
int am_i_running_as_root()
{
uid_t uid = getuid(), euid = geteuid();
if (uid == 0 || euid == 0) {
return 1;
}
return 0;
}
/**
* Reset the target values
*
* @param root the pointer to the chain that will be reseted.
*
* @return it returns the number of structures that was reseted.
*/
size_t zero_all_targets(struct target *root)
{
struct target *w;
size_t count = 0;
for (w = root; w; w = w->next) {
count++;
if (unlikely(w->root_pid)) {
struct pid_on_target *pid_on_target = w->root_pid;
while (pid_on_target) {
struct pid_on_target *pid_on_target_to_free = pid_on_target;
pid_on_target = pid_on_target->next;
free(pid_on_target_to_free);
}
w->root_pid = NULL;
}
}
return count;
}
/**