1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
/* declarations of routines that interface with the kernel's IPsec mechanism
*
* Copyright (C) 2024 Paul Wouters <pwouters@>
* Copyright (C) 2024 Andrew Cagney
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*/
#include <sys/utsname.h> /* for uname() */
#include <stdlib.h>
#include "kernel_info.h"
#include "log.h"
#include "sparse_names.h"
struct kernel_info {
enum kinfo_os os;
unsigned major;
unsigned minor;
unsigned patch;
};
static struct kernel_info kinfo; /* declare at end, so code uses header declaration */
const struct sparse_names kinfo_os_names = {
.list = {
SPARSE("FreeBSD", KINFO_FREEBSD),
SPARSE("NetBSD", KINFO_NETBSD),
SPARSE("OpenBSD", KINFO_OPENBSD),
SPARSE("Linux", KINFO_LINUX),
SPARSE_NULL,
},
};
bool kernel_ge(enum kinfo_os os, unsigned major, unsigned minor, unsigned patch)
{
if (kinfo.os != os)
return false;
if (kinfo.major < major)
return false;
if (kinfo.major == major && kinfo.minor < minor)
return false;
if (kinfo.major == major && kinfo.minor == minor && kinfo.patch < patch)
return false;
return true;
}
void init_kernel_info(struct logger *logger)
{
struct utsname uts;
if (uname(&uts) < 0) {
llog(RC_LOG, logger, "host: unknown");
return;
}
unsigned *ver[] = {
&kinfo.major,
&kinfo.minor,
&kinfo.patch,
};
unsigned i = 0;
char *c = uts.release;
while (*c && i < elemsof(ver)) {
if (char_isdigit(*c)) {
(*ver[i]) = strtoul(c, &c, 10);
i++;
} else {
c++;
}
}
const struct sparse_name *os = sparse_lookup(&kinfo_os_names, shunk1(uts.sysname));
if (os == NULL) {
kinfo.os = KINFO_UNKNOWN;
} else {
kinfo.os = os->value;
}
name_buf osn;
llog(RC_LOG, logger, "operating system: %s %u.%u.%u [%s %s %s %s]",
str_sparse(&kinfo_os_names, kinfo.os, &osn),
kinfo.major, kinfo.minor, kinfo.patch,
uts.sysname, uts.release, uts.version, uts.machine);
}
|