libnftnl  1.0.2
common.c
1 /*
2  * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  */
9 
10 #include <stdlib.h>
11 #include <sys/socket.h>
12 #include <linux/netlink.h>
13 #include <linux/netfilter/nfnetlink.h>
14 
15 #include <libmnl/libmnl.h>
16 #include <libnftnl/common.h>
17 
18 #include "internal.h"
19 
20 struct nlmsghdr *nft_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
21  uint16_t type, uint32_t seq)
22 {
23  struct nlmsghdr *nlh;
24  struct nfgenmsg *nfh;
25 
26  nlh = mnl_nlmsg_put_header(buf);
27  nlh->nlmsg_type = (NFNL_SUBSYS_NFTABLES << 8) | cmd;
28  nlh->nlmsg_flags = NLM_F_REQUEST | type;
29  nlh->nlmsg_seq = seq;
30 
31  nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
32  nfh->nfgen_family = family;
33  nfh->version = NFNETLINK_V0;
34  nfh->res_id = 0;
35 
36  return nlh;
37 }
38 EXPORT_SYMBOL(nft_nlmsg_build_hdr);
39 
40 struct nft_parse_err *nft_parse_err_alloc(void)
41 {
42  return calloc(1, sizeof(struct nft_parse_err));
43 }
44 EXPORT_SYMBOL(nft_parse_err_alloc);
45 
46 void nft_parse_err_free(struct nft_parse_err *err)
47 {
48  xfree(err);
49 }
50 EXPORT_SYMBOL(nft_parse_err_free);
51 
52 int nft_parse_perror(const char *msg, struct nft_parse_err *err)
53 {
54  switch (err->error) {
55  case NFT_PARSE_EBADINPUT:
56  return fprintf(stderr, "%s: Bad input format in line %d column %d\n",
57  msg, err->line, err->column);
58  case NFT_PARSE_EMISSINGNODE:
59  return fprintf(stderr, "%s: Node \"%s\" not found\n",
60  msg, err->node_name);
61  case NFT_PARSE_EBADTYPE:
62  return fprintf(stderr, "%s: Invalid type in node \"%s\"\n",
63  msg, err->node_name);
64  default:
65  return fprintf(stderr, "%s: Undefined error\n", msg);
66  }
67 }
68 EXPORT_SYMBOL(nft_parse_perror);
69 
70 int nft_event_header_snprintf(char *buf, size_t size, uint32_t type,
71  uint32_t flags)
72 {
73  int ret = 0;
74 
75  if (!(flags & NFT_OF_EVENT_ANY))
76  return 0;
77 
78  switch (type) {
79  case NFT_OUTPUT_XML:
80  if (flags & NFT_OF_EVENT_NEW) {
81  ret = snprintf(buf, size, "<event><type>new</type>");
82  } else if (flags & NFT_OF_EVENT_DEL) {
83  ret = snprintf(buf, size,
84  "<event><type>delete</type>");
85  } else {
86  ret = snprintf(buf, size,
87  "<event><type>unknown</type>");
88  }
89  break;
90  case NFT_OUTPUT_JSON:
91  if (flags & NFT_OF_EVENT_NEW) {
92  ret = snprintf(buf, size, "{event:{type:\"new\",{\"");
93  } else if (flags & NFT_OF_EVENT_DEL) {
94  ret = snprintf(buf, size,
95  "{event:{type:\"delete\",{\"");
96  } else {
97  ret = snprintf(buf, size,
98  "{event:{type:\"unknown\",{\"");
99  }
100  break;
101  default:
102  if (flags & NFT_OF_EVENT_NEW) {
103  ret = snprintf(buf, size, "%9s", "[NEW] ");
104  } else if (flags & NFT_OF_EVENT_DEL) {
105  ret = snprintf(buf, size, "%9s", "[DELETE] ");
106  } else {
107  ret = snprintf(buf, size, "%9s", "[unknown] ");
108  }
109  break;
110  }
111  return ret;
112 }
113 
114 int nft_event_header_fprintf(FILE *fp, uint32_t type, uint32_t flags)
115 {
116  char buf[64]; /* enough for the maximum string length above */
117 
118  nft_event_header_snprintf(buf, sizeof(buf), type, flags);
119  buf[sizeof(buf) - 1] = '\0';
120 
121  return fprintf(fp, "%s", buf);
122 }
123 
124 int nft_event_footer_snprintf(char *buf, size_t size, uint32_t type,
125  uint32_t flags)
126 {
127  if (!(flags & NFT_OF_EVENT_ANY))
128  return 0;
129 
130  switch (type) {
131  case NFT_OUTPUT_XML:
132  return snprintf(buf, size, "</event>");
133  case NFT_OUTPUT_JSON:
134  return snprintf(buf, size, "}}}");
135  default:
136  return 0;
137  }
138 }
139 
140 int nft_event_footer_fprintf(FILE *fp, uint32_t type, uint32_t flags)
141 {
142  char buf[32]; /* enough for the maximum string length above */
143 
144  nft_event_footer_snprintf(buf, sizeof(buf), type, flags);
145  buf[sizeof(buf) - 1] = '\0';
146 
147  return fprintf(fp, "%s", buf);
148 }