nftables/src/owner.c
Pablo Neira Ayuso 77fd4fa282 src: Add GPLv2+ header to .c files of recent creation
This patch comes after a proposal of mine at NFWS 2022 that resulted in
agreement to license recent .c files under GPLv2+ by the attendees at this
meeting:

- Stefano Brivio
- Fernando F. Mancera
- Phil Sutter
- Jozsef Kadlecsik
- Florian Westphal
- Laura Garcia
- Arturo Borrero
- Pablo Neira

It has already happened that one of the external library dependencies
was moved to GPLv3+ (libreadline), resulting in a change to libedit by
default in b4dded0ca78d ("configure: default to libedit for cli").

I have added the GPLv2+ header to the following files:

                        Authors
                        -------
src/cmd.c               Pablo
src/fib.c               Florian
src/hash.c              Pablo
src/iface.c             Pablo
src/json.c              Phil + fixes from occasional contributors
src/libnftables.c       Eric Leblond and Phil
src/mergesort.c         Elise Lenion
src/misspell.c          Pablo
src/mnl.c               Pablo + fixes from occasional contributors
src/monitor.c           Arturo
src/numgen.c            Pablo
src/osf.c               Fernando
src/owner.c             Pablo
src/parser_json.c       Phil + fixes from occasional contributors
src/print.c             Phil
src/xfrm.c              Florian
src/xt.c                Pablo

Eric Leblond and Elise Lennion did not attend NFWS 2022, but they
acknowledged this license update already in the past when I proposed
this to them in private emails.

Update COPYING file too to refer that we are now moving towards GPLv2 or
any later.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2023-01-02 15:25:28 +01:00

182 lines
3.3 KiB
C

/*
* Copyright (c) 2021 Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 (or any
* later) as published by the Free Software Foundation.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <inttypes.h>
#include <dirent.h>
#include <netlink.h>
#include <owner.h>
static char *pid2name(pid_t pid)
{
char procname[256], *prog;
FILE *fp;
int ret;
ret = snprintf(procname, sizeof(procname), "/proc/%lu/stat", (unsigned long)pid);
if (ret < 0 || ret > (int)sizeof(procname))
return NULL;
fp = fopen(procname, "r");
if (!fp)
return NULL;
ret = fscanf(fp, "%*u (%m[^)]", &prog);
fclose(fp);
if (ret == 1)
return prog;
return NULL;
}
static char *portid2name(pid_t pid, uint32_t portid, unsigned long inode)
{
const struct dirent *ent;
char procname[256];
DIR *dir;
int ret;
ret = snprintf(procname, sizeof(procname), "/proc/%lu/fd/", (unsigned long)pid);
if (ret < 0 || ret >= (int)sizeof(procname))
return NULL;
dir = opendir(procname);
if (!dir)
return NULL;
for (;;) {
unsigned long ino;
char tmp[128];
ssize_t rl;
ent = readdir(dir);
if (!ent)
break;
if (ent->d_type != DT_LNK)
continue;
ret = snprintf(procname, sizeof(procname), "/proc/%d/fd/%s",
pid, ent->d_name);
if (ret < 0 || ret >= (int)sizeof(procname))
continue;
rl = readlink(procname, tmp, sizeof(tmp));
if (rl <= 0 || rl >= (ssize_t)sizeof(tmp))
continue;
tmp[rl] = 0;
ret = sscanf(tmp, "socket:[%lu]", &ino);
if (ret == 1 && ino == inode) {
closedir(dir);
return pid2name(pid);
}
}
closedir(dir);
return NULL;
}
static char *name_by_portid(uint32_t portid, unsigned long inode)
{
const struct dirent *ent;
char *prog;
DIR *dir;
/* Many netlink users use their process ID to allocate the first port id. */
prog = portid2name(portid, portid, inode);
if (prog)
return prog;
/* no luck, search harder. */
dir = opendir("/proc");
if (!dir)
return NULL;
for (;;) {
unsigned long pid;
char *end;
ent = readdir(dir);
if (!ent)
break;
if (ent->d_type != DT_DIR)
continue;
pid = strtoul(ent->d_name, &end, 10);
if (pid <= 1 || *end)
continue;
if (pid == portid) /* already tried */
continue;
prog = portid2name(pid, portid, inode);
if (prog)
break;
}
closedir(dir);
return prog;
}
char *get_progname(uint32_t portid)
{
FILE *fp = fopen("/proc/net/netlink", "r");
uint32_t portid_check;
unsigned long inode;
int ret, prot;
if (!fp)
return NULL;
for (;;) {
char line[256];
if (!fgets(line, sizeof(line), fp))
break;
ret = sscanf(line, "%*x %d %u %*x %*d %*d %*x %*d %*u %lu\n",
&prot, &portid_check, &inode);
if (ret == EOF)
break;
if (ret == 3 && portid_check == portid && prot == NETLINK_NETFILTER) {
static uint32_t last_portid;
static uint32_t last_inode;
static char *last_program;
char *prog;
fclose(fp);
if (last_portid == portid && last_inode == inode)
return last_program;
prog = name_by_portid(portid, inode);
free(last_program);
last_program = prog;
last_portid = portid;
last_inode = inode;
return prog;
}
}
fclose(fp);
return NULL;
}