File: kernel_info.c

package info (click to toggle)
libreswan 5.2-2.3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 81,644 kB
  • sloc: ansic: 129,988; sh: 32,018; xml: 20,646; python: 10,303; makefile: 3,022; javascript: 1,506; sed: 574; yacc: 511; perl: 264; awk: 52
file content (95 lines) | stat: -rw-r--r-- 2,393 bytes parent folder | download | duplicates (2)
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);
}