libnftnl  1.2.9
utils.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
4  * (C) 2013 by Arturo Borrero Gonzalez <arturo@debian.org>
5  */
6 
7 #include <internal.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <limits.h>
11 #include <stdint.h>
12 #include <arpa/inet.h>
13 #include <errno.h>
14 #include <inttypes.h>
15 
16 #include <libnftnl/common.h>
17 
18 #include <linux/netfilter.h>
19 #include <linux/netfilter/nf_tables.h>
20 
21 static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
22  [NFPROTO_INET] = "inet",
23  [NFPROTO_IPV4] = "ip",
24  [NFPROTO_ARP] = "arp",
25  [NFPROTO_NETDEV] = "netdev",
26  [NFPROTO_BRIDGE] = "bridge",
27  [NFPROTO_IPV6] = "ip6",
28 };
29 
30 const char *nftnl_family2str(uint32_t family)
31 {
32  if (family >= NFPROTO_NUMPROTO || !nftnl_family_str[family])
33  return "unknown";
34 
35  return nftnl_family_str[family];
36 }
37 
38 const char *nftnl_verdict2str(uint32_t verdict)
39 {
40  switch (verdict) {
41  case NF_ACCEPT:
42  return "accept";
43  case NF_DROP:
44  return "drop";
45  case NF_STOLEN:
46  return "stolen";
47  case NF_QUEUE:
48  return "queue";
49  case NF_REPEAT:
50  return "repeat";
51  case NF_STOP:
52  return "stop";
53  case NFT_RETURN:
54  return "return";
55  case NFT_JUMP:
56  return "jump";
57  case NFT_GOTO:
58  return "goto";
59  case NFT_CONTINUE:
60  return "continue";
61  case NFT_BREAK:
62  return "break";
63  default:
64  return "unknown";
65  }
66 }
67 
68 enum nftnl_cmd_type nftnl_flag2cmd(uint32_t flags)
69 {
70  if (flags & NFTNL_OF_EVENT_NEW)
71  return NFTNL_CMD_ADD;
72  else if (flags & NFTNL_OF_EVENT_DEL)
73  return NFTNL_CMD_DELETE;
74 
75  return NFTNL_CMD_UNSPEC;
76 }
77 
78 int nftnl_fprintf(FILE *fp, const void *obj, uint32_t cmd, uint32_t type,
79  uint32_t flags,
80  int (*snprintf_cb)(char *buf, size_t bufsiz, const void *obj,
81  uint32_t cmd, uint32_t type,
82  uint32_t flags))
83 {
84  char _buf[NFTNL_SNPRINTF_BUFSIZ];
85  char *buf = _buf;
86  size_t bufsiz = sizeof(_buf);
87  int ret;
88 
89  ret = snprintf_cb(buf, bufsiz, obj, cmd, type, flags);
90  if (ret <= 0)
91  goto out;
92 
93  if (ret >= NFTNL_SNPRINTF_BUFSIZ) {
94  bufsiz = ret + 1;
95 
96  buf = malloc(bufsiz);
97  if (buf == NULL)
98  return -1;
99 
100  ret = snprintf_cb(buf, bufsiz, obj, cmd, type, flags);
101  if (ret <= 0)
102  goto out;
103  }
104 
105  ret = fprintf(fp, "%s", buf);
106 
107 out:
108  if (buf != _buf)
109  xfree(buf);
110 
111  return ret;
112 }
113 
114 void __nftnl_assert_attr_exists(uint16_t attr, uint16_t attr_max,
115  const char *filename, int line)
116 {
117  fprintf(stderr, "libnftnl: attribute %d > %d (maximum) assertion failed in %s:%d\n",
118  attr, attr_max, filename, line);
119  exit(EXIT_FAILURE);
120 }
121 
122 void __nftnl_assert_fail(uint16_t attr, const char *filename, int line)
123 {
124  fprintf(stderr, "libnftnl: attribute %d assertion failed in %s:%d\n",
125  attr, filename, line);
126  exit(EXIT_FAILURE);
127 }
128 
129 void __noreturn __abi_breakage(const char *file, int line, const char *reason)
130 {
131  fprintf(stderr, "nf_tables kernel ABI is broken, contact your vendor.\n"
132  "%s:%d reason: %s\n", file, line, reason);
133  exit(EXIT_FAILURE);
134 }
135 
136 int nftnl_set_str_attr(const char **dptr, uint32_t *flags,
137  uint16_t attr, const void *data, uint32_t data_len)
138 {
139  if (*flags & (1 << attr))
140  xfree(*dptr);
141 
142  *dptr = strndup(data, data_len);
143  if (!*dptr)
144  return -1;
145 
146  *flags |= (1 << attr);
147  return 0;
148 }