• Main Page
  • Modules
  • Files
  • File List

libnetfilter_acct.c

00001 /*
00002  * (C) 2011 by Pablo Neira Ayuso <pablo@netfilter.org>
00003  * (C) 2011 by Intra2net AG <http://www.intra2net.com>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the Lesser GNU General Public License as published
00007  * by the Free Software Foundation; either version 2.1 of the License, or
00008  * (at your option) any later version.
00009  */
00010 #include "internal.h"
00011 
00012 #include <time.h>
00013 #include <endian.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 
00017 #include <libmnl/libmnl.h>
00018 #include <linux/netfilter/nfnetlink.h>
00019 #include <linux/netfilter/nfnetlink_acct.h>
00020 
00021 #include <libnetfilter_acct/libnetfilter_acct.h>
00022 
00058 struct nfacct {
00059         char            name[NFACCT_NAME_MAX];
00060         uint64_t        pkts;
00061         uint64_t        bytes;
00062         uint32_t        bitset;
00063 };
00064 
00076 struct nfacct *nfacct_alloc(void)
00077 {
00078         return calloc(1, sizeof(struct nfacct));
00079 }
00080 EXPORT_SYMBOL(nfacct_alloc);
00081 
00086 void nfacct_free(struct nfacct *nfacct)
00087 {
00088         free(nfacct);
00089 }
00090 EXPORT_SYMBOL(nfacct_free);
00091 
00098 void
00099 nfacct_attr_set(struct nfacct *nfacct, enum nfacct_attr_type type,
00100                 const void *data)
00101 {
00102         switch(type) {
00103         case NFACCT_ATTR_NAME:
00104                 strncpy(nfacct->name, data, NFACCT_NAME_MAX);
00105                 nfacct->name[NFACCT_NAME_MAX-1] = '\0';
00106                 nfacct->bitset |= (1 << NFACCT_ATTR_NAME);
00107                 break;
00108         case NFACCT_ATTR_PKTS:
00109                 nfacct->bytes = *((uint64_t *) data);
00110                 nfacct->bitset |= (1 << NFACCT_ATTR_PKTS);
00111                 break;
00112         case NFACCT_ATTR_BYTES:
00113                 nfacct->pkts = *((uint64_t *) data);
00114                 nfacct->bitset |= (1 << NFACCT_ATTR_BYTES);
00115                 break;
00116         }
00117 }
00118 EXPORT_SYMBOL(nfacct_attr_set);
00119 
00126 void
00127 nfacct_attr_set_str(struct nfacct *nfacct, enum nfacct_attr_type type,
00128                     const char *name)
00129 {
00130         nfacct_attr_set(nfacct, type, name);
00131 }
00132 EXPORT_SYMBOL(nfacct_attr_set_str);
00133 
00140 void
00141 nfacct_attr_set_u64(struct nfacct *nfacct, enum nfacct_attr_type type,
00142                     uint64_t value)
00143 {
00144         nfacct_attr_set(nfacct, type, &value);
00145 }
00146 EXPORT_SYMBOL(nfacct_attr_set_u64);
00147 
00153 void
00154 nfacct_attr_unset(struct nfacct *nfacct, enum nfacct_attr_type type)
00155 {
00156         switch(type) {
00157         case NFACCT_ATTR_NAME:
00158                 nfacct->bitset &= ~(1 << NFACCT_ATTR_NAME);
00159                 break;
00160         case NFACCT_ATTR_PKTS:
00161                 nfacct->bitset &= ~(1 << NFACCT_ATTR_PKTS);
00162                 break;
00163         case NFACCT_ATTR_BYTES:
00164                 nfacct->bitset &= ~(1 << NFACCT_ATTR_BYTES);
00165                 break;
00166         }
00167 }
00168 EXPORT_SYMBOL(nfacct_attr_unset);
00169 
00178 const void *nfacct_attr_get(struct nfacct *nfacct, enum nfacct_attr_type type)
00179 {
00180         const void *ret = NULL;
00181 
00182         switch(type) {
00183         case NFACCT_ATTR_NAME:
00184                 if (nfacct->bitset & (1 << NFACCT_ATTR_NAME))
00185                         ret = nfacct->name;
00186                 break;
00187         case NFACCT_ATTR_PKTS:
00188                 if (nfacct->bitset & (1 << NFACCT_ATTR_PKTS))
00189                         ret = &nfacct->pkts;
00190                 break;
00191         case NFACCT_ATTR_BYTES:
00192                 if (nfacct->bitset & (1 << NFACCT_ATTR_BYTES))
00193                         ret = &nfacct->bytes;
00194                 break;
00195         }
00196         return ret;
00197 }
00198 EXPORT_SYMBOL(nfacct_attr_get);
00199 
00208 const char *
00209 nfacct_attr_get_str(struct nfacct *nfacct, enum nfacct_attr_type type)
00210 {
00211         return (char *)nfacct_attr_get(nfacct, type);
00212 }
00213 EXPORT_SYMBOL(nfacct_attr_get_str);
00214 
00223 uint64_t nfacct_attr_get_u64(struct nfacct *nfacct, enum nfacct_attr_type type)
00224 {
00225         const void *ret = nfacct_attr_get(nfacct, type);
00226         return ret ? *((uint64_t *)ret) : 0;
00227 }
00228 EXPORT_SYMBOL(nfacct_attr_get_u64);
00229 
00241 int nfacct_snprintf(char *buf, size_t size, struct nfacct *nfacct,
00242                     uint16_t type, uint16_t flags)
00243 {
00244         int ret = 0;
00245 
00246         switch(type) {
00247         case NFACCT_SNPRINTF_T_PLAIN:
00248                 if (flags & NFACCT_SNPRINTF_F_FULL) {
00249                         ret = snprintf(buf, size,
00250                                 "{ pkts = %.20llu, bytes = %.20llu } = %s;",
00251                                 (unsigned long long)
00252                                 nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES),
00253                                 (unsigned long long)
00254                                 nfacct_attr_get_u64(nfacct, NFACCT_ATTR_PKTS),
00255                                 nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME));
00256                 } else {
00257                         ret = snprintf(buf, size, "%s\n",
00258                                 nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME));
00259                 }
00260                 break;
00261         case NFACCT_SNPRINTF_T_XML:
00262                 ret = snprintf(buf, size,
00263                                 "<obj><name>%s</name>"
00264                                 "<pkts>%.20llu</pkts>"
00265                                 "<bytes>%.20llu</bytes></obj>",
00266                                 nfacct_attr_get_str(nfacct, NFACCT_ATTR_NAME),
00267                                 (unsigned long long)
00268                                 nfacct_attr_get_u64(nfacct, NFACCT_ATTR_BYTES),
00269                                 (unsigned long long)
00270                                 nfacct_attr_get_u64(nfacct, NFACCT_ATTR_PKTS));
00271                 break;
00272         default:
00273                 ret = -1;
00274                 break;
00275         }
00276         return ret;
00277 }
00278 EXPORT_SYMBOL(nfacct_snprintf);
00279 
00317 struct nlmsghdr *
00318 nfacct_nlmsg_build_hdr(char *buf, uint8_t cmd, uint16_t flags, uint32_t seq)
00319 {
00320         struct nlmsghdr *nlh;
00321         struct nfgenmsg *nfh;
00322 
00323         nlh = mnl_nlmsg_put_header(buf);
00324         nlh->nlmsg_type = (NFNL_SUBSYS_ACCT << 8) | cmd;
00325         nlh->nlmsg_flags = NLM_F_REQUEST | flags;
00326         nlh->nlmsg_seq = seq;
00327 
00328         nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
00329         nfh->nfgen_family = AF_UNSPEC;
00330         nfh->version = NFNETLINK_V0;
00331         nfh->res_id = 0;
00332 
00333         return nlh;
00334 }
00335 EXPORT_SYMBOL(nfacct_nlmsg_build_hdr);
00336 
00342 void nfacct_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfacct *nfacct)
00343 {
00344         if (nfacct->bitset & (1 << NFACCT_ATTR_NAME))
00345                 mnl_attr_put_strz(nlh, NFACCT_NAME, nfacct->name);
00346 
00347         if (nfacct->bitset & (1 << NFACCT_ATTR_PKTS))
00348                 mnl_attr_put_u64(nlh, NFACCT_PKTS, htobe64(nfacct->pkts));
00349 
00350         if (nfacct->bitset & (1 << NFACCT_ATTR_BYTES))
00351                 mnl_attr_put_u64(nlh, NFACCT_PKTS, htobe64(nfacct->bytes));
00352 }
00353 EXPORT_SYMBOL(nfacct_nlmsg_build_payload);
00354 
00355 static int nfacct_nlmsg_parse_attr_cb(const struct nlattr *attr, void *data)
00356 {
00357         const struct nlattr **tb = data;
00358         int type = mnl_attr_get_type(attr);
00359 
00360         if (mnl_attr_type_valid(attr, NFACCT_MAX) < 0)
00361                 return MNL_CB_OK;
00362 
00363         switch(type) {
00364         case NFACCT_NAME:
00365                 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
00366                         perror("mnl_attr_validate");
00367                         return MNL_CB_ERROR;
00368                 }
00369                 break;
00370         case NFACCT_PKTS:
00371                 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
00372                         perror("mnl_attr_validate");
00373                         return MNL_CB_ERROR;
00374                 }
00375                 break;
00376         case NFACCT_BYTES:
00377                 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
00378                         perror("mnl_attr_validate");
00379                         return MNL_CB_ERROR;
00380                 }
00381                 break;
00382         }
00383         tb[type] = attr;
00384         return MNL_CB_OK;
00385 }
00386 
00395 int
00396 nfacct_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfacct *nfacct)
00397 {
00398         struct nlattr *tb[NFACCT_MAX+1] = {};
00399         struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
00400 
00401         mnl_attr_parse(nlh, sizeof(*nfg), nfacct_nlmsg_parse_attr_cb, tb);
00402         if (!tb[NFACCT_NAME] && !tb[NFACCT_PKTS] && !tb[NFACCT_BYTES])
00403                 return -1;
00404 
00405         nfacct_attr_set_str(nfacct, NFACCT_ATTR_NAME,
00406                             mnl_attr_get_str(tb[NFACCT_NAME]));
00407         nfacct_attr_set_u64(nfacct, NFACCT_ATTR_PKTS,
00408                             be64toh(mnl_attr_get_u64(tb[NFACCT_PKTS])));
00409         nfacct_attr_set_u64(nfacct, NFACCT_ATTR_BYTES,
00410                             be64toh(mnl_attr_get_u64(tb[NFACCT_BYTES])));
00411 
00412         return 0;
00413 }
00414 EXPORT_SYMBOL(nfacct_nlmsg_parse_payload);
00415 

Generated on Tue Mar 27 2012 12:36:24 for libnetfilter_acct by  doxygen 1.7.1