aboutsummaryrefslogtreecommitdiffstats
path: root/test/packetdrill/capability.h
diff options
context:
space:
mode:
authorJianfeng Tan <henry.tjf@antfin.com>2019-11-18 06:59:50 +0000
committerJianfeng Tan <henry.tjf@antfin.com>2020-03-05 01:31:33 +0800
commit78c896b3b3127515478090c19447e27dc406427e (patch)
treed6d67d4683e9ca0409f9984a834547a572fb5310 /test/packetdrill/capability.h
parente4380f4866091fd92a7a57667dd938a99144f9cd (diff)
Signed-off-by: Jianfeng Tan <henry.tjf@antfin.com> Signed-off-by: Jielong Zhou <jielong.zjl@antfin.com> Signed-off-by: Jian Zhang <wuzai.zj@antfin.com> Signed-off-by: Chen Zhao <winters.zc@antfin.com> Change-Id: I55c39de4c6cd30f991f35631eb507f770230f08e
Diffstat (limited to 'test/packetdrill/capability.h')
-rw-r--r--test/packetdrill/capability.h102
1 files changed, 102 insertions, 0 deletions
diff --git a/test/packetdrill/capability.h b/test/packetdrill/capability.h
new file mode 100644
index 0000000..7ec5ee2
--- /dev/null
+++ b/test/packetdrill/capability.h
@@ -0,0 +1,102 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Author: willemb@google.com (Will de Bruijn)
+//
+// POSIX capability support for Linux: simplified libcap
+// GPL applies, as this interface was inspired by sys/capability.h
+
+#ifndef _LINUX_GTESTS_NET_CAPABILITY_H
+#define _LINUX_GTESTS_NET_CAPABILITY_H
+
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#else
+#include <linux/capability.h>
+
+typedef struct __user_cap_data_struct *cap_t;
+typedef int cap_value_t;
+
+typedef enum {
+ CAP_EFFECTIVE=0,
+ CAP_PERMITTED=1,
+ CAP_INHERITABLE=2
+} cap_flag_t;
+
+typedef enum {
+ CAP_CLEAR=0,
+ CAP_SET=1
+} cap_flag_value_t;
+
+static struct __user_cap_header_struct header = {
+ .version = _LINUX_CAPABILITY_VERSION_3,
+ .pid = 0,
+};
+
+// System calls: implemented in libc
+int capset(cap_user_header_t header, cap_user_data_t data);
+int capget(cap_user_header_t header, const cap_user_data_t data);
+
+// Extract a value for one name in one of the capability lists
+// only supports flag CAP_EFFECTIVE
+static inline int
+cap_get_flag(cap_t cap, cap_value_t name, cap_flag_t flag, cap_flag_value_t *val)
+{
+ assert(flag == CAP_EFFECTIVE);
+ assert(name < (sizeof(cap->effective) * 8));
+ *val = (cap->effective & (1 << name)) ? CAP_SET : CAP_CLEAR;
+ return 0;
+}
+
+// Set the value for a number of names in one of the capability lists
+// only supports flag CAP_EFFECTIVE
+static inline int
+cap_set_flag(cap_t cap, cap_flag_t flag, int num_name,
+ const cap_value_t *names, cap_flag_value_t val)
+{
+ int i;
+
+ assert(flag == CAP_EFFECTIVE);
+ if (val == CAP_SET)
+ for (i = 0; i < num_name; i++)
+ cap->effective |= (1 << names[i]);
+ else
+ for (i = 0; i < num_name; i++)
+ cap->effective &= ~(1 << names[i]);
+
+ return 0;
+}
+
+// Get the capability lists from the kernel
+static inline cap_t
+cap_get_proc(void)
+{
+ cap_t capabilities = calloc(_LINUX_CAPABILITY_U32S_3,
+ sizeof(struct __user_cap_data_struct));
+ if (capget(&header, capabilities)) {
+ perror("capget");
+ return NULL;
+ }
+
+ return capabilities;
+}
+
+// Update the capability lists in the kernel
+static inline int
+cap_set_proc(cap_t capabilities)
+{
+ if (capset(&header, capabilities)) {
+ perror("capset");
+ return -1;
+ }
+ return 0;
+}
+
+// Free a capability list
+static inline int
+cap_free(void *capabilities)
+{
+ free(capabilities);
+ return 0;
+}
+
+#endif /* !HAVE_SYS_CAPABILITY_H */
+#endif /* _LINUX_GTESTS_NET_CAPABILITY_H */