[-]
[+]
|
Changed |
pmacct.changes
|
|
[-]
[+]
|
Changed |
pmacct.spec
^
|
|
[-]
[+]
|
Deleted |
pmacct-0.12.3-bgp.patch
^
|
@@ -1,19 +0,0 @@
---- src/bgp/bgp.c.orig 2010-07-31 13:22:02.117866605 +0200
-+++ src/bgp/bgp.c 2010-07-31 13:23:52.751094500 +0200
-@@ -57,6 +57,7 @@
- struct bgp_open *bopen;
- char bgp_packet[BGP_MAX_PACKET_SIZE], *bgp_packet_ptr;
- char bgp_reply_pkt[BGP_MAX_PACKET_SIZE], *bgp_reply_pkt_ptr;
-+ char *str_buf;
- #if defined ENABLE_IPV6
- struct sockaddr_storage server, client;
- struct ipv6_mreq multi_req6;
-@@ -309,7 +310,7 @@
- }
- else {
- if (peer->buf.len > BGP_MAX_PACKET_SIZE) {
-- realloc(peer->buf.base, BGP_MAX_PACKET_SIZE);
-+ str_buf = realloc(peer->buf.base, BGP_MAX_PACKET_SIZE);
- memset(peer->buf.base, 0, BGP_MAX_PACKET_SIZE);
- peer->buf.len = BGP_MAX_PACKET_SIZE;
- }
|
[-]
[+]
|
Deleted |
pmacct-0.14.0.tar.bz2/EXAMPLES
^
|
@@ -1,985 +0,0 @@
-pmacct (Promiscuous mode IP Accounting package)
-pmacct is Copyright (C) 2003-2011 by Paolo Lucente
-
-TABLE OF CONTENTS:
-I. Plugins included with pmacct distribution
-II. Configuring pmacct for compilation
-III. Brief SQL (MySQL, PostgreSQL, SQLite 3.x) setup examples
-IV. Running the libpcap-based daemon (pmacctd)
-V. Running the NetFlow and sFlow daemons (nfacctd/sfacctd)
-VI. Running the ULOG-based daemon (uacctd)
-VII. Running the pmacct client (pmacct)
-VIII. Running the logfile players (pmmyplay/pmpgplay)
-IX. Quickstart guide to packet/stream classifiers
-X. Quickstart guide to setup a NetFlow agent/probe
-XI. Quickstart guide to setup a sFlow agent/probe
-XII. Quickstart guide to setup the BGP daemon
-XIII. Quickstart guide to setup a NetFlow/sFlow replicator
-XIV. Quickstart guide to setup the IS-IS daemon
-XV. Running the print plugin to write to flat-files
-
-
-I. Plugins included with pmacct distribution
-Given its open and pluggable architecture, pmacct is easily extensible by writing new
-plugins. Here is a list of plugins included within the official pmacct distribution.
-
-'memory': data are stored in a memory table and can be fetched via the pmacct client
- tool, 'pmacct'. It also allows easily data injection into 3rd party tools
- like GNUplot, MRTG, RRDtool or a Net-SNMP server
-'mysql': a working MySQL installation can be used for data storage
-'pgsql': a working PostgreSQL installation can be used for data storage
-'sqlite3': a working SQLite 3.x or BerkeleyDB 5.x (compiled in with the SQLite API)
- installation can be used for data storage
-'print': data are printed at regular intervals to flat-files or standard output
-
-
-II. Configuring pmacct for compilation
-The simplest way to configure the package for compilation is to let the configure
-script to probe default headers and libraries for you. By default SQL plugins are
-not enabled; much like multi-threading (pre-requisite for compiling the BGP daemon
-code), IPv6 support and 64 bits counters. A few examples will follow; as usual to
-get the list of available switches, you can use the following command-line:
-
-shell> ./configure --help
-
-Examples on how to enable the support for (1) MySQL, (2) PostgreSQL, (3) SQLite and
-any (4) mixed compilation:
-
-(1) shell> ./configure --enable-mysql
-(2) shell> ./configure --enable-pgsql
-(3) shell> ./configure --enable-sqlite3
-(4) shell> ./configure --enable-mysql --enable-pgsql
-
-
-III. Brief SQL setup examples
-Scripts for setting up databases (MySQL, PostgreSQL and SQLite) are into the 'sql/'
-tree. For further guidance read the relevant README files in such directory. One of
-the crucial concepts to deal with, when using default IP or BGP SQL tables, is table
-versioning: please read more about it in the FAQS document (Q16).
-
-IIIa. MySQL examples
-shell> cd sql/
-
-- To create v1 tables:
-shell> mysql -u root -p < pmacct-create-db_v1.mysql
-shell> mysql -u root -p < pmacct-grant-db.mysql
-
-Data will be available in 'acct' table of 'pmacct' DB.
-
-- To create v2 tables:
-shell> mysql -u root -p < pmacct-create-db_v2.mysql
-shell> mysql -u root -p < pmacct-grant-db.mysql
-
-Data will be available in 'acct_v2' table of 'pmacct' DB.
-
-... And so on for the newer versions.
-
-IIIb. PostgreSQL examples
-Which user has to execute the following two scripts and how to autenticate with the
-PostgreSQL server depends upon your current configuration. Keep in mind that both
-scripts need postgres superuser permissions to execute some commands successfully:
-shell> cp -p *.pgsql /tmp
-shell> su - postgres
-
-To create v1 tables:
-shell> psql -d template1 -f /tmp/pmacct-create-db.pgsql
-shell> psql -d pmacct -f /tmp/pmacct-create-table_v1.pgsql
-
-To create v2 tables:
-shell> psql -d template1 -f /tmp/pmacct-create-db.pgsql
-shell> psql -d pmacct -f /tmp/pmacct-create-table_v2.pgsql
-
-... And so on for the newer versions.
-
-A few tables will be created into 'pmacct' DB. 'acct' ('acct_v2' or 'acct_v3') table is
-the default table where data will be written when in 'typed' mode (see 'sql_data' option
-in CONFIG-KEYS document; default value is 'typed'); 'acct_uni' ('acct_uni_v2' or
-'acct_uni_v3') is the default table where data will be written when in 'unified' mode.
-
-Since v6, PostgreSQL tables are greatly simplified: unified mode is no longer supported
-and an unique table ('acct_v6', for example) is created instead.
-
-IIIc. SQLite examples
-shell> cd sql/
-
-- To create v1 tables:
-shell> sqlite3 /tmp/pmacct.db < pmacct-create-table.sqlite3
-
-Data will be available in 'acct' table of '/tmp/pmacct.db' DB. Of course, you can change
-the database filename basing on your preferences.
-
-- To create v2 tables:
-shell> sqlite3 /tmp/pmacct.db < pmacct-create-table_v2.sqlite3
-
-Data will be available in 'acct_v2' table of '/tmp/pmacct.db' DB.
-
-... And so on for the newer versions.
-
-IIId. Custom SQL tables
-Custom SQL tables can be built by creating your own SQL schema and indexes. This allows
-to freely mix-and-match the primitives relevant to your accounting scenario. Specifying
-SQL table version and type (sql_table_version, sql_table_type) is not required; whereas
-a new directive, sql_optimize_clauses, is introduced to flag table customization to
-pmacct. This is a simple configuration snippet:
-
-sql_optimize_clauses: true
-sql_table: <table name>
-aggregate: <aggregation primitives list>
-
-IIIe. Historical accounting
-Enabling historical accounting allows to aggregate data over time (ie. 5 mins, hourly,
-daily) in a flexible and fully configurable way. Timestamps are lodged into two fields:
-'stamp_inserted' which represents the basetime of the timeslot and 'stamp_updated' which
-says when a given timeslot was updated for the last time. Following there is a pretty
-standard configuration fragment to slice data into nicely aligned (or rounded-off) 5
-minutes timeslots:
-
-sql_history: 5m
-sql_history_roundoff: m
-
-IIIf. INSERTs-only
-UPDATE queries are demanding in terms of resources; this is why, even if they are
-supported by pmacct, a savy approach is to cache data for longer times in memory and
-write them off once per timeslot (sql_history): this produces a much lighter INSERTs-
-only environemnt. This is an example based on 5 minutes timeslots:
-
-sql_refresh_time: 300
-sql_history: 5m
-sql_history_roundoff: m
-sql_dont_try_update: true
-
-Note that sql_refresh_time is always expressed in seconds.
-
-
-IV. Running the libpcap-based daemon (pmacctd)
-pmacctd, like the other daemons, can be run with commandline options, using a config
-file or a mix of the two. Sample configuration files are in examples/ tree. Note also
-that most of the new features are available only as configuration directives. To be
-aware of the existing configuration directives, please read the CONFIG-KEYS document.
-
-Show all available pmacctd commandline switches:
-shell> pmacctd -h
-
-Run pmacctd reading configuration from a specified file (see examples/ tree for a brief
-list of some commonly useed keys; divert your eyes to CONFIG-KEYS for the full list).
-This example applies to all daemons:
-shell> pmacctd -f pmacctd.conf
-
-Daemonize the process; listen on eth0; aggregate data by src_host/dst_host; write to a
-MySQL server; limit traffic matching only source ip network 10.0.0.0/16; note that
-filters work the same as tcpdump. So, refer to libpcap/tcpdump man pages for examples
-and further reading.
-
-shell> pmacctd -D -c src_host,dst_host -i eth0 -P mysql src net 10.0.0.0/16
-
-Or written the configuration way:
-!
-daemonize: true
-plugins: mysql
-aggregate: src_host, dst_host
-interface: eth0
-pcap_filter: src net 10.0.0.0/16
-! ...
-
-Print collected traffic data aggregated by src_host/dst_host over the screen; refresh
-data every 30 seconds and listen on eth0.
-
-shell> pmacctd -P print -r 30 -i eth0 -c src_host,dst_host
-
-Or written the configuration way:
-!
-plugins: print
-print_refresh_time: 30
-aggregate: src_host, dst_host
-interface: eth0
-! ...
-
-Daemonize the process; let pmacct aggregate traffic in order to show in vs out traffic
-for network 192.168.0.0/16; send data to a PostgreSQL server. This configuration is not
-possible via commandline switches; the corresponding configuration follows:
-
-!
-daemonize: true
-plugins: pgsql[in], pgsql[out]
-aggregate[in]: dst_host
-aggregate[out]: src_host
-aggregate_filter[in]: dst net 192.168.0.0/16
-aggregate_filter[out]: src net 192.168.0.0/16
-sql_table[in]: acct_in
-sql_table[out]: acct_out
-! ...
-
-The previous example looks nice! But how to make data historical ? Simple enough, let's
-suppose you want to split traffic by hour and write data into the DB every 60 seconds.
-
-!
-daemonize: true
-plugins: pgsql[in], pgsql[out]
-aggregate[in]: dst_host
-aggregate[out]: src_host
-aggregate_filter[in]: dst net 192.168.0.0/16
-aggregate_filter[out]: src net 192.168.0.0/16
-sql_table[in]: acct_in
-sql_table[out]: acct_out
-sql_refresh_time: 60
-sql_history: 1h
-sql_history_roundoff: h
-! ...
-
-Let's now translate the same example in the memory plugin world. It's use is valuable
-expecially when it's required to feed bytes/packets/flows counters to external programs.
-Examples about the client program will follow later in this document. Now, note that
-each memory table need its own pipe file in order to get correctly contacted by the
-client:
-
-!
-daemonize: true
-plugins: memory[in], memory[out]
-aggregate[in]: dst_host
-aggregate[out]: src_host
-aggregate_filter[in]: dst net 192.168.0.0/16
-aggregate_filter[out]: src net 192.168.0.0/16
-imt_path[in]: /tmp/pmacct_in.pipe
-imt_path[out]: /tmp/pmacct_out.pipe
-! ...
-
-As a further note, check the CONFIG-KEYS document about more imt_* directives as they
-will support in the task of fine tuning the size and boundaries of memory tables, if
-default values are not ok for your setup.
-
-Now, fire multiple instances of pmacctd, each on a different interface; again, because
-each instance will have its own memory table, it will require its own pipe file for
-client queries aswell (as explained in the previous examples):
-shell> pmacctd -D -i eth0 -m 8 -s 65535 -p /tmp/pipe.eth0
-shell> pmacctd -D -i ppp0 -m 0 -s 32768 -p /tmp/pipe.ppp0
-
-Run pmacctd logging what happens to syslog and using "local2" facility:
-shell> pmacctd -c src_host,dst_host -S local2
-
-NOTE: superuser privileges are needed to execute pmacctd correctly.
-
-
-V. Running the NetFlow and sFlow daemons (nfacctd/sfacctd)
-All examples about pmacctd are also valid for nfacctd and sfacctd with the exception
-of directives that apply exclusively to libpcap. If you've skipped examples in section
-'IV', please read them before continuing. All configuration keys available are in the
-CONFIG-KEYS document. Some examples:
-
-Run nfacctd reading configuration from a specified file.
-shell> nfacctd -f nfacctd.conf
-
-Daemonize the process; aggregate data by sum_host (by host, summing inbound + outbound
-traffic); write to a local MySQL server. Listen on port 5678 for incoming Netflow
-datagrams (from one or multiple NetFlow agents). Let's make pmacct refresh data each
-two minutes and let's make data historical, divided into timeslots of 10 minutes each.
-Finally, let's make use of a SQL table, version 4.
-shell> nfacctd -D -c sum_host -P mysql -l 5678
-
-And now written the configuration way:
-!
-daemonize: true
-plugins: mysql
-aggregate: sum_host
-nfacctd_port: 5678
-sql_refresh_time: 120
-sql_history: 10m
-sql_history_roundoff: mh
-sql_table_version: 4
-! ...
-
-VI. Running the ULOG-based daemon (uacctd)
-All examples about pmacctd are also valid for uacctd with the exception of directives
-that apply exclusively to libpcap. If you've skipped examples in section 'IV', please
-read them before continuing. All configuration keys available are in the CONFIG-KEYS
-document.
-
-The Linux ULOG infrastructure requires a couple parameters in order to work properly.
-These are the ULOG multicast group (uacctd_group) to which captured packets have to be
-sent to and the Netlink buffer size (uacctd_nl_size). The default buffer settings (4KB)
-typically works OK for small environments. If the uacctd user is not already familiar
-with the iptables ULOG target, it is adviceable to start with a tutorial, like the one
-at the following URL ("6.5.15. ULOG target" section):
-
-http://www.faqs.org/docs/iptables/targets.html
-
-Apart from determining how and what traffic to capture with iptables, which is topic
-outside the scope of this document, the most relevant point is the "--ulog-nlgroup"
-iptables setting has to match with the "uacctd_group" uacctd one.
-
-A couple examples follow:
-
-Run uacctd reading configuration from a specified file.
-shell> uacctd -f uacctd.conf
-
-Daemonize the process; aggregate data by sum_host (by host, summing inbound + outbound
-traffic); write to a local MySQL server. Listen on ULOG multicast group #5. Let's make
-pmacct divide data into historical time-bins of 5 minutes. Let's disable UPDATE queries
-and hence align refresh time with the timeslot length. Finally, let's make use of a SQL
-table, version 4:
-!
-uacctd_group: 5
-daemonize: true
-plugins: mysql
-aggregate: sum_host
-sql_refresh_time: 300
-sql_history: 5m
-sql_history_roundoff: mh
-sql_table_version: 4
-sql_dont_try_update: true
-! ...
-
-VII. Running the pmacct client (pmacct)
-The pmacct client is used to retrieve data from memory tables. Requests and answers
-are exchanged via a pipe file: authorization is strictly connected to permissions on
-the pipe file. Note: while writing queries commandline, it may happen to write chars
-with a special meaning for the shell itself (ie. ; or *). Mind to either escape ( \;
-or \* ) them or put in quotes ( " ).
-
-Show all available pmacct client commandline switches:
-shell> pmacct -h
-
-Fetch data stored into the memory table:
-shell> pmacct -s
-
-Match data between source IP 192.168.0.10 and destination IP 192.168.0.3 and return
-a formatted output; display all fields (-a), this way the output is easy to be parsed
-by tools like awk/sed; each unused field will be zero-filled:
-shell> pmacct -c src_host,dst_host -M 192.168.0.10,192.168.0.3 -a
-
-Similar to the previous example; it is requested to reset data for matched entries;
-the server will return the actual counters to the client, then will reset them:
-shell> pmacct -c src_host,dst_host -M 192.168.0.10,192.168.0.3 -r
-
-Fetch data for IP address dst_host 10.0.1.200; we also ask for a 'counter only' output
-('-N') suitable, this time, for injecting data in tools like MRTG or RRDtool (sample
-scripts are in the examples/ tree). Bytes counter will be returned (but the '-n' switch
-allows also select which counter to display). If multiple entries match the request (ie
-because the query is based on dst_host but the daemon is actually aggregating traffic
-as "src_host, dst_host") their counters will be summed:
-shell> pmacct -c dst_host -N 10.0.1.200
-
-Another query; this time let's contact the server listening on pipe file /tmp/pipe.eth0:
-shell> pmacct -c sum_port -N 80 -p /tmp/pipe.eth0
-
-Find all data matching host 192.168.84.133 as either their source or destination address.
-In particular, this example shows how to use wildcards and how to spawn multiple queries
-(each separated by the ';' symbol). Take care to follow the same order when specifying
-the primitive name (-c) and its actual value ('-M' or '-N'):
-shell> pmacct -c src_host,dst_host -N "192.168.84.133,*;*,192.168.84.133"
-
-Find all web and smtp traffic; we are interested in have just the total of such traffic
-(for example, to split legal network usage from the total); the output will be a unique
-counter, sum of the partial (coming from each query) values.
-shell> pmacct -c src_port,dst_port -N "25,*;*,25;80,*;*,80" -S
-
-Show traffic between the specified hosts; this aims to be a simple example of a batch
-query; note that as value of both '-N' and '-M' switches it can be supplied a value like:
-'file:/home/paolo/queries.list': actual values will be read from the specified file (and
-they need to be written into it, one per line) instead of commandline:
-shell> pmacct -c src_host,dst_host -N "10.0.0.10,10.0.0.1;10.0.0.9,10.0.0.1;10.0.0.8,10.0.0.1"
-shell> pmacct -c src_host,dst_host -N "file:/home/paolo/queries.list"
-
-
-VIII. Running the logfile players (pmmyplay and pmpgplay)
-For brevity, examples in this section will revolve around "pmmyplay" tool but the same
-are applicable to "pmpgplay". Currently, two different methods are supported as failover
-action when the RDBMS fails: logfiles or backup DB. While planning for a recovery method,
-consider that the logfile method is being discontinued and you are encouraged to use the
-backup DB option.
-
-Display online help and available options:
-shell> pmmyplay -h
-
-Play the whole specified file, inserting elements in the DB and enabling debug:
-shell> pmmyplay -d -f /tmp/pmacct-recovery.dat
-
-Just see on the screen the content of the supplied logfile; that is, do not interact with
-the DB:
-shell> pmmyplay -d -t -f /tmp/pmacct-recovery.dat
-
-Play a single (-n 1) element (the fifth) from the specified file (useful if for example
-a previous player execution was aborted due to a failure):
-shell> pmmyplay -o 5 -n 1 -f /tmp/pmacct-recovery.dat
-
-Play all elements until the end of file, starting from element number six:
-shell> pmmyplay -o 6 -f /tmp/pmacct-recovery.dat -p ohwhatanicepwrd
-
-
-IX. Quickstart guide to packet classifiers
-pmacct 0.10.0 sees the introduction of a packet classification feature. The approach
-is fully extensible: classification patterns are based over regular expressions (RE),
-must be placed into a common directory and have a .pat file extension. Patterns for
-well-known protocols are available and are just a click away. Furthermore, you can
-write your own patterns (and share them with the active L7-filter project's community).
-Below the quickstarter guide:
-
-a) download pmacct
-shell> wget http://www.pmacct.net/pmacct-x.y.z.tar.gz
-
-b) compile pmacct
-shell> cd pmacct-x.y.z; ./configure && make && make install
-
-c-1) download regular expression (RE) classifiers as-you-need them: you just need to
- point your browser to http://l7-filter.sourceforge.net/protocols/ then:
-
- shell> cd /path/to/classifiers/
- shell> wget http://l7-filter.sourceforge.net/layer7-protocols/protocols/[ protocol ].pat
-
-c-2) download all the RE classifiers available: you just need to point your browser to
- http://sourceforge.net/projects/l7-filter (and take to the latest L7-protocol
- definitions tarball). Pay attention to remove potential catch-all patterns which
- might be part of the downloaded package (ie. unknown.pat and unset.pat).
-
-c-3) download shared object (SO) classifiers (written in C) as-you-need them: you need
- just to point your browser to http://www.pmacct.net/classification/ , download the
- available package, extract files and compile things following INSTALL instructions.
- When everything is finished, install the produced shared objects:
-
- shell> mv *.so /path/to/classifiers/
-
-d-1) build pmacct configuration, a memory table example:
-!
-daemonize: true
-interface: eth0
-aggregate: flows, class
-plugins: memory
-classifiers: /path/to/classifiers/
-snaplen: 700
-!...
-
-d-2) build pmacct configuration, a SQL example:
-!
-daemonize: true
-interface: eth0
-aggregate: flows, class
-plugins: mysql
-classifiers: /path/to/classifiers/
-snaplen: 700
-sql_history: 1h
-sql_history_roundoff: h
-sql_table_version: 5
-sql_aggressive_classification: true
-!...
-
-e) Ok, we are done! Fire the pmacct collector daemon:
-
- shell> pmacctd -f /path/to/configuration/file
-
- You can now play with the SQL or pmacct client; furthermore, you can add/remove/write
- patterns and load them by restarting the pmacct daemon. If using the memory plugin
- you can check out the list of loaded plugins with 'pmacct -C'. Don't underestimate
- the importance of 'snaplen', 'pmacctd_flow_buffer_size', 'pmacctd_flow_buffer_buckets'
- values; get the time to take a read about them in the CONFIG-KEYS document.
-
-
-X. Quickstart guide to setup a NetFlow agent/probe
-pmacct 0.11.0 sees the introduction of traffic data export capabilities, through both
-NetFlow and sFlow protocols. While NetFlow v5 is fixed by nature, v9 adds flexibility
-by allowing to transport custom informations (for example, L7-classification tags to a
-remote collector). Below the quickstarter guide:
-
-a) usual initial steps: download pmacct, unpack it, compile it.
-
-b) build NetFlow probe configuration, using pmacctd:
-!
-daemonize: true
-interface: eth0
-aggregate: src_host, dst_host, src_port, dst_port, proto, tos
-plugins: nfprobe
-nfprobe_receiver: 1.2.3.4:2100
-nfprobe_version: 9
-! nfprobe_engine: 1:1
-! nfprobe_timeouts: tcp=120:maxlife=3600
-!
-! networks_file: /path/to/networks.lst
-!...
-
- This is a basic working configuration. Additional features include: 1) generate ASNs
- by using a networks_file pointing to a valid Networks File (see examples/ directory)
- and adding src_as, dst_as primitives to the 'aggregate' directive; alternatively, as
- of release 0.12.0rc2, it's possible to generate ASNs from the pmacctd BGP thread. The
- following fragment can be added to the configuration above:
-
-pmacctd_as: bgp
-bgp_daemon: true
-bgp_daemon_ip: 127.0.0.1
-bgp_agent_map: /path/to/agent_to_peer.map
-bgp_daemon_port: 17917
-
- The bgp_daemon_port can be changed from the standard BGP port (179/TCP) in order to
- co-exist with other BGP routing software which might be running on the same host.
- Furthermore, they can safely peer each other by using 127.0.0.1 as bgp_daemon_ip.
- In pmacctd, bgp_agent_map does the trick of mapping 0.0.0.0 to the IP address of
- the BGP peer (ie. 127.0.0.1: 'id=127.0.0.1 ip=0.0.0.0'); this setup, while generic,
- was tested working in conjunction with Quagga 0.99.14. Following a relevant fragment
- of the Quagga configuration:
-
-router bgp Y
- bgp router-id X.X.X.X
- neighbor 127.0.0.1 remote-as Y
- neighbor 127.0.0.1 port 17917
- neighbor 127.0.0.1 update-source X.X.X.X
-!
-
- 2) encode flow classification information in NetFlow v9 like Cisco does with its
- NBAR/NetFlow v9 tie-up. This can be done by introducing the 'class' primitive to
- the afore mentioned 'aggregate' and add the extra configuration directives:
-
-aggregate: class, src_host, dst_host, src_port, dst_port, proto, tos
-classifiers: /path/to/classifiers/
-snaplen: 700
-
- Further information on this topic can be found in the section of this document about
- stream classification; 3) add direction (ingress, egress) awareness to measured IP
- traffic flows. Direction can be inferred either statically (in, out) or dinamically
- (tag, tag2) via nfprobe_direction directive. Let's look at a dynamic example using
- tag2; first, add the following lines to the daemon configuration:
-
-nfprobe_direction: tag2
-pre_tag_map: /path/to/pretag.map
-
- then edit the tag map as follows. A return value of '1' means ingress while '2' is
- translated to egress. It is possible to employ L2 and/or L3 addresses to recognize
- flow directions. The 'id2' primitive (tag2) will be used to carry the return value:
-
-id=1 filter='dst host XXX.XXX.XXX.XXX'
-id=2 filter='src host XXX.XXX.XXX.XXX'
-
-id=1 filter='ether src XX:XX:XX:XX:XX:XX'
-id=2 filter='ether dst XX:XX:XX:XX:XX:XX'
-
- Indeed in such a case, the 'id' primitive (tag) can be leveraged to other uses (ie.
- filter sub-set of the traffic for flow export); 4) add interface (input, output)
- awareness to measured IP traffic flowsi - in addition to direction awareness, as
- just discussed. Interface can be inferred either statically (<1-4294967295>) or
- dynamically (tag, tag2) via nfprobe_ifindex directive. Let's look at a dynamic
- example using tag; first add the following lines to the daemon configuration:
-
-nfprobe_direction: tag
-pre_tag_map: /path/to/pretag.map
-
- then edit the tag map as follows. It is possible to employ L2 and/or L3 addresses
- to recognize flow directions. The 'id' primitive (tag) will be used to carry the
- return value:
-
-id=100 filter='dst host XXX.XXX.XXX.XXX'
-id=100 filter='src host XXX.XXX.XXX.XXX'
-id=200 filter='dst host YYY.YYY.YYY.YYY'
-id=200 filter='src host YYY.YYY.YYY.YYY'
-
-id=200 filter='ether src YY:YY:YY:YY:YY:YY'
-id=200 filter='ether dst YY:YY:YY:YY:YY:YY'
-
-c) build NetFlow collector configuration, using nfacctd:
-!
-daemonize: true
-nfacctd_ip: 1.2.3.4
-nfacctd_port: 2100
-plugins: memory[display]
-aggregate[display]: src_host, dst_host, src_port, dst_port, proto
-!
-! classifiers: /path/to/classifiers
-
-d) Ok, we are done ! Now fire both daemons:
-
- shell a> pmacctd -f /path/to/configuration/pmacctd-nfprobe.conf
- shell b> nfacctd -f /path/to/configuration/nfacctd-memory.conf
-
-
-XI. Quickstart guide to setup a sFlow agent/probe
-pmacct 0.11.0 sees the introduction of traffic data export capabilities via sFlow; such
-protocol is quite different from NetFlow: in short, it works by exporting portions of
-sampled packets rather than building uni-directional flows as it happens in NetFlow;
-this less-stateful approach makes sFlow a light export protocol well-tailored for high-
-speed networks. Further, sFlow v5 can be extended much like NetFlow v9: meaning, ie.,
-L7 classification or basic Extended Gateway information (ie. src_as, dst_as) can be
-embedded in the record structure being exported. Below the quickstarter guide:
-
-b) build sFlow probe configuration, using pmacctd:
-!
-daemonize: true
-interface: eth0
-plugins: sfprobe
-sampling_rate: 20
-sfprobe_agentsubid: 1402
-sfprobe_receiver: 1.2.3.4:6343
-!
-! networks_file: /path/to/networks.lst
-! classifiers: /path/to/classifiers/
-! snaplen: 700
-!...
-
-
-XII. Quickstart guide to setup the BGP daemon
-pmacct 0.12.0 integrates a BGP daemon into the IP accounting collectors part of
-the toolset. Such daemon is run as a thread within the collector core process. The
-idea is to receive data-plane information, ie. via NetFlow, sFlow, etc., and control
-plane information, ie. full routing tables via BGP from edge routers. Per-peer BGP
-RIBs are maintained to ensure local or regional views of the network (ie. in case
-of large networks which are partitioned in BGP clusters or federations).
-In case of routers with default-only or partial BGP views, the default route can be
-followed up (bgp_default_follow); also it might be desirable in certain situations,
-for example to save resources, to entirely map one or a set of agents to a BGP peer
-(bgp_agent_map).
-
-Pre-requisite is that the pmacct package has to be configured for compilation with
-threads, this line will do it:
-
-./configure --enable-threads
-
-The following configuration fragment is alone sufficient to set up a BGP daemon which
-will bind to an IP address and will support up to a maximum number of 100 peers. Once
-PE routers start sending NetFlow datagrams and peer up, it should be possible to see
-the BGP-related fields, ie. src_as, dst_as, as_path, peer_as_dst, local_pref, MED, etc.,
-correctly populated while querying the memory table:
-
-bgp_daemon: true
-bgp_daemon_ip: X.X.X.X
-bgp_daemon_max_peers: 100
-nfacctd_as_new: bgp
-[ ... ]
-plugins: memory
-aggregation: src_as, dst_as, local_pref, med, as_path, peer_dst_as
-
-The BGP daemon reads the remote ASN upon receipt of a BGP OPEN message and dynamically
-presents itself as part of the same Autonomous System - to ensure an iBGP relationship
-is established all the times. Also, the BGP daemon acts as a passive BGP neighbor and
-hence will never try to re-establish a fallen peering session.
-For debugging purposes related to the BGP feed(s), the bgp_daemon_msglog configuration
-directive can be enabled in order to log UPDATE and WITHDRAW BGP events.
-
-XIIa. Limiting AS-PATH and BGP community attributes length
-AS-PATH and BGP communities can by nature get easily long, when represented as strings.
-Sometimes only a small portion of their content is relevant to the accounting task and
-hence a filtering layer was developed to take special care of these attributes. The
-bgp_aspath_radius cuts the AS-PATH down after a specified amount of hops; whereas the
-bgp_stdcomm_pattern does a simple sub-string matching against standard BGP communities,
-filtering in only those that match (optionally, for better precision, a pre-defined
-number of characters can be wildcarded by employing the '.' symbol, like in regular
-expressions). See a typical usage example below:
-
-bgp_aspath_radius: 3
-bgp_stdcomm_pattern: 12345:
-
-A detailed description of these configuration directives is, as usual, included in
-the CONFIG-KEYS document.
-
-XIIb. The source peer AS case
-The peer_src_as primitive adds useful insight in understanding where traffic enters
-the observed routing domain; but asymmetric routing impacts accuracy delivered by
-devices configured with either NetFlow or sFlow and the peer-as feature (as it only
-performs a reverse lookup, ie. a lookup on the source IP address, in the BGP table
-hence saying where it would route such traffic). pmacct offers a few ways to perform
-some mapping to tackle this issue and easily model both private and public peerings,
-both bi-lateral or multi-lateral. Find below how to use a map, reloadable at runtime,
-and its contents (for full syntax guide lines, please see the 'peers.map.example'
-file within the examples section):
-
-bgp_peer_src_as_type: map
-bgp_peer_src_as_map: /path/to/peers.map
-
-[/path/to/peers.map]
-id=12345 ip=1.2.3.4 in=10 bgp_nexthop=3.4.5.6
-id=34567 ip=1.2.3.4 in=10
-
-id=45678 ip=2.3.4.5 in=20 src_mac=00:11:22:33:44:55
-id=56789 ip=2.3.4.5 in=20 src_mac=00:22:33:44:55:66
-
-Even though all this mapping is static, it can be auto-provisioned to a good degree
-by means of external scripts running at regular intervals and, for example, querying
-relevant routers via SNMP. In this sense, the bgpPeerTable MIB is a good starting
-point. Alternatively pmacct also offers the option to perform reverse BGP lookups.
-
-NOTES:
-* When mapping, the peer_src_as primitive doesn't really apply to egress NetFlow
- (or egress sFlow) as it mainly relies on either the input interface index
- (ifIndex), the source MAC address, a reverse BGP next-hop lookup or a combination
- of these.
-* "Source" MED, local preference, communities and AS-PATH have all been dedicated an
- aggregation primitives. Each carries its own peculiarities but the general concepts
- highlighed in this paragraph apply to these aswell. Check CONFIG-KEYS out for the
- src_[med|local_pref|as_path|std_comm|ext_comm]_[type|map] configuration directives.
-
-XIIc. Tracking entities on the own IP address space
-It might happen that not all entities attached to the service provider network are
-speaking BGP but rather they get IP prefixes redistributed into iBGP (different
-routing protocols, statics, directly connected, etc.). These can be private IP
-addresses or segments of the SP address space. The common factor to all of them is
-that while being present in iBGP, these prefixes can't be tracked any further due
-to the lack of attributes like AS-PATH or an ASN. To overcome this situation the
-simplest approach is to employ a bgp_peer_src_as_map directive, described previously
-(ie. making use of interface descriptions as a possible way to automate the process).
-Alterntively, the bgp_stdcomm_pattern_to_asn directive was developed to fit into
-this scenario: assuming procedures of a SP are (or can be changed) to label every
-relevant non-BGP speaking entity IP prefixes uniquely with a BGP standard community,
-this directive allows to map the community to a peer AS/origin AS couple as per the
-following example: XXXXX:YYYYY => Peer-AS=XXXXX, Origin-AS=YYYYY.
-
-
-XIId. Preparing the router to BGP peer
-Once the collector is configured and started up the remaining step is to let routers
-to export traffic samples to the collector and BGP peer with it. Configuring the same
-source IP address across both NetFlow and BGP features allows the pmacct collector to
-perform the required correlations. Also, setting the BGP Router ID accordingly allows
-for more clear log messages. It's adviceable to configure the collector at the routers
-as a Route-Reflector (RR) client.
-
-A relevant configuration example for a Cisco router follows:
-
-ip flow-export source Loopback12345
-ip flow-export version 5
-ip flow-export destination X.X.X.X 2100
-!
-router bgp 12345
- neighbor X.X.X.X remote-as 12345
- neighbor X.X.X.X update-source Loopback12345
- neighbor X.X.X.X version 4
- neighbor X.X.X.X send-community
- neighbor X.X.X.X route-reflector-client
- neighbor X.X.X.X description nfacctd
-
-A relevant configuration example for a Juniper router follows:
-
-forwarding-options {
- sampling {
- output {
- cflowd X.X.X.X {
- port 2100;
- source-address Y.Y.Y.Y;
- version 5;
- }
- }
- }
-}
-protocols bgp {
- group rr-netflow {
- type internal;
- local-address Y.Y.Y.Y;
- family inet {
- any;
- }
- cluster Y.Y.Y.Y;
- neighbor X.X.X.X {
- description "nfacctd";
- }
- }
-}
-
-XIIe. A working configuration example writing to a MySQL database
-The following setup is a realistic example for a MPLS-enabled IP carrier network
-divided in multiple BGP clusters. Samples are aggregated in a way which is suitable
-to get an overview of traffic trajectories, collecting much information where these
-enter the AS and where they get out.
-
-daemonize: true
-nfacctd_port: 2100
-nfacctd_time_new: true
-
-plugins: mysql[5mins], mysql[hourly]
-
-sql_optimize_clauses: true
-sql_dont_try_update: true
-sql_multi_values: 1024000
-
-sql_history_roundoff[5mins]: m
-sql_history[5mins]: 5m
-sql_refresh_time[5mins]: 300
-sql_table[5mins]: acct_bgp_5mins
-
-sql_history_roundoff[hourly]: h
-sql_history[hourly]: 1h
-sql_refresh_time[hourly]: 3600
-sql_table[hourly]: acct_bgp_1hr
-
-bgp_daemon: true
-bgp_daemon_ip: X.X.X.X
-bgp_daemon_max_peers: 100
-bgp_aspath_radius: 3
-bgp_follow_default: 1
-nfacctd_as_new: bgp
-bgp_peer_src_as_type: map
-bgp_peer_src_as_map: /path/to/peers.map
-
-plugin_buffer_size: 10240
-plugin_pipe_size: 1024000
-aggregate: tag, src_as, dst_as, peer_src_as, peer_dst_as, peer_src_ip, peer_dst_ip, local_pref, as_path
-
-pre_tag_map: /path/to/pretag.map
-refresh_maps: true
-pre_tag_map_entries: 3840
-
-The content of the maps (bgp_peer_src_as_map, pre_tag_map) is meant to be pretty
-standard and will not be shown. As it can be grasped from the above configuration,
-the SQL schema was customized. Below a suggestion on how this can be modified for
-more efficiency - with additional INDEXes, to speed up specific queries response
-time, remaining to be worked out:
-
-create table acct_bgp_5mins (
- id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
- agent_id INT(4) UNSIGNED NOT NULL,
- as_src INT(4) UNSIGNED NOT NULL,
- as_dst INT(4) UNSIGNED NOT NULL,
- peer_as_src INT(4) UNSIGNED NOT NULL,
- peer_as_dst INT(4) UNSIGNED NOT NULL,
- peer_ip_src CHAR(15) NOT NULL,
- peer_ip_dst CHAR(15) NOT NULL,
- as_path CHAR(21) NOT NULL,
- local_pref INT(4) UNSIGNED NOT NULL,
- packets INT UNSIGNED NOT NULL,
- bytes BIGINT UNSIGNED NOT NULL,
- stamp_inserted DATETIME NOT NULL,
- stamp_updated DATETIME,
- PRIMARY KEY (id),
- INDEX ...
-) TYPE=MyISAM AUTO_INCREMENT=1;
-
-create table acct_bgp_1hr (
- id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
- agent_id INT(4) UNSIGNED NOT NULL,
- as_src INT(4) UNSIGNED NOT NULL,
- as_dst INT(4) UNSIGNED NOT NULL,
- peer_as_src INT(4) UNSIGNED NOT NULL,
- peer_as_dst INT(4) UNSIGNED NOT NULL,
- peer_ip_src CHAR(15) NOT NULL,
- peer_ip_dst CHAR(15) NOT NULL,
- as_path CHAR(21) NOT NULL,
- local_pref INT(4) UNSIGNED NOT NULL,
- packets INT UNSIGNED NOT NULL,
- bytes BIGINT UNSIGNED NOT NULL,
- stamp_inserted DATETIME NOT NULL,
- stamp_updated DATETIME,
- PRIMARY KEY (id),
- INDEX ...
-) TYPE=MyISAM AUTO_INCREMENT=1;
-
-XIIf. BGP daemon implementation concluding notes
-The implementation supports both 4-bytes ASN and IPv6 (MP-BGP); IPv6 peers are not
-supported yet though. When storing data via SQL, BGP primitives can be freely mix-
-and-matched with other primitives (ie. L2/L3/L4) when customizing the SQL table
-(sql_optimize_clauses: true). Environments making use of BGP Multi-Path are not
-currently supported; if you are using this and would like to see it implemented,
-please get in touch. TCP MD5 signature for BGP messages is not yet supported but
-on the radar. For a review of all the configurable knobs and features see the
-CONFIG-KEYS document.
-
-
-XIII. Quickstart guide to setup a NetFlow/sFlow replicator
-pmacct 0.12 (>= 0.12.2) includes a new 'tee' plugin which is meant to replicate
-NetFlow/sFlow data to N remote collectors. The plugin can also act transparently
-by preserving the original IP address of the datagrams.
-Setting up a replicator is very easy. All is needed is where to listen to for
-incoming packets, where to replicate them to and optionally a filtering layer,
-if required. Filtering bases on the standard pre_tag_map infrastructure; only
-coarse-grained filtering against original source IP address is possible.
-
-nfacctd_port: 2100
-nfacctd_ip: X.X.X.X
-
-plugins: tee[a], tee[b]
-tee_receiver[a]: Y.Y.Y.Y:2100
-tee_receiver[b]: Z.Z.Z.Z:2100
-! tee_transparent: true
-
-! pre_tag_map: /path/to/pretag.map
-! pre_tag_filter[b]: 0
-
-plugin_buffer_size: 10240
-plugin_pipe_size: 1024000
-
-The pre_tag_filter in the above configuration snapshot applies only to the 'tee'
-plugin instance 'b' and filters out any NetFlow/sFlow packets marked with a non-
-zero 'id'. Plugin instance 'a' would normally receive all packets instead. An
-example of the pre_tag_map content follows:
-
-id=1 ip=A.A.A.A
-id=1 ip=B.B.B.B
-id=1 ip=C.C.C.C
-
-To enable the transparent mode, the tee_transparent should be commented out. It
-preserves the original IP address of the NetFlow/sFlow sender while replicating
-by essentially spoofing it. This feature is not global and can be freely enabled
-only on a subset of the active replicators. It requires super-user permissions
-in order to run.
-
-Concluding note: 'tee' plugin is not compatible with different plugins - within
-the same daemon instance. So if in the need of using pmacct for both collecting
-and replicating data, two separate instances must be used (intuitively with the
-replicator instance feeding the collector one).
-
-
-XIV. Quickstart guide to setup the IS-IS daemon
-pmacct 0.14.0 integrates an IS-IS daemon into the IP accounting collectors part
-of the toolset. Such daemon is run as a thread within the collector core process.
-The idea is to receive data-plane information, ie. via NetFlow, sFlow, etc., and
-control-plane information via IS-IS. Currently a single L2 P2P neighborship, ie.
-over a GRE tunnel, is supported. The daemon is currently used for the purpose of
-route resolution. A sample scenario could be that more specific internal routes
-might be configured to get summarized in BGP while crossing cluster boundaries.
-
-Pre-requisite for the use of the IS-IS daemon is that the pmacct package has to
-be configured for compilation with threads, this line will do it:
-
-./configure --enable-threads
-
-XIVa. Preparing the collector for the L2 P2P IS-IS neighborship
-It's assumed the collector sits on an Ethernet segment and has not direct link
-(L2) connectivity to an IS-IS speaker, hence the need to establish a GRE tunnel.
-While extensive literature and OS specific examples exist on the topic, a brief
-example for Linux, consistent with rest of the chapter, is provided below:
-
-ip tunnel add gre2 mode gre remote 10.0.1.2 local 10.0.1.1 ttl 255
-ip link set gre2 up
-
-The following configuration fragment is sufficient to set up an IS-IS daemon
-which will bind to a network interface gre2 configured with IP address 10.0.1.1
-in an IS-IS area 49.0001 and a CLNS MTU set to 1400:
-
-isis_daemon: true
-isis_daemon_ip: 10.0.1.1
-isis_daemon_net: 49.0001.0100.0000.1001.00
-isis_daemon_iface: gre2
-isis_daemon_mtu: 1400
-! isis_daemon_msglog: true
-
-XIVb. Preparing the router for the L2 P2P IS-IS neighborship
-Once the collector is ready, the remaining step is to configure a remote router
-for the L2 P2P IS-IS neighborship. The following bit of configuration (based on
-Cisco IOS) will match the above fragment of configuration for the IS-IS daemon:
-
-interface Tunnel0
- ip address 10.0.1.2 255.255.255.252
- ip router isis
- tunnel source FastEthernet0
- tunnel destination XXX.XXX.XXX.XXX
- clns mtu 1400
- isis metric 1000
-!
-router isis
- net 49.0001.0100.0000.1002.00
- is-type level-2-only
- metric-style wide
- log-adjacency-changes
- passive-interface Loopback0
-!
-
-
-XV. Running the print plugin to write to flat-files
-Print plugin was originally conceived to display data on standard output; with
-pmacct 0.14 a new 'print_output_file' configuration directive is introduced to
-allow the plugin to write to flat-files aswell. Dynamic filenames are supported.
-Output is text-based (no binary proprietary format) and can be either CSV or
-formatted ('print_output' directive). When to write to disk can be configured
-via the 'print_refresh_time' directive. An example follows on how to write to
-files on a 15 mins basis in CSV format:
-
-print_refresh_time: 900
-print_output: csv
-print_output_file: /path/to/file-%Y%m%d-%H%M.txt
-print_time_roundoff: m
-
-Which, over time, would produce a would produce a series of files as follows:
-
--rw------- 1 paolo paolo 2067 Nov 21 00:15 blabla-20111121-0000.txt
--rw------- 1 paolo paolo 2772 Nov 21 00:30 blabla-20111121-0015.txt
--rw------- 1 paolo paolo 1916 Nov 21 00:45 blabla-20111121-0030.txt
--rw------- 1 paolo paolo 2940 Nov 21 01:00 blabla-20111121-0045.txt
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/AUTHORS
^
|
@@ -1,4 +1,4 @@
-pmacct (Promiscuous mode IP Accounting package) v0.14.0
+pmacct (Promiscuous mode IP Accounting package) v0.14.1
pmacct is Copyright (C) 2003-2012 by Paolo Lucente
Founder:
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/CONFIG-KEYS
^
|
@@ -2,7 +2,7 @@
Both configuration directives and commandline switches are listed below.
A configuration consists of key/value pairs, separated by the ':' char.
Starting a line with the '!' symbol, makes the whole line to be ignored
-by the interpreter, making it a comment. Please refer also to the EXAMPLES
+by the interpreter, making it a comment. Please also refer to QUICKSTART
document and the 'examples/' sub-tree for some examples.
Directives are sometimes grouped, like sql_table and print_output_file:
@@ -1195,7 +1195,7 @@
addresses for the IS-IS area and the system ID of the router. No default value is set and
a non-zero value is mandatory. Extensive IS-IS and ISO literature cover the topic, example
of the NET value format can be found as part of the "Quickstart guide to setup the IS-IS
- daemon" in the EXAMPLES document.
+ daemon" in the QUICKSTART document.
KEY: isis_daemon_iface
DESC: Defines the network interface (ie. gre1) where to bind the IS-IS daemon. No default value
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/ChangeLog
^
|
@@ -1,6 +1,44 @@
-pmacct (Promiscuous mode IP Accounting package) v0.14.0
+pmacct (Promiscuous mode IP Accounting package) v0.14.1
pmacct is Copyright (C) 2003-2012 by Paolo Lucente
+0.14.1 -- 03-08-2012
+ + nfacctd: introduced support for IPFIX variable-length IEs (RFC5101),
+ improved support for IPFIX PEN IEs.
+ + nfacctd, sfacctd: positive/negative caching for bgp_agent_map and
+ sampling_map is being introduced. Cache entries are invalidated upon
+ reload of the maps.
+ + bgp_agent_map: resolution of IPv4 NetFlow agents to BGP speakers
+ with IPv6 sessions is now possible. This is to support dual-stack
+ network deployments. Also the keyword 'filter' is introduced and
+ supported values are only 'ip' and 'ip6'.
+ + nfacctd: etype primitive can be populated from IP_PROTOCOL_VERSION,
+ ie. Field Type #60, in addition to ETHERTYPE, ie. Field Type #256.
+ Should both be present the latter has priority over the former.
+ + print plugin: introduced a pointer to the latest filename in the set,
+ ie. in cases when variable filenames are specified. The pointer comes
+ in the shape of a symlink called "<plugin name>-latest".
+ ! fix, pretag_handlers.c: BGP next-hop handlers are now hooked to the
+ longest-match mechanism for destination IP prefix.
+ ! fix, net_aggr.c: defining a networks_file configuration directive in
+ conjunction with --enable-ipv6 was causing a SEGVs. This is now solved.
+ ! fix, uacctd: cache routine is now being called in order to resolve
+ in/out interface ifindexes. Patch is courtesy by Stig Thormodsrud.
+ ! fix, BGP daemon: bgp_neighbors_file now lists also IPv6 BGP peerings.
+ ! fix, sql_common.c: SQL writers due to safe action are now logged with
+ a warning message rather than debug.
+ ! fix, PostgreSQL table schemas: under certain conditions, default
+ definition of stamp_inserted was generating a 'date/time field value
+ out of range: "0000-01-01 00:00:00"' error. Many thanks to Marcello
+ di Leonardo for reporting the issue and providing a fix.
+ ! fix, IS-IS daemon: sockunion_print() function was found not portable
+ and has been removed.
+ ! fix, BGP daemon: memcpy() replaced by ip6_addr_cpy() upon writing to
+ sockaddr_in6 structures.
+ ! fix, EXAMPLES document has been renamed QUICKSTART for disambiguation
+ on filesystems where case-sensitive names are not supported.
+ ! Several code cleanups. Patches are courtesy by Osama Abu Elsorour
+ and Ryan Steinmetz.
+
0.14.0 -- 11-04-2012
+ pmacct now integrates an IS-IS daemon within collectors; the daemon
is being run as a parallel thread within the collector core process;
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/FAQS
^
|
@@ -1,5 +1,5 @@
pmacct (Promiscuous mode IP Accounting package)
-pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+pmacct is Copyright (C) 2003-2012 by Paolo Lucente
Q1: What is pmacct project homepage ?
A: It is http://www.pmacct.net/ . There isn't any official mirror site.
@@ -38,9 +38,9 @@
By inception, pmacct always aimed to a single-stage approach instead, ie. offer data
reduction tecniques and correlation tools to process network traffic data on the fly,
so to immediately offer the desired view(s) of the traffic. pmacct writes to files in
- text-format (either csv or formatted via its 'print' plugin, see EXAMPLES for further
- information) so to maximize potential integration with 3rd party applications while
- keeping low the effort of customization.
+ text-format (either csv or formatted via its 'print' plugin, see QUICKSTART doc for
+ further information) so to maximize potential integration with 3rd party applications
+ while keeping low the effort of customization.
Q6: Is it feasible for pmacct to scale by making use of either memory tables or RDBMS
@@ -152,7 +152,7 @@
and 'stamp_updated' fields but they remain empty.
A: Historical accounting is easily enabled by adding to the SQL plugin configuration a
'sql_history' directive. Associate to it a 'sql_history_roundoff'. For examples and
- syntax, refer to CONFIG-KEYS and EXAMPLES documents.
+ syntax, refer to CONFIG-KEYS and QUICKSTART documents.
Q12: CLI is not enough to me. I would like to graph traffic data: how to do that?
|
[-]
[+]
|
Added |
pmacct-0.14.1.tar.bz2/QUICKSTART
^
|
@@ -0,0 +1,985 @@
+pmacct (Promiscuous mode IP Accounting package)
+pmacct is Copyright (C) 2003-2012 by Paolo Lucente
+
+TABLE OF CONTENTS:
+I. Plugins included with pmacct distribution
+II. Configuring pmacct for compilation
+III. Brief SQL (MySQL, PostgreSQL, SQLite 3.x) setup examples
+IV. Running the libpcap-based daemon (pmacctd)
+V. Running the NetFlow and sFlow daemons (nfacctd/sfacctd)
+VI. Running the ULOG-based daemon (uacctd)
+VII. Running the pmacct client (pmacct)
+VIII. Running the logfile players (pmmyplay/pmpgplay)
+IX. Quickstart guide to packet/stream classifiers
+X. Quickstart guide to setup a NetFlow agent/probe
+XI. Quickstart guide to setup a sFlow agent/probe
+XII. Quickstart guide to setup the BGP daemon
+XIII. Quickstart guide to setup a NetFlow/sFlow replicator
+XIV. Quickstart guide to setup the IS-IS daemon
+XV. Running the print plugin to write to flat-files
+
+
+I. Plugins included with pmacct distribution
+Given its open and pluggable architecture, pmacct is easily extensible by writing new
+plugins. Here is a list of plugins included within the official pmacct distribution.
+
+'memory': data are stored in a memory table and can be fetched via the pmacct client
+ tool, 'pmacct'. It also allows easily data injection into 3rd party tools
+ like GNUplot, MRTG, RRDtool or a Net-SNMP server
+'mysql': a working MySQL installation can be used for data storage
+'pgsql': a working PostgreSQL installation can be used for data storage
+'sqlite3': a working SQLite 3.x or BerkeleyDB 5.x (compiled in with the SQLite API)
+ installation can be used for data storage
+'print': data are printed at regular intervals to flat-files or standard output
+
+
+II. Configuring pmacct for compilation
+The simplest way to configure the package for compilation is to let the configure
+script to probe default headers and libraries for you. By default SQL plugins are
+not enabled; much like multi-threading (pre-requisite for compiling the BGP daemon
+code), IPv6 support and 64 bits counters. A few examples will follow; as usual to
+get the list of available switches, you can use the following command-line:
+
+shell> ./configure --help
+
+Examples on how to enable the support for (1) MySQL, (2) PostgreSQL, (3) SQLite and
+any (4) mixed compilation:
+
+(1) shell> ./configure --enable-mysql
+(2) shell> ./configure --enable-pgsql
+(3) shell> ./configure --enable-sqlite3
+(4) shell> ./configure --enable-mysql --enable-pgsql
+
+
+III. Brief SQL setup examples
+Scripts for setting up databases (MySQL, PostgreSQL and SQLite) are into the 'sql/'
+tree. For further guidance read the relevant README files in such directory. One of
+the crucial concepts to deal with, when using default IP or BGP SQL tables, is table
+versioning: please read more about it in the FAQS document (Q16).
+
+IIIa. MySQL examples
+shell> cd sql/
+
+- To create v1 tables:
+shell> mysql -u root -p < pmacct-create-db_v1.mysql
+shell> mysql -u root -p < pmacct-grant-db.mysql
+
+Data will be available in 'acct' table of 'pmacct' DB.
+
+- To create v2 tables:
+shell> mysql -u root -p < pmacct-create-db_v2.mysql
+shell> mysql -u root -p < pmacct-grant-db.mysql
+
+Data will be available in 'acct_v2' table of 'pmacct' DB.
+
+... And so on for the newer versions.
+
+IIIb. PostgreSQL examples
+Which user has to execute the following two scripts and how to autenticate with the
+PostgreSQL server depends upon your current configuration. Keep in mind that both
+scripts need postgres superuser permissions to execute some commands successfully:
+shell> cp -p *.pgsql /tmp
+shell> su - postgres
+
+To create v1 tables:
+shell> psql -d template1 -f /tmp/pmacct-create-db.pgsql
+shell> psql -d pmacct -f /tmp/pmacct-create-table_v1.pgsql
+
+To create v2 tables:
+shell> psql -d template1 -f /tmp/pmacct-create-db.pgsql
+shell> psql -d pmacct -f /tmp/pmacct-create-table_v2.pgsql
+
+... And so on for the newer versions.
+
+A few tables will be created into 'pmacct' DB. 'acct' ('acct_v2' or 'acct_v3') table is
+the default table where data will be written when in 'typed' mode (see 'sql_data' option
+in CONFIG-KEYS document; default value is 'typed'); 'acct_uni' ('acct_uni_v2' or
+'acct_uni_v3') is the default table where data will be written when in 'unified' mode.
+
+Since v6, PostgreSQL tables are greatly simplified: unified mode is no longer supported
+and an unique table ('acct_v6', for example) is created instead.
+
+IIIc. SQLite examples
+shell> cd sql/
+
+- To create v1 tables:
+shell> sqlite3 /tmp/pmacct.db < pmacct-create-table.sqlite3
+
+Data will be available in 'acct' table of '/tmp/pmacct.db' DB. Of course, you can change
+the database filename basing on your preferences.
+
+- To create v2 tables:
+shell> sqlite3 /tmp/pmacct.db < pmacct-create-table_v2.sqlite3
+
+Data will be available in 'acct_v2' table of '/tmp/pmacct.db' DB.
+
+... And so on for the newer versions.
+
+IIId. Custom SQL tables
+Custom SQL tables can be built by creating your own SQL schema and indexes. This allows
+to freely mix-and-match the primitives relevant to your accounting scenario. Specifying
+SQL table version and type (sql_table_version, sql_table_type) is not required; whereas
+a new directive, sql_optimize_clauses, is introduced to flag table customization to
+pmacct. This is a simple configuration snippet:
+
+sql_optimize_clauses: true
+sql_table: <table name>
+aggregate: <aggregation primitives list>
+
+IIIe. Historical accounting
+Enabling historical accounting allows to aggregate data over time (ie. 5 mins, hourly,
+daily) in a flexible and fully configurable way. Timestamps are lodged into two fields:
+'stamp_inserted' which represents the basetime of the timeslot and 'stamp_updated' which
+says when a given timeslot was updated for the last time. Following there is a pretty
+standard configuration fragment to slice data into nicely aligned (or rounded-off) 5
+minutes timeslots:
+
+sql_history: 5m
+sql_history_roundoff: m
+
+IIIf. INSERTs-only
+UPDATE queries are demanding in terms of resources; this is why, even if they are
+supported by pmacct, a savy approach is to cache data for longer times in memory and
+write them off once per timeslot (sql_history): this produces a much lighter INSERTs-
+only environemnt. This is an example based on 5 minutes timeslots:
+
+sql_refresh_time: 300
+sql_history: 5m
+sql_history_roundoff: m
+sql_dont_try_update: true
+
+Note that sql_refresh_time is always expressed in seconds.
+
+
+IV. Running the libpcap-based daemon (pmacctd)
+pmacctd, like the other daemons, can be run with commandline options, using a config
+file or a mix of the two. Sample configuration files are in examples/ tree. Note also
+that most of the new features are available only as configuration directives. To be
+aware of the existing configuration directives, please read the CONFIG-KEYS document.
+
+Show all available pmacctd commandline switches:
+shell> pmacctd -h
+
+Run pmacctd reading configuration from a specified file (see examples/ tree for a brief
+list of some commonly useed keys; divert your eyes to CONFIG-KEYS for the full list).
+This example applies to all daemons:
+shell> pmacctd -f pmacctd.conf
+
+Daemonize the process; listen on eth0; aggregate data by src_host/dst_host; write to a
+MySQL server; limit traffic matching only source ip network 10.0.0.0/16; note that
+filters work the same as tcpdump. So, refer to libpcap/tcpdump man pages for examples
+and further reading.
+
+shell> pmacctd -D -c src_host,dst_host -i eth0 -P mysql src net 10.0.0.0/16
+
+Or written the configuration way:
+!
+daemonize: true
+plugins: mysql
+aggregate: src_host, dst_host
+interface: eth0
+pcap_filter: src net 10.0.0.0/16
+! ...
+
+Print collected traffic data aggregated by src_host/dst_host over the screen; refresh
+data every 30 seconds and listen on eth0.
+
+shell> pmacctd -P print -r 30 -i eth0 -c src_host,dst_host
+
+Or written the configuration way:
+!
+plugins: print
+print_refresh_time: 30
+aggregate: src_host, dst_host
+interface: eth0
+! ...
+
+Daemonize the process; let pmacct aggregate traffic in order to show in vs out traffic
+for network 192.168.0.0/16; send data to a PostgreSQL server. This configuration is not
+possible via commandline switches; the corresponding configuration follows:
+
+!
+daemonize: true
+plugins: pgsql[in], pgsql[out]
+aggregate[in]: dst_host
+aggregate[out]: src_host
+aggregate_filter[in]: dst net 192.168.0.0/16
+aggregate_filter[out]: src net 192.168.0.0/16
+sql_table[in]: acct_in
+sql_table[out]: acct_out
+! ...
+
+The previous example looks nice! But how to make data historical ? Simple enough, let's
+suppose you want to split traffic by hour and write data into the DB every 60 seconds.
+
+!
+daemonize: true
+plugins: pgsql[in], pgsql[out]
+aggregate[in]: dst_host
+aggregate[out]: src_host
+aggregate_filter[in]: dst net 192.168.0.0/16
+aggregate_filter[out]: src net 192.168.0.0/16
+sql_table[in]: acct_in
+sql_table[out]: acct_out
+sql_refresh_time: 60
+sql_history: 1h
+sql_history_roundoff: h
+! ...
+
+Let's now translate the same example in the memory plugin world. It's use is valuable
+expecially when it's required to feed bytes/packets/flows counters to external programs.
+Examples about the client program will follow later in this document. Now, note that
+each memory table need its own pipe file in order to get correctly contacted by the
+client:
+
+!
+daemonize: true
+plugins: memory[in], memory[out]
+aggregate[in]: dst_host
+aggregate[out]: src_host
+aggregate_filter[in]: dst net 192.168.0.0/16
+aggregate_filter[out]: src net 192.168.0.0/16
+imt_path[in]: /tmp/pmacct_in.pipe
+imt_path[out]: /tmp/pmacct_out.pipe
+! ...
+
+As a further note, check the CONFIG-KEYS document about more imt_* directives as they
+will support in the task of fine tuning the size and boundaries of memory tables, if
+default values are not ok for your setup.
+
+Now, fire multiple instances of pmacctd, each on a different interface; again, because
+each instance will have its own memory table, it will require its own pipe file for
+client queries aswell (as explained in the previous examples):
+shell> pmacctd -D -i eth0 -m 8 -s 65535 -p /tmp/pipe.eth0
+shell> pmacctd -D -i ppp0 -m 0 -s 32768 -p /tmp/pipe.ppp0
+
+Run pmacctd logging what happens to syslog and using "local2" facility:
+shell> pmacctd -c src_host,dst_host -S local2
+
+NOTE: superuser privileges are needed to execute pmacctd correctly.
+
+
+V. Running the NetFlow and sFlow daemons (nfacctd/sfacctd)
+All examples about pmacctd are also valid for nfacctd and sfacctd with the exception
+of directives that apply exclusively to libpcap. If you've skipped examples in section
+'IV', please read them before continuing. All configuration keys available are in the
+CONFIG-KEYS document. Some examples:
+
+Run nfacctd reading configuration from a specified file.
+shell> nfacctd -f nfacctd.conf
+
+Daemonize the process; aggregate data by sum_host (by host, summing inbound + outbound
+traffic); write to a local MySQL server. Listen on port 5678 for incoming Netflow
+datagrams (from one or multiple NetFlow agents). Let's make pmacct refresh data each
+two minutes and let's make data historical, divided into timeslots of 10 minutes each.
+Finally, let's make use of a SQL table, version 4.
+shell> nfacctd -D -c sum_host -P mysql -l 5678
+
+And now written the configuration way:
+!
+daemonize: true
+plugins: mysql
+aggregate: sum_host
+nfacctd_port: 5678
+sql_refresh_time: 120
+sql_history: 10m
+sql_history_roundoff: mh
+sql_table_version: 4
+! ...
+
+VI. Running the ULOG-based daemon (uacctd)
+All examples about pmacctd are also valid for uacctd with the exception of directives
+that apply exclusively to libpcap. If you've skipped examples in section 'IV', please
+read them before continuing. All configuration keys available are in the CONFIG-KEYS
+document.
+
+The Linux ULOG infrastructure requires a couple parameters in order to work properly.
+These are the ULOG multicast group (uacctd_group) to which captured packets have to be
+sent to and the Netlink buffer size (uacctd_nl_size). The default buffer settings (4KB)
+typically works OK for small environments. If the uacctd user is not already familiar
+with the iptables ULOG target, it is adviceable to start with a tutorial, like the one
+at the following URL ("6.5.15. ULOG target" section):
+
+http://www.faqs.org/docs/iptables/targets.html
+
+Apart from determining how and what traffic to capture with iptables, which is topic
+outside the scope of this document, the most relevant point is the "--ulog-nlgroup"
+iptables setting has to match with the "uacctd_group" uacctd one.
+
+A couple examples follow:
+
+Run uacctd reading configuration from a specified file.
+shell> uacctd -f uacctd.conf
+
+Daemonize the process; aggregate data by sum_host (by host, summing inbound + outbound
+traffic); write to a local MySQL server. Listen on ULOG multicast group #5. Let's make
+pmacct divide data into historical time-bins of 5 minutes. Let's disable UPDATE queries
+and hence align refresh time with the timeslot length. Finally, let's make use of a SQL
+table, version 4:
+!
+uacctd_group: 5
+daemonize: true
+plugins: mysql
+aggregate: sum_host
+sql_refresh_time: 300
+sql_history: 5m
+sql_history_roundoff: mh
+sql_table_version: 4
+sql_dont_try_update: true
+! ...
+
+VII. Running the pmacct client (pmacct)
+The pmacct client is used to retrieve data from memory tables. Requests and answers
+are exchanged via a pipe file: authorization is strictly connected to permissions on
+the pipe file. Note: while writing queries commandline, it may happen to write chars
+with a special meaning for the shell itself (ie. ; or *). Mind to either escape ( \;
+or \* ) them or put in quotes ( " ).
+
+Show all available pmacct client commandline switches:
+shell> pmacct -h
+
+Fetch data stored into the memory table:
+shell> pmacct -s
+
+Match data between source IP 192.168.0.10 and destination IP 192.168.0.3 and return
+a formatted output; display all fields (-a), this way the output is easy to be parsed
+by tools like awk/sed; each unused field will be zero-filled:
+shell> pmacct -c src_host,dst_host -M 192.168.0.10,192.168.0.3 -a
+
+Similar to the previous example; it is requested to reset data for matched entries;
+the server will return the actual counters to the client, then will reset them:
+shell> pmacct -c src_host,dst_host -M 192.168.0.10,192.168.0.3 -r
+
+Fetch data for IP address dst_host 10.0.1.200; we also ask for a 'counter only' output
+('-N') suitable, this time, for injecting data in tools like MRTG or RRDtool (sample
+scripts are in the examples/ tree). Bytes counter will be returned (but the '-n' switch
+allows also select which counter to display). If multiple entries match the request (ie
+because the query is based on dst_host but the daemon is actually aggregating traffic
+as "src_host, dst_host") their counters will be summed:
+shell> pmacct -c dst_host -N 10.0.1.200
+
+Another query; this time let's contact the server listening on pipe file /tmp/pipe.eth0:
+shell> pmacct -c sum_port -N 80 -p /tmp/pipe.eth0
+
+Find all data matching host 192.168.84.133 as either their source or destination address.
+In particular, this example shows how to use wildcards and how to spawn multiple queries
+(each separated by the ';' symbol). Take care to follow the same order when specifying
+the primitive name (-c) and its actual value ('-M' or '-N'):
+shell> pmacct -c src_host,dst_host -N "192.168.84.133,*;*,192.168.84.133"
+
+Find all web and smtp traffic; we are interested in have just the total of such traffic
+(for example, to split legal network usage from the total); the output will be a unique
+counter, sum of the partial (coming from each query) values.
+shell> pmacct -c src_port,dst_port -N "25,*;*,25;80,*;*,80" -S
+
+Show traffic between the specified hosts; this aims to be a simple example of a batch
+query; note that as value of both '-N' and '-M' switches it can be supplied a value like:
+'file:/home/paolo/queries.list': actual values will be read from the specified file (and
+they need to be written into it, one per line) instead of commandline:
+shell> pmacct -c src_host,dst_host -N "10.0.0.10,10.0.0.1;10.0.0.9,10.0.0.1;10.0.0.8,10.0.0.1"
+shell> pmacct -c src_host,dst_host -N "file:/home/paolo/queries.list"
+
+
+VIII. Running the logfile players (pmmyplay and pmpgplay)
+For brevity, examples in this section will revolve around "pmmyplay" tool but the same
+are applicable to "pmpgplay". Currently, two different methods are supported as failover
+action when the RDBMS fails: logfiles or backup DB. While planning for a recovery method,
+consider that the logfile method is being discontinued and you are encouraged to use the
+backup DB option.
+
+Display online help and available options:
+shell> pmmyplay -h
+
+Play the whole specified file, inserting elements in the DB and enabling debug:
+shell> pmmyplay -d -f /tmp/pmacct-recovery.dat
+
+Just see on the screen the content of the supplied logfile; that is, do not interact with
+the DB:
+shell> pmmyplay -d -t -f /tmp/pmacct-recovery.dat
+
+Play a single (-n 1) element (the fifth) from the specified file (useful if for example
+a previous player execution was aborted due to a failure):
+shell> pmmyplay -o 5 -n 1 -f /tmp/pmacct-recovery.dat
+
+Play all elements until the end of file, starting from element number six:
+shell> pmmyplay -o 6 -f /tmp/pmacct-recovery.dat -p ohwhatanicepwrd
+
+
+IX. Quickstart guide to packet classifiers
+pmacct 0.10.0 sees the introduction of a packet classification feature. The approach
+is fully extensible: classification patterns are based over regular expressions (RE),
+must be placed into a common directory and have a .pat file extension. Patterns for
+well-known protocols are available and are just a click away. Furthermore, you can
+write your own patterns (and share them with the active L7-filter project's community).
+Below the quickstarter guide:
+
+a) download pmacct
+shell> wget http://www.pmacct.net/pmacct-x.y.z.tar.gz
+
+b) compile pmacct
+shell> cd pmacct-x.y.z; ./configure && make && make install
+
+c-1) download regular expression (RE) classifiers as-you-need them: you just need to
+ point your browser to http://l7-filter.sourceforge.net/protocols/ then:
+
+ shell> cd /path/to/classifiers/
+ shell> wget http://l7-filter.sourceforge.net/layer7-protocols/protocols/[ protocol ].pat
+
+c-2) download all the RE classifiers available: you just need to point your browser to
+ http://sourceforge.net/projects/l7-filter (and take to the latest L7-protocol
+ definitions tarball). Pay attention to remove potential catch-all patterns which
+ might be part of the downloaded package (ie. unknown.pat and unset.pat).
+
+c-3) download shared object (SO) classifiers (written in C) as-you-need them: you need
+ just to point your browser to http://www.pmacct.net/classification/ , download the
+ available package, extract files and compile things following INSTALL instructions.
+ When everything is finished, install the produced shared objects:
+
+ shell> mv *.so /path/to/classifiers/
+
+d-1) build pmacct configuration, a memory table example:
+!
+daemonize: true
+interface: eth0
+aggregate: flows, class
+plugins: memory
+classifiers: /path/to/classifiers/
+snaplen: 700
+!...
+
+d-2) build pmacct configuration, a SQL example:
+!
+daemonize: true
+interface: eth0
+aggregate: flows, class
+plugins: mysql
+classifiers: /path/to/classifiers/
+snaplen: 700
+sql_history: 1h
+sql_history_roundoff: h
+sql_table_version: 5
+sql_aggressive_classification: true
+!...
+
+e) Ok, we are done! Fire the pmacct collector daemon:
+
+ shell> pmacctd -f /path/to/configuration/file
+
+ You can now play with the SQL or pmacct client; furthermore, you can add/remove/write
+ patterns and load them by restarting the pmacct daemon. If using the memory plugin
+ you can check out the list of loaded plugins with 'pmacct -C'. Don't underestimate
+ the importance of 'snaplen', 'pmacctd_flow_buffer_size', 'pmacctd_flow_buffer_buckets'
+ values; get the time to take a read about them in the CONFIG-KEYS document.
+
+
+X. Quickstart guide to setup a NetFlow agent/probe
+pmacct 0.11.0 sees the introduction of traffic data export capabilities, through both
+NetFlow and sFlow protocols. While NetFlow v5 is fixed by nature, v9 adds flexibility
+by allowing to transport custom informations (for example, L7-classification tags to a
+remote collector). Below the quickstarter guide:
+
+a) usual initial steps: download pmacct, unpack it, compile it.
+
+b) build NetFlow probe configuration, using pmacctd:
+!
+daemonize: true
+interface: eth0
+aggregate: src_host, dst_host, src_port, dst_port, proto, tos
+plugins: nfprobe
+nfprobe_receiver: 1.2.3.4:2100
+nfprobe_version: 9
+! nfprobe_engine: 1:1
+! nfprobe_timeouts: tcp=120:maxlife=3600
+!
+! networks_file: /path/to/networks.lst
+!...
+
+ This is a basic working configuration. Additional features include: 1) generate ASNs
+ by using a networks_file pointing to a valid Networks File (see examples/ directory)
+ and adding src_as, dst_as primitives to the 'aggregate' directive; alternatively, as
+ of release 0.12.0rc2, it's possible to generate ASNs from the pmacctd BGP thread. The
+ following fragment can be added to the configuration above:
+
+pmacctd_as: bgp
+bgp_daemon: true
+bgp_daemon_ip: 127.0.0.1
+bgp_agent_map: /path/to/agent_to_peer.map
+bgp_daemon_port: 17917
+
+ The bgp_daemon_port can be changed from the standard BGP port (179/TCP) in order to
+ co-exist with other BGP routing software which might be running on the same host.
+ Furthermore, they can safely peer each other by using 127.0.0.1 as bgp_daemon_ip.
+ In pmacctd, bgp_agent_map does the trick of mapping 0.0.0.0 to the IP address of
+ the BGP peer (ie. 127.0.0.1: 'id=127.0.0.1 ip=0.0.0.0'); this setup, while generic,
+ was tested working in conjunction with Quagga 0.99.14. Following a relevant fragment
+ of the Quagga configuration:
+
+router bgp Y
+ bgp router-id X.X.X.X
+ neighbor 127.0.0.1 remote-as Y
+ neighbor 127.0.0.1 port 17917
+ neighbor 127.0.0.1 update-source X.X.X.X
+!
+
+ 2) encode flow classification information in NetFlow v9 like Cisco does with its
+ NBAR/NetFlow v9 tie-up. This can be done by introducing the 'class' primitive to
+ the afore mentioned 'aggregate' and add the extra configuration directives:
+
+aggregate: class, src_host, dst_host, src_port, dst_port, proto, tos
+classifiers: /path/to/classifiers/
+snaplen: 700
+
+ Further information on this topic can be found in the section of this document about
+ stream classification; 3) add direction (ingress, egress) awareness to measured IP
+ traffic flows. Direction can be inferred either statically (in, out) or dinamically
+ (tag, tag2) via nfprobe_direction directive. Let's look at a dynamic example using
+ tag2; first, add the following lines to the daemon configuration:
+
+nfprobe_direction: tag2
+pre_tag_map: /path/to/pretag.map
+
+ then edit the tag map as follows. A return value of '1' means ingress while '2' is
+ translated to egress. It is possible to employ L2 and/or L3 addresses to recognize
+ flow directions. The 'id2' primitive (tag2) will be used to carry the return value:
+
+id=1 filter='dst host XXX.XXX.XXX.XXX'
+id=2 filter='src host XXX.XXX.XXX.XXX'
+
+id=1 filter='ether src XX:XX:XX:XX:XX:XX'
+id=2 filter='ether dst XX:XX:XX:XX:XX:XX'
+
+ Indeed in such a case, the 'id' primitive (tag) can be leveraged to other uses (ie.
+ filter sub-set of the traffic for flow export); 4) add interface (input, output)
+ awareness to measured IP traffic flowsi - in addition to direction awareness, as
+ just discussed. Interface can be inferred either statically (<1-4294967295>) or
+ dynamically (tag, tag2) via nfprobe_ifindex directive. Let's look at a dynamic
+ example using tag; first add the following lines to the daemon configuration:
+
+nfprobe_direction: tag
+pre_tag_map: /path/to/pretag.map
+
+ then edit the tag map as follows. It is possible to employ L2 and/or L3 addresses
+ to recognize flow directions. The 'id' primitive (tag) will be used to carry the
+ return value:
+
+id=100 filter='dst host XXX.XXX.XXX.XXX'
+id=100 filter='src host XXX.XXX.XXX.XXX'
+id=200 filter='dst host YYY.YYY.YYY.YYY'
+id=200 filter='src host YYY.YYY.YYY.YYY'
+
+id=200 filter='ether src YY:YY:YY:YY:YY:YY'
+id=200 filter='ether dst YY:YY:YY:YY:YY:YY'
+
+c) build NetFlow collector configuration, using nfacctd:
+!
+daemonize: true
+nfacctd_ip: 1.2.3.4
+nfacctd_port: 2100
+plugins: memory[display]
+aggregate[display]: src_host, dst_host, src_port, dst_port, proto
+!
+! classifiers: /path/to/classifiers
+
+d) Ok, we are done ! Now fire both daemons:
+
+ shell a> pmacctd -f /path/to/configuration/pmacctd-nfprobe.conf
+ shell b> nfacctd -f /path/to/configuration/nfacctd-memory.conf
+
+
+XI. Quickstart guide to setup a sFlow agent/probe
+pmacct 0.11.0 sees the introduction of traffic data export capabilities via sFlow; such
+protocol is quite different from NetFlow: in short, it works by exporting portions of
+sampled packets rather than building uni-directional flows as it happens in NetFlow;
+this less-stateful approach makes sFlow a light export protocol well-tailored for high-
+speed networks. Further, sFlow v5 can be extended much like NetFlow v9: meaning, ie.,
+L7 classification or basic Extended Gateway information (ie. src_as, dst_as) can be
+embedded in the record structure being exported. Below the quickstarter guide:
+
+b) build sFlow probe configuration, using pmacctd:
+!
+daemonize: true
+interface: eth0
+plugins: sfprobe
+sampling_rate: 20
+sfprobe_agentsubid: 1402
+sfprobe_receiver: 1.2.3.4:6343
+!
+! networks_file: /path/to/networks.lst
+! classifiers: /path/to/classifiers/
+! snaplen: 700
+!...
+
+
+XII. Quickstart guide to setup the BGP daemon
+pmacct 0.12.0 integrates a BGP daemon into the IP accounting collectors part of
+the toolset. Such daemon is run as a thread within the collector core process. The
+idea is to receive data-plane information, ie. via NetFlow, sFlow, etc., and control
+plane information, ie. full routing tables via BGP from edge routers. Per-peer BGP
+RIBs are maintained to ensure local or regional views of the network (ie. in case
+of large networks which are partitioned in BGP clusters or federations).
+In case of routers with default-only or partial BGP views, the default route can be
+followed up (bgp_default_follow); also it might be desirable in certain situations,
+for example to save resources, to entirely map one or a set of agents to a BGP peer
+(bgp_agent_map).
+
+Pre-requisite is that the pmacct package has to be configured for compilation with
+threads, this line will do it:
+
+./configure --enable-threads
+
+The following configuration fragment is alone sufficient to set up a BGP daemon which
+will bind to an IP address and will support up to a maximum number of 100 peers. Once
+PE routers start sending NetFlow datagrams and peer up, it should be possible to see
+the BGP-related fields, ie. src_as, dst_as, as_path, peer_as_dst, local_pref, MED, etc.,
+correctly populated while querying the memory table:
+
+bgp_daemon: true
+bgp_daemon_ip: X.X.X.X
+bgp_daemon_max_peers: 100
+nfacctd_as_new: bgp
+[ ... ]
+plugins: memory
+aggregation: src_as, dst_as, local_pref, med, as_path, peer_dst_as
+
+The BGP daemon reads the remote ASN upon receipt of a BGP OPEN message and dynamically
+presents itself as part of the same Autonomous System - to ensure an iBGP relationship
+is established all the times. Also, the BGP daemon acts as a passive BGP neighbor and
+hence will never try to re-establish a fallen peering session.
+For debugging purposes related to the BGP feed(s), the bgp_daemon_msglog configuration
+directive can be enabled in order to log UPDATE and WITHDRAW BGP events.
+
+XIIa. Limiting AS-PATH and BGP community attributes length
+AS-PATH and BGP communities can by nature get easily long, when represented as strings.
+Sometimes only a small portion of their content is relevant to the accounting task and
+hence a filtering layer was developed to take special care of these attributes. The
+bgp_aspath_radius cuts the AS-PATH down after a specified amount of hops; whereas the
+bgp_stdcomm_pattern does a simple sub-string matching against standard BGP communities,
+filtering in only those that match (optionally, for better precision, a pre-defined
+number of characters can be wildcarded by employing the '.' symbol, like in regular
+expressions). See a typical usage example below:
+
+bgp_aspath_radius: 3
+bgp_stdcomm_pattern: 12345:
+
+A detailed description of these configuration directives is, as usual, included in
+the CONFIG-KEYS document.
+
+XIIb. The source peer AS case
+The peer_src_as primitive adds useful insight in understanding where traffic enters
+the observed routing domain; but asymmetric routing impacts accuracy delivered by
+devices configured with either NetFlow or sFlow and the peer-as feature (as it only
+performs a reverse lookup, ie. a lookup on the source IP address, in the BGP table
+hence saying where it would route such traffic). pmacct offers a few ways to perform
+some mapping to tackle this issue and easily model both private and public peerings,
+both bi-lateral or multi-lateral. Find below how to use a map, reloadable at runtime,
+and its contents (for full syntax guide lines, please see the 'peers.map.example'
+file within the examples section):
+
+bgp_peer_src_as_type: map
+bgp_peer_src_as_map: /path/to/peers.map
+
+[/path/to/peers.map]
+id=12345 ip=1.2.3.4 in=10 bgp_nexthop=3.4.5.6
+id=34567 ip=1.2.3.4 in=10
+
+id=45678 ip=2.3.4.5 in=20 src_mac=00:11:22:33:44:55
+id=56789 ip=2.3.4.5 in=20 src_mac=00:22:33:44:55:66
+
+Even though all this mapping is static, it can be auto-provisioned to a good degree
+by means of external scripts running at regular intervals and, for example, querying
+relevant routers via SNMP. In this sense, the bgpPeerTable MIB is a good starting
+point. Alternatively pmacct also offers the option to perform reverse BGP lookups.
+
+NOTES:
+* When mapping, the peer_src_as primitive doesn't really apply to egress NetFlow
+ (or egress sFlow) as it mainly relies on either the input interface index
+ (ifIndex), the source MAC address, a reverse BGP next-hop lookup or a combination
+ of these.
+* "Source" MED, local preference, communities and AS-PATH have all been dedicated an
+ aggregation primitives. Each carries its own peculiarities but the general concepts
+ highlighed in this paragraph apply to these aswell. Check CONFIG-KEYS out for the
+ src_[med|local_pref|as_path|std_comm|ext_comm]_[type|map] configuration directives.
+
+XIIc. Tracking entities on the own IP address space
+It might happen that not all entities attached to the service provider network are
+speaking BGP but rather they get IP prefixes redistributed into iBGP (different
+routing protocols, statics, directly connected, etc.). These can be private IP
+addresses or segments of the SP address space. The common factor to all of them is
+that while being present in iBGP, these prefixes can't be tracked any further due
+to the lack of attributes like AS-PATH or an ASN. To overcome this situation the
+simplest approach is to employ a bgp_peer_src_as_map directive, described previously
+(ie. making use of interface descriptions as a possible way to automate the process).
+Alterntively, the bgp_stdcomm_pattern_to_asn directive was developed to fit into
+this scenario: assuming procedures of a SP are (or can be changed) to label every
+relevant non-BGP speaking entity IP prefixes uniquely with a BGP standard community,
+this directive allows to map the community to a peer AS/origin AS couple as per the
+following example: XXXXX:YYYYY => Peer-AS=XXXXX, Origin-AS=YYYYY.
+
+
+XIId. Preparing the router to BGP peer
+Once the collector is configured and started up the remaining step is to let routers
+to export traffic samples to the collector and BGP peer with it. Configuring the same
+source IP address across both NetFlow and BGP features allows the pmacct collector to
+perform the required correlations. Also, setting the BGP Router ID accordingly allows
+for more clear log messages. It's adviceable to configure the collector at the routers
+as a Route-Reflector (RR) client.
+
+A relevant configuration example for a Cisco router follows:
+
+ip flow-export source Loopback12345
+ip flow-export version 5
+ip flow-export destination X.X.X.X 2100
+!
+router bgp 12345
+ neighbor X.X.X.X remote-as 12345
+ neighbor X.X.X.X update-source Loopback12345
+ neighbor X.X.X.X version 4
+ neighbor X.X.X.X send-community
+ neighbor X.X.X.X route-reflector-client
+ neighbor X.X.X.X description nfacctd
+
+A relevant configuration example for a Juniper router follows:
+
+forwarding-options {
+ sampling {
+ output {
+ cflowd X.X.X.X {
+ port 2100;
+ source-address Y.Y.Y.Y;
+ version 5;
+ }
+ }
+ }
+}
+protocols bgp {
+ group rr-netflow {
+ type internal;
+ local-address Y.Y.Y.Y;
+ family inet {
+ any;
+ }
+ cluster Y.Y.Y.Y;
+ neighbor X.X.X.X {
+ description "nfacctd";
+ }
+ }
+}
+
+XIIe. A working configuration example writing to a MySQL database
+The following setup is a realistic example for a MPLS-enabled IP carrier network
+divided in multiple BGP clusters. Samples are aggregated in a way which is suitable
+to get an overview of traffic trajectories, collecting much information where these
+enter the AS and where they get out.
+
+daemonize: true
+nfacctd_port: 2100
+nfacctd_time_new: true
+
+plugins: mysql[5mins], mysql[hourly]
+
+sql_optimize_clauses: true
+sql_dont_try_update: true
+sql_multi_values: 1024000
+
+sql_history_roundoff[5mins]: m
+sql_history[5mins]: 5m
+sql_refresh_time[5mins]: 300
+sql_table[5mins]: acct_bgp_5mins
+
+sql_history_roundoff[hourly]: h
+sql_history[hourly]: 1h
+sql_refresh_time[hourly]: 3600
+sql_table[hourly]: acct_bgp_1hr
+
+bgp_daemon: true
+bgp_daemon_ip: X.X.X.X
+bgp_daemon_max_peers: 100
+bgp_aspath_radius: 3
+bgp_follow_default: 1
+nfacctd_as_new: bgp
+bgp_peer_src_as_type: map
+bgp_peer_src_as_map: /path/to/peers.map
+
+plugin_buffer_size: 10240
+plugin_pipe_size: 1024000
+aggregate: tag, src_as, dst_as, peer_src_as, peer_dst_as, peer_src_ip, peer_dst_ip, local_pref, as_path
+
+pre_tag_map: /path/to/pretag.map
+refresh_maps: true
+pre_tag_map_entries: 3840
+
+The content of the maps (bgp_peer_src_as_map, pre_tag_map) is meant to be pretty
+standard and will not be shown. As it can be grasped from the above configuration,
+the SQL schema was customized. Below a suggestion on how this can be modified for
+more efficiency - with additional INDEXes, to speed up specific queries response
+time, remaining to be worked out:
+
+create table acct_bgp_5mins (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
+ agent_id INT(4) UNSIGNED NOT NULL,
+ as_src INT(4) UNSIGNED NOT NULL,
+ as_dst INT(4) UNSIGNED NOT NULL,
+ peer_as_src INT(4) UNSIGNED NOT NULL,
+ peer_as_dst INT(4) UNSIGNED NOT NULL,
+ peer_ip_src CHAR(15) NOT NULL,
+ peer_ip_dst CHAR(15) NOT NULL,
+ as_path CHAR(21) NOT NULL,
+ local_pref INT(4) UNSIGNED NOT NULL,
+ packets INT UNSIGNED NOT NULL,
+ bytes BIGINT UNSIGNED NOT NULL,
+ stamp_inserted DATETIME NOT NULL,
+ stamp_updated DATETIME,
+ PRIMARY KEY (id),
+ INDEX ...
+) TYPE=MyISAM AUTO_INCREMENT=1;
+
+create table acct_bgp_1hr (
+ id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT,
+ agent_id INT(4) UNSIGNED NOT NULL,
+ as_src INT(4) UNSIGNED NOT NULL,
+ as_dst INT(4) UNSIGNED NOT NULL,
+ peer_as_src INT(4) UNSIGNED NOT NULL,
+ peer_as_dst INT(4) UNSIGNED NOT NULL,
+ peer_ip_src CHAR(15) NOT NULL,
+ peer_ip_dst CHAR(15) NOT NULL,
+ as_path CHAR(21) NOT NULL,
+ local_pref INT(4) UNSIGNED NOT NULL,
+ packets INT UNSIGNED NOT NULL,
+ bytes BIGINT UNSIGNED NOT NULL,
+ stamp_inserted DATETIME NOT NULL,
+ stamp_updated DATETIME,
+ PRIMARY KEY (id),
+ INDEX ...
+) TYPE=MyISAM AUTO_INCREMENT=1;
+
+XIIf. BGP daemon implementation concluding notes
+The implementation supports both 4-bytes ASN and IPv6 (MP-BGP); IPv6 peers are not
+supported yet though. When storing data via SQL, BGP primitives can be freely mix-
+and-matched with other primitives (ie. L2/L3/L4) when customizing the SQL table
+(sql_optimize_clauses: true). Environments making use of BGP Multi-Path are not
+currently supported; if you are using this and would like to see it implemented,
+please get in touch. TCP MD5 signature for BGP messages is not yet supported but
+on the radar. For a review of all the configurable knobs and features see the
+CONFIG-KEYS document.
+
+
+XIII. Quickstart guide to setup a NetFlow/sFlow replicator
+pmacct 0.12 (>= 0.12.2) includes a new 'tee' plugin which is meant to replicate
+NetFlow/sFlow data to N remote collectors. The plugin can also act transparently
+by preserving the original IP address of the datagrams.
+Setting up a replicator is very easy. All is needed is where to listen to for
+incoming packets, where to replicate them to and optionally a filtering layer,
+if required. Filtering bases on the standard pre_tag_map infrastructure; only
+coarse-grained filtering against original source IP address is possible.
+
+nfacctd_port: 2100
+nfacctd_ip: X.X.X.X
+
+plugins: tee[a], tee[b]
+tee_receiver[a]: Y.Y.Y.Y:2100
+tee_receiver[b]: Z.Z.Z.Z:2100
+! tee_transparent: true
+
+! pre_tag_map: /path/to/pretag.map
+! pre_tag_filter[b]: 0
+
+plugin_buffer_size: 10240
+plugin_pipe_size: 1024000
+
+The pre_tag_filter in the above configuration snapshot applies only to the 'tee'
+plugin instance 'b' and filters out any NetFlow/sFlow packets marked with a non-
+zero 'id'. Plugin instance 'a' would normally receive all packets instead. An
+example of the pre_tag_map content follows:
+
+id=1 ip=A.A.A.A
+id=1 ip=B.B.B.B
+id=1 ip=C.C.C.C
+
+To enable the transparent mode, the tee_transparent should be commented out. It
+preserves the original IP address of the NetFlow/sFlow sender while replicating
+by essentially spoofing it. This feature is not global and can be freely enabled
+only on a subset of the active replicators. It requires super-user permissions
+in order to run.
+
+Concluding note: 'tee' plugin is not compatible with different plugins - within
+the same daemon instance. So if in the need of using pmacct for both collecting
+and replicating data, two separate instances must be used (intuitively with the
+replicator instance feeding the collector one).
+
+
+XIV. Quickstart guide to setup the IS-IS daemon
+pmacct 0.14.0 integrates an IS-IS daemon into the IP accounting collectors part
+of the toolset. Such daemon is run as a thread within the collector core process.
+The idea is to receive data-plane information, ie. via NetFlow, sFlow, etc., and
+control-plane information via IS-IS. Currently a single L2 P2P neighborship, ie.
+over a GRE tunnel, is supported. The daemon is currently used for the purpose of
+route resolution. A sample scenario could be that more specific internal routes
+might be configured to get summarized in BGP while crossing cluster boundaries.
+
+Pre-requisite for the use of the IS-IS daemon is that the pmacct package has to
+be configured for compilation with threads, this line will do it:
+
+./configure --enable-threads
+
+XIVa. Preparing the collector for the L2 P2P IS-IS neighborship
+It's assumed the collector sits on an Ethernet segment and has not direct link
+(L2) connectivity to an IS-IS speaker, hence the need to establish a GRE tunnel.
+While extensive literature and OS specific examples exist on the topic, a brief
+example for Linux, consistent with rest of the chapter, is provided below:
+
+ip tunnel add gre2 mode gre remote 10.0.1.2 local 10.0.1.1 ttl 255
+ip link set gre2 up
+
+The following configuration fragment is sufficient to set up an IS-IS daemon
+which will bind to a network interface gre2 configured with IP address 10.0.1.1
+in an IS-IS area 49.0001 and a CLNS MTU set to 1400:
+
+isis_daemon: true
+isis_daemon_ip: 10.0.1.1
+isis_daemon_net: 49.0001.0100.0000.1001.00
+isis_daemon_iface: gre2
+isis_daemon_mtu: 1400
+! isis_daemon_msglog: true
+
+XIVb. Preparing the router for the L2 P2P IS-IS neighborship
+Once the collector is ready, the remaining step is to configure a remote router
+for the L2 P2P IS-IS neighborship. The following bit of configuration (based on
+Cisco IOS) will match the above fragment of configuration for the IS-IS daemon:
+
+interface Tunnel0
+ ip address 10.0.1.2 255.255.255.252
+ ip router isis
+ tunnel source FastEthernet0
+ tunnel destination XXX.XXX.XXX.XXX
+ clns mtu 1400
+ isis metric 1000
+!
+router isis
+ net 49.0001.0100.0000.1002.00
+ is-type level-2-only
+ metric-style wide
+ log-adjacency-changes
+ passive-interface Loopback0
+!
+
+
+XV. Running the print plugin to write to flat-files
+Print plugin was originally conceived to display data on standard output; with
+pmacct 0.14 a new 'print_output_file' configuration directive is introduced to
+allow the plugin to write to flat-files aswell. Dynamic filenames are supported.
+Output is text-based (no binary proprietary format) and can be either CSV or
+formatted ('print_output' directive). When to write to disk can be configured
+via the 'print_refresh_time' directive. An example follows on how to write to
+files on a 15 mins basis in CSV format:
+
+print_refresh_time: 900
+print_output: csv
+print_output_file: /path/to/file-%Y%m%d-%H%M.txt
+print_time_roundoff: m
+
+Which, over time, would produce a would produce a series of files as follows:
+
+-rw------- 1 paolo paolo 2067 Nov 21 00:15 blabla-20111121-0000.txt
+-rw------- 1 paolo paolo 2772 Nov 21 00:30 blabla-20111121-0015.txt
+-rw------- 1 paolo paolo 1916 Nov 21 00:45 blabla-20111121-0030.txt
+-rw------- 1 paolo paolo 2940 Nov 21 01:00 blabla-20111121-0045.txt
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/README
^
|
@@ -6,7 +6,7 @@
- Distribution tarball:
* ChangeLog: History of features version by version
* CONFIG-KEYS: Available configuration directives explained
- * EXAMPLES: Examples, command-lines, quickstart guides
+ * QUICKSTART: Examples, command-lines, quickstart guides
* FAQS: FAQ document
* INSTALL: basic installation guide
* docs/: Miscellaneous internals, UNIX signals, SQL triggers documents
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/configure
^
|
@@ -733,7 +733,7 @@
PACKAGE=pmacctd
-VERSION=0.14.0
+VERSION=0.14.1
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
{ echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/configure.in
^
|
@@ -1,8 +1,8 @@
dnl Process this file with autoconf to produce a configure script.
dnl configuration file for pmacct
-AC_INIT([src/pmacctd.c], [0.14.0], [paolo@pmacct.net])
-AM_INIT_AUTOMAKE([pmacctd], [0.14.0])
+AC_INIT([src/pmacctd.c], [0.14.1], [paolo@pmacct.net])
+AM_INIT_AUTOMAKE([pmacctd], [0.14.1])
AC_PREFIX_DEFAULT([/usr/local])
dnl Checks for programs.
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/examples/agent_to_peer.map.example
^
|
@@ -4,7 +4,7 @@
! File syntax is key-based. Read full syntax rules in 'pretag.map.example' in
! this same directory.
!
-! nfacctd, sfacctd: valid keys: id, ip.
+! All daemons valid keys: id, ip, filter.
!
! list of currently supported keys follow:
!
@@ -13,6 +13,11 @@
! of the device which is originating NetFlow packets; in
! sfacctd this is compared against the AgentId field of
! received sFlow samples.
+! 'filter' Matches incoming packets against the supplied filter
+! expression (expected in libpcap syntax); the filter
+! needs to be enclosed in quotes ('). In this map this
+! is meant to discriminate among IPv4 ('ip') and IPv6
+! ('ip6') traffic.
!
! A couple of straightforward examples follow.
!
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/sql/pmacct-create-table_bgp_v1.pgsql
^
|
@@ -19,7 +19,7 @@
med BIGINT NOT NULL DEFAULT 0,
packets INT NOT NULL,
bytes BIGINT NOT NULL,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_bgp_pk PRIMARY KEY (agent_id, as_src, as_dst, peer_as_src, peer_as_dst, peer_ip_src, peer_ip_dst, comms, as_path, local_pref, med, stamp_inserted)
);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/sql/pmacct-create-table_v2.pgsql
^
|
@@ -17,7 +17,7 @@
ip_proto SMALLINT NOT NULL DEFAULT 0,
packets INT NOT NULL,
bytes BIGINT NOT NULL,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_uni_v2_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, stamp_inserted)
);
@@ -35,7 +35,7 @@
ip_proto SMALLINT NOT NULL DEFAULT 0,
packets INT NOT NULL,
bytes BIGINT NOT NULL,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_v2_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, stamp_inserted)
);
@@ -53,7 +53,7 @@
ip_proto SMALLINT NOT NULL DEFAULT 0,
packets INT NOT NULL,
bytes BIGINT NOT NULL,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_as_v2_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, stamp_inserted)
);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/sql/pmacct-create-table_v3.pgsql
^
|
@@ -18,7 +18,7 @@
tos INT NOT NULL DEFAULT 0,
packets INT NOT NULL,
bytes BIGINT NOT NULL,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_uni_v3_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
@@ -37,7 +37,7 @@
tos INT NOT NULL DEFAULT 0,
packets INT NOT NULL,
bytes BIGINT NOT NULL,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_v3_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
@@ -56,7 +56,7 @@
tos INT NOT NULL DEFAULT 0,
packets INT NOT NULL,
bytes BIGINT NOT NULL,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_as_v3_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/sql/pmacct-create-table_v4.pgsql
^
|
@@ -19,7 +19,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_uni_v4_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
@@ -39,7 +39,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_v4_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
@@ -59,7 +59,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_as_v4_pk PRIMARY KEY (agent_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/sql/pmacct-create-table_v5.pgsql
^
|
@@ -20,7 +20,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_uni_v5_pk PRIMARY KEY (agent_id, class_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
@@ -41,7 +41,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_v5_pk PRIMARY KEY (agent_id, class_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
@@ -62,7 +62,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_as_v5_pk PRIMARY KEY (agent_id, class_id, mac_src, mac_dst, vlan, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/sql/pmacct-create-table_v6.pgsql
^
|
@@ -22,7 +22,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_v6_pk PRIMARY KEY (agent_id, class_id, mac_src, mac_dst, vlan, as_src, as_dst, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/sql/pmacct-create-table_v7.pgsql
^
|
@@ -23,7 +23,7 @@
packets INT NOT NULL,
bytes BIGINT NOT NULL,
flows INT NOT NULL DEFAULT 0,
- stamp_inserted timestamp without time zone NOT NULL DEFAULT '0000-01-01 00:00:00',
+ stamp_inserted timestamp without time zone NOT NULL DEFAULT '0001-01-01 00:00:00',
stamp_updated timestamp without time zone,
CONSTRAINT acct_v7_pk PRIMARY KEY (agent_id, class_id, mac_src, mac_dst, vlan, as_src, as_dst, ip_src, ip_dst, port_src, port_dst, ip_proto, tos, stamp_inserted)
);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/addr.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2010 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -232,6 +232,18 @@
ptrd[chunk] = ptrs[chunk];
}
+/*
+ * ip6_addr_32bit_cpy(): copy of arbitrary 32bit IPv6 address chunks
+ */
+void ip6_addr_32bit_cpy(void *dst, void *src, int dstart, int sstart, int send)
+{
+ register u_int32_t *ptrs = src, *ptrd = dst;
+ int schunk, dchunk;
+
+ for (schunk = sstart, dchunk = dstart; schunk <= send; schunk++, dchunk++)
+ ptrd[dchunk] = ptrs[schunk];
+}
+
void etheraddr_string(const u_char *ep, char *buf)
{
u_int i, j;
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/addr.h
^
|
@@ -23,6 +23,7 @@
EXT u_int64_t pm_ntohll(u_int64_t);
EXT unsigned int ip6_addr_cmp(void *, void *);
EXT void ip6_addr_cpy(void *, void *);
+EXT void ip6_addr_32bit_cpy(void *, void *, int, int, int);
EXT void etheraddr_string(const u_char *, char *);
EXT int string_etheraddr(const u_char *, char *);
EXT int is_multicast(struct host_addr *);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/bgp/bgp.c
^
|
@@ -337,7 +337,7 @@
}
else {
if (peer->buf.len > BGP_MAX_PACKET_SIZE) {
- realloc(peer->buf.base, BGP_MAX_PACKET_SIZE);
+ peer->buf.base = realloc(peer->buf.base, BGP_MAX_PACKET_SIZE);
memset(peer->buf.base, 0, BGP_MAX_PACKET_SIZE);
peer->buf.len = BGP_MAX_PACKET_SIZE;
}
@@ -1562,10 +1562,10 @@
return key;
}
-int attrhash_cmp(void *p1,void *p2)
+int attrhash_cmp(const void *p1, const void *p2)
{
- struct bgp_attr *attr1 = p1;
- struct bgp_attr *attr2 = p2;
+ const struct bgp_attr *attr1 = (const struct bgp_attr *)p1;
+ const struct bgp_attr *attr2 = (const struct bgp_attr *)p2;
if (attr1->flag == attr2->flag
&& attr1->origin == attr2->origin
@@ -1896,7 +1896,7 @@
#if defined ENABLE_IPV6
struct in6_addr pref6;
#endif
- u_int32_t modulo;
+ u_int32_t modulo, peer_idx, *peer_idx_ptr;
safi_t safi;
rd_t rd;
@@ -1910,20 +1910,44 @@
if (pptrs->bta) {
sa = &sa_local;
- sa->sa_family = AF_INET;
- ((struct sockaddr_in *)sa)->sin_addr.s_addr = pptrs->bta;
+ if (pptrs->bta_af == ETHERTYPE_IP) {
+ sa->sa_family = AF_INET;
+ ((struct sockaddr_in *)sa)->sin_addr.s_addr = pptrs->bta;
+ }
+#if defined ENABLE_IPV6
+ else if (pptrs->bta_af == ETHERTYPE_IPV6) {
+ sa->sa_family = AF_INET6;
+ ip6_addr_32bit_cpy(&((struct sockaddr_in6 *)sa)->sin6_addr, &pptrs->bta, 0, 0, 1);
+ ip6_addr_32bit_cpy(&((struct sockaddr_in6 *)sa)->sin6_addr, &pptrs->bta2, 2, 0, 1);
+ }
+#endif
}
start_again:
- if (xs_entry && xs_entry->peer_idx) {
- if (!sa_addr_cmp(sa, &peers[xs_entry->peer_idx].addr) || !sa_addr_cmp(sa, &peers[xs_entry->peer_idx].id)) {
- peer = &peers[xs_entry->peer_idx];
- pptrs->bgp_peer = (char *) &peers[xs_entry->peer_idx];
+ peer_idx = 0; peer_idx_ptr = NULL;
+ if (xs_entry) {
+ if (pptrs->l3_proto == ETHERTYPE_IP) {
+ peer_idx = xs_entry->peer_v4_idx;
+ peer_idx_ptr = &xs_entry->peer_v4_idx;
+ }
+#if defined ENABLE_IPV6
+ else if (pptrs->l3_proto == ETHERTYPE_IPV6) {
+ peer_idx = xs_entry->peer_v6_idx;
+ peer_idx_ptr = &xs_entry->peer_v6_idx;
+ }
+#endif
+ }
+
+
+ if (xs_entry && peer_idx) {
+ if (!sa_addr_cmp(sa, &peers[peer_idx].addr) || !sa_addr_cmp(sa, &peers[peer_idx].id)) {
+ peer = &peers[peer_idx];
+ pptrs->bgp_peer = (char *) &peers[peer_idx];
}
/* If no match then let's invalidate the entry */
else {
- xs_entry->peer_idx = 0;
+ *peer_idx_ptr = 0;
peer = NULL;
}
}
@@ -1932,7 +1956,7 @@
if (!sa_addr_cmp(sa, &peers[peers_idx].addr) || !sa_addr_cmp(sa, &peers[peers_idx].id)) {
peer = &peers[peers_idx];
pptrs->bgp_peer = (char *) &peers[peers_idx];
- if (xs_entry) xs_entry->peer_idx = peers_idx;
+ if (xs_entry && peer_idx_ptr) *peer_idx_ptr = peers_idx;
break;
}
}
@@ -2118,7 +2142,7 @@
sa = &sa_local;
memset(sa, 0, sizeof(struct sockaddr));
sa->sa_family = AF_INET6;
- memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr, &info->attr->mp_nexthop.address.ipv6, 16);
+ ip6_addr_cpy(&((struct sockaddr_in6 *)sa)->sin6_addr, &info->attr->mp_nexthop.address.ipv6);
goto start_again;
}
#endif
@@ -2247,7 +2271,7 @@
pptrs->f_agent = (char *) &sa_local;
memset(sa, 0, sizeof(struct sockaddr));
sa->sa_family = AF_INET6;
- memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr, &info->attr->mp_nexthop.address.ipv6, 16);
+ ip6_addr_cpy(&((struct sockaddr_in6 *)sa)->sin6_addr, &info->attr->mp_nexthop.address.ipv6);
saved_info = (char *) info;
ttl--;
goto start_again;
@@ -2291,7 +2315,7 @@
{
FILE *file;
char neighbor[INET6_ADDRSTRLEN+1];
- int idx, len;
+ int idx, len, ret;
uid_t owner = -1;
gid_t group = -1;
@@ -2302,7 +2326,7 @@
file = fopen(filename,"w");
if (file) {
- if (chown(filename, owner, group) == -1)
+ if ((ret = chown(filename, owner, group)) == -1)
Log(LOG_WARNING, "WARN: Unable to chown() '%s': %s\n", filename, strerror(errno));
if (file_lock(fileno(file))) {
@@ -2318,7 +2342,15 @@
neighbor[len] = '\0';
fwrite(neighbor, len, 1, file);
}
- /* we don't happen to support IPv6 neighbors just yet */
+#if defined ENABLE_IPV6
+ else if (peers[idx].addr.family == AF_INET6) {
+ inet_ntop(AF_INET6, &peers[idx].addr.address.ipv6, neighbor, INET6_ADDRSTRLEN);
+ len = strlen(neighbor);
+ neighbor[len] = '\n'; len++;
+ neighbor[len] = '\0';
+ fwrite(neighbor, len, 1, file);
+ }
+#endif
}
}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/bgp/bgp.h
^
|
@@ -178,7 +178,6 @@
EXT void load_comm_patterns(char **, char **, char **);
EXT void load_peer_src_as_comm_ranges(char *, char *);
EXT void evaluate_comm_patterns(char *, char *, char **, int);
-//EXT as_t evaluate_last_asn(char *);
EXT as_t evaluate_last_asn(struct aspath *);
EXT as_t evaluate_first_asn(char *);
EXT void bgp_srcdst_lookup(struct packet_ptrs *);
@@ -187,7 +186,7 @@
EXT void process_bgp_md5_file(int, struct bgp_md5_table *);
EXT unsigned int attrhash_key_make(void *);
-EXT int attrhash_cmp(void *, void *);
+EXT int attrhash_cmp(const void *, const void *);
EXT void attrhash_init();
EXT void cache_to_pkt_bgp_primitives(struct pkt_bgp_primitives *, struct cache_bgp_primitives *);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/imt_plugin.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -35,7 +35,6 @@
struct sockaddr cAddr;
struct pkt_data *data;
struct ports_table pt;
- struct timezone tz;
unsigned char srvbuf[maxqsize];
unsigned char *srvbufptr;
struct query_header *qh;
@@ -174,7 +173,7 @@
num = select(select_fd, &read_descs, NULL, NULL, NULL);
if (num < 0) goto select_again;
- gettimeofday(&cycle_stamp, &tz);
+ gettimeofday(&cycle_stamp, NULL);
/* doing server tasks */
if (FD_ISSET(sd, &read_descs)) {
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/ip_flow.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2009 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -79,9 +79,8 @@
void ip_flow_handler(struct packet_ptrs *pptrs)
{
struct timeval now;
- struct timezone tz;
- gettimeofday(&now, &tz);
+ gettimeofday(&now, NULL);
if (now.tv_sec > flt_prune_deadline) {
prune_old_flows(&now);
@@ -420,9 +419,8 @@
void ip_flow6_handler(struct packet_ptrs *pptrs)
{
struct timeval now;
- struct timezone tz;
- gettimeofday(&now, &tz);
+ gettimeofday(&now, NULL);
if (now.tv_sec > flt6_prune_deadline) {
prune_old_flows6(&now);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/isis/sockunion.c
^
|
@@ -596,45 +596,6 @@
return NULL;
}
-/* Print sockunion structure */
-static void __attribute__ ((unused))
-sockunion_print (union sockunion *su)
-{
- if (su == NULL)
- return;
-
- switch (su->sa.sa_family)
- {
- case AF_INET:
- printf ("%s\n", inet_ntoa (su->sin.sin_addr));
- break;
-#ifdef ENABLE_IPV6
- case AF_INET6:
- {
- char buf [SU_ADDRSTRLEN];
-
- printf ("%s\n", inet_ntop (AF_INET6, &(su->sin6.sin6_addr),
- buf, sizeof (buf)));
- }
- break;
-#endif /* ENABLE_IPV6 */
-
-#ifdef AF_LINK
- case AF_LINK:
- {
- struct sockaddr_dl *sdl;
-
- sdl = (struct sockaddr_dl *)&(su->sa);
- printf ("link#%d\n", sdl->sdl_index);
- }
- break;
-#endif /* AF_LINK */
- default:
- printf ("af_unknown %d\n", su->sa.sa_family);
- break;
- }
-}
-
#ifdef ENABLE_IPV6
static int
in6addr_cmp (struct in6_addr *addr1, struct in6_addr *addr2)
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/mysql_plugin.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -36,7 +36,6 @@
struct ports_table pt;
struct pollfd pfd;
struct insert_data idata;
- struct timezone tz;
time_t refresh_deadline;
int timeout;
int ret, num;
@@ -145,7 +144,7 @@
exit(0);
default: /* Parent */
if (pqq_ptr) sql_cache_flush_pending(pending_queries_queue, pqq_ptr, &idata);
- gettimeofday(&idata.flushtime, &tz);
+ gettimeofday(&idata.flushtime, NULL);
while (idata.now > refresh_deadline)
refresh_deadline += config.sql_refresh_time;
while (idata.now > idata.triggertime && idata.t_timeslot > 0) {
@@ -227,7 +226,7 @@
exit(0);
default: /* Parent */
if (pqq_ptr) sql_cache_flush_pending(pending_queries_queue, pqq_ptr, &idata);
- gettimeofday(&idata.flushtime, &tz);
+ gettimeofday(&idata.flushtime, NULL);
while (idata.now > refresh_deadline)
refresh_deadline += config.sql_refresh_time;
while (idata.now > idata.triggertime && idata.t_timeslot > 0) {
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/net_aggr.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -667,7 +667,7 @@
else if (p->src_ip.family == AF_INET6) {
res6 = binsearch6(nt, nc, &p->src_ip);
if (!res6) p->src_nmask = 0;
- else p->src_nmask = res->masknum;
+ else p->src_nmask = res6->masknum;
}
#endif
}
@@ -688,7 +688,7 @@
else if (p->dst_ip.family == AF_INET6) {
res6 = binsearch6(nt, nc, &p->dst_ip);
if (!res6) p->dst_nmask = 0;
- else p->dst_nmask = res->masknum;
+ else p->dst_nmask = res6->masknum;
}
#endif
}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/network.h
^
|
@@ -271,6 +271,7 @@
u_char *f_data; /* ptr to NetFlow data */
u_char *f_tpl; /* ptr to NetFlow V9 template */
u_char *f_status; /* ptr to status table entry */
+ u_char *f_status_g; /* ptr to status table entry. global per f_agent */
u_char *idtable; /* ptr to pretag table map */
u_char *bpas_table; /* ptr to bgp_peer_as_src table map */
u_char *blp_table; /* ptr to bgp_src_local_pref table map */
@@ -288,7 +289,9 @@
pm_id_t bpas; /* bgp_peer_as_src */
pm_id_t blp; /* bgp_src_local_pref */
pm_id_t bmed; /* bgp_src_med */
+ u_int16_t bta_af; /* bgp_to_agent address family */
pm_id_t bta; /* bgp_to_agent */
+ pm_id_t bta2; /* bgp_to_agent (cont.d: 64bits more for IPv6 addresses) */
pm_id_t bitr; /* bgp_iface_to_rd */
pm_id_t st; /* sampling_map */
char *bgp_src; /* pointer to bgp_node structure for source prefix, if any */
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/nfacctd.c
^
|
@@ -77,7 +77,7 @@
printf(" -r \tRefresh time (in seconds)\n");
printf(" -O \t[ formatted | csv ] \n\tOutput format\n");
printf("\n");
- printf(" See EXAMPLES or visit http://wiki.pmacct.net/ for examples.\n");
+ printf(" See QUICKSTART or visit http://wiki.pmacct.net/ for examples.\n");
printf("\n");
printf("For suggestions, critics, bugs, contact me: %s.\n", MANTAINER);
}
@@ -152,6 +152,8 @@
biss_map_allocated = FALSE;
bta_map_allocated = FALSE;
bitr_map_allocated = FALSE;
+ bta_map_caching = TRUE;
+ sampling_map_caching = TRUE;
find_id_func = NF_find_id;
data_plugins = 0;
@@ -178,6 +180,7 @@
memset(&bta_table, 0, sizeof(bta_table));
memset(&bitr_table, 0, sizeof(bitr_table));
memset(&sampling_table, 0, sizeof(sampling_table));
+ memset(&reload_map_tstamp, 0, sizeof(reload_map_tstamp));
config.acct_type = ACCT_NF;
rows = 0;
@@ -771,7 +774,11 @@
if (!allowed) continue;
if (reload_map) {
+ bta_map_caching = TRUE;
+ sampling_map_caching = TRUE;
+
load_networks(config.networks_file, &nt, &nc);
+
if (config.nfacctd_bgp && config.nfacctd_bgp_peer_as_src_map)
load_id_file(MAP_BGP_PEER_AS_SRC, config.nfacctd_bgp_peer_as_src_map, &bpas_table, &req, &bpas_map_allocated);
if (config.nfacctd_bgp && config.nfacctd_bgp_src_local_pref_map)
@@ -788,7 +795,9 @@
load_id_file(MAP_SAMPLING, config.sampling_map, &sampling_table, &req, &sampling_map_allocated);
set_sampling_table(&pptrs, (u_char *) &sampling_table);
}
+
reload_map = FALSE;
+ gettimeofday(&reload_map_tstamp, NULL);
}
if (data_plugins) {
@@ -862,7 +871,7 @@
/* IP header's id field is unused; we will use it to transport our id */
if (config.nfacctd_isis) isis_srcdst_lookup(pptrs);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, &pptrs->bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, pptrs, &pptrs->bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(pptrs);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, pptrs, &pptrs->bpas, NULL);
@@ -897,6 +906,7 @@
pkt += NfHdrV5Sz;
exp_v5 = (struct struct_export_v5 *)pkt;
pptrs->f_status = nfv578_check_status(pptrs);
+ pptrs->f_status_g = NULL;
reset_mac(pptrs);
@@ -924,7 +934,7 @@
/* IP header's id field is unused; we will use it to transport our id */
if (config.nfacctd_isis) isis_srcdst_lookup(pptrs);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, &pptrs->bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, pptrs, &pptrs->bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(pptrs);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, pptrs, &pptrs->bpas, NULL);
@@ -959,6 +969,7 @@
pkt += NfHdrV7Sz;
exp_v7 = (struct struct_export_v7 *)pkt;
pptrs->f_status = nfv578_check_status(pptrs);
+ pptrs->f_status_g = NULL;
reset_mac(pptrs);
@@ -986,7 +997,7 @@
/* IP header's id field is unused; we will use it to transport our id */
if (config.nfacctd_isis) isis_srcdst_lookup(pptrs);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, &pptrs->bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, pptrs, &pptrs->bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(pptrs);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, pptrs, &pptrs->bpas, NULL);
@@ -1021,6 +1032,7 @@
pkt += NfHdrV8Sz;
exp_v8 = pkt;
pptrs->f_status = nfv578_check_status(pptrs);
+ pptrs->f_status_g = NULL;
reset_mac(pptrs);
reset_ip4(pptrs);
@@ -1036,7 +1048,7 @@
/* IP header's id field is unused; we will use it to transport our id */
if (config.nfacctd_isis) isis_srcdst_lookup(pptrs);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, &pptrs->bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, pptrs, &pptrs->bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(pptrs);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, pptrs, &pptrs->bpas, NULL);
@@ -1087,8 +1099,10 @@
pptrs->f_header = pkt;
pkt += HdrSz;
off += HdrSz;
- pptrsv->v4.f_status = nfv9_check_status(pptrs, SourceId, FlowSeq);
+ pptrsv->v4.f_status = nfv9_check_status(pptrs, SourceId, 0, FlowSeq, TRUE);
set_vector_f_status(pptrsv);
+ pptrsv->v4.f_status_g = nfv9_check_status(pptrs, 0, NF9_OPT_SCOPE_SYSTEM, 0, FALSE);
+ set_vector_f_status_g(pptrsv);
process_flowset:
if (off+NfDataHdrV9Sz >= len) {
@@ -1118,7 +1132,7 @@
return;
}
- handle_template_v9(template_hdr, pptrs, fid, SourceId, &pens);
+ handle_template(template_hdr, pptrs, fid, SourceId, &pens);
tpl_ptr += sizeof(struct template_hdr_v9)+(ntohs(template_hdr->num)*sizeof(struct template_field_v9))+(pens*sizeof(u_int32_t));
flowoff += sizeof(struct template_hdr_v9)+(ntohs(template_hdr->num)*sizeof(struct template_field_v9))+(pens*sizeof(u_int32_t));
@@ -1144,7 +1158,7 @@
return;
}
- handle_template_v9((struct template_hdr_v9 *)opt_template_hdr, pptrs, fid, SourceId, NULL);
+ handle_template((struct template_hdr_v9 *)opt_template_hdr, pptrs, fid, SourceId, NULL);
/* Increment is not precise for NetFlow v9 but will work */
tpl_ptr += sizeof(struct options_template_hdr_v9)+((ntohs(opt_template_hdr->scope_len)+ntohs(opt_template_hdr->option_len))*sizeof(struct template_field_v9));
@@ -1167,7 +1181,7 @@
pkt += NfDataHdrV9Sz;
flowoff += NfDataHdrV9Sz;
- tpl = find_template_v9(data_hdr->flow_id, pptrs, fid, SourceId);
+ tpl = find_template(data_hdr->flow_id, pptrs, fid, SourceId);
if (!tpl) {
struct host_addr a;
u_char agent_addr[50];
@@ -1222,6 +1236,9 @@
struct pkt_classifier css;
pm_class_t class_id = 0, class_int_id = 0;
+ /* Handling the global option scoping case */
+ if (tpl->tpl[NF9_OPT_SCOPE_SYSTEM].len) entry = (struct xflow_status_entry *) pptrs->f_status_g;
+
memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
if (entry) centry = search_class_id_status_table(entry->class, class_id);
@@ -1262,6 +1279,9 @@
}
else {
while (flowoff+tpl->len <= flowsetlen) {
+ /* Let's bake offsets and lengths if we have variable-length fields */
+ if (tpl->vlen) resolve_vlen_template(pkt, tpl);
+
pptrs->f_data = pkt;
pptrs->f_tpl = (u_char *) tpl;
reset_net_status_v(pptrsv);
@@ -1304,11 +1324,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrs->class = NF_evaluate_classifiers(entry->class, pptrs->f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrs->class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(pptrs);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, &pptrs->bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, pptrs, &pptrs->bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(pptrs);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, pptrs, &pptrs->bpas, NULL);
@@ -1356,11 +1379,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrsv->v6.class = NF_evaluate_classifiers(entry->class, pptrsv->v6.f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrsv->v6.class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->v6);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->v6, &pptrsv->v6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->v6, &pptrsv->v6.bta, &pptrsv->v6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->v6, &pptrsv->v6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->v6);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->v6, &pptrsv->v6.bpas, NULL);
@@ -1410,11 +1436,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrsv->vlan4.class = NF_evaluate_classifiers(entry->class, pptrsv->vlan4.f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrsv->vlan4.class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlan4);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan4, &pptrsv->vlan4.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan4, &pptrsv->vlan4.bta, &pptrsv->vlan4.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlan4, &pptrsv->vlan4.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlan4);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlan4, &pptrsv->vlan4.bpas, NULL);
@@ -1464,11 +1493,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrsv->vlan6.class = NF_evaluate_classifiers(entry->class, pptrsv->vlan6.f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrsv->vlan6.class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlan6);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan6, &pptrsv->vlan6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan6, &pptrsv->vlan6.bta, &pptrsv->vlan6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlan6, &pptrsv->vlan6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlan6);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlan6, &pptrsv->vlan6.bpas, NULL);
@@ -1528,11 +1560,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrsv->mpls4.class = NF_evaluate_classifiers(entry->class, pptrsv->mpls4.f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrsv->mpls4.class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->mpls4);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls4, &pptrsv->mpls4.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls4, &pptrsv->mpls4.bta, &pptrsv->mpls4.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->mpls4, &pptrsv->mpls4.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->mpls4);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->mpls4, &pptrsv->mpls4.bpas, NULL);
@@ -1591,11 +1626,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrsv->mpls6.class = NF_evaluate_classifiers(entry->class, pptrsv->mpls6.f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrsv->mpls6.class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->mpls6);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls6, &pptrsv->mpls6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls6, &pptrsv->mpls6.bta, &pptrsv->mpls6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->mpls6, &pptrsv->mpls6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->mpls6);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->mpls6, &pptrsv->mpls6.bpas, NULL);
@@ -1657,11 +1695,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrsv->vlanmpls4.class = NF_evaluate_classifiers(entry->class, pptrsv->vlanmpls4.f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrsv->vlanmpls4.class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlanmpls4);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bta, &pptrsv->vlanmpls4.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlanmpls4);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bpas, NULL);
@@ -1722,11 +1763,14 @@
if (tpl->tpl[NF9_APPLICATION_ID].len == 4) {
struct xflow_status_entry *entry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_entry *gentry = (struct xflow_status_entry *) pptrs->f_status_g;
+ pm_class_t class_id = 0;
- if (entry) pptrsv->vlanmpls6.class = NF_evaluate_classifiers(entry->class, pptrsv->vlanmpls6.f_data+tpl->tpl[NF9_APPLICATION_ID].off);
+ memcpy(&class_id, pkt+tpl->tpl[NF9_APPLICATION_ID].off, 4);
+ if (entry) pptrsv->vlanmpls6.class = NF_evaluate_classifiers(entry->class, &class_id, gentry);
}
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlanmpls6);
- if (config.nfacctd_bgp_to_agent_map) NF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bta, &pptrsv->vlanmpls6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) NF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlanmpls6);
if (config.nfacctd_bgp_peer_as_src_map) NF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bpas, NULL);
@@ -1930,13 +1974,13 @@
Log(severity, errstr);
}
-void NF_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
+int NF_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
{
int x, j, stop;
struct sockaddr *sa = (struct sockaddr *) pptrs->f_agent;
pm_id_t id;
- if (!t) return;
+ if (!t) return 0;
/* The id_table is shared between by IPv4 and IPv6 NetFlow agents.
IPv4 ones are in the lower part (0..x), IPv6 ones are in the upper
@@ -1960,6 +2004,11 @@
if (t->e[x].stack.func) id = (*t->e[x].stack.func)(id, *tag2);
*tag2 = id;
}
+ else if (stop == BTA_MAP_RCODE_ID_ID2) {
+ // stack not applicable here
+ *tag = id;
+ *tag2 = t->e[x].id2;
+ }
if (t->e[x].jeq.ptr) {
if (t->e[x].ret) {
@@ -1991,6 +2040,11 @@
if (t->e[x].stack.func) id = (*t->e[x].stack.func)(id, *tag2);
*tag2 = id;
}
+ else if (stop == BTA_MAP_RCODE_ID_ID2) {
+ // stack not applicable here
+ *tag = id;
+ *tag2 = t->e[x].id2;
+ }
if (t->e[x].jeq.ptr) {
if (t->e[x].ret) {
@@ -2010,6 +2064,8 @@
}
}
#endif
+
+ return stop;
}
char *nfv578_check_status(struct packet_ptrs *pptrs)
@@ -2021,7 +2077,7 @@
struct xflow_status_entry *entry = NULL;
if (hash >= 0) {
- entry = search_status_table(sa, aux1, hash, XFLOW_STATUS_TABLE_MAX_ENTRIES);
+ entry = search_status_table(sa, aux1, 0, hash, XFLOW_STATUS_TABLE_MAX_ENTRIES);
if (entry) {
update_status_table(entry, ntohl(hdr->flow_sequence));
entry->inc = ntohs(hdr->count);
@@ -2031,15 +2087,15 @@
return (char *) entry;
}
-char *nfv9_check_status(struct packet_ptrs *pptrs, u_int32_t sid, u_int32_t seq)
+char *nfv9_check_status(struct packet_ptrs *pptrs, u_int32_t sid, u_int32_t flags, u_int32_t seq, u_int8_t update)
{
struct sockaddr *sa = (struct sockaddr *) pptrs->f_agent;
int hash = hash_status_table(sid, sa, XFLOW_STATUS_TABLE_SZ);
struct xflow_status_entry *entry = NULL;
if (hash >= 0) {
- entry = search_status_table(sa, sid, hash, XFLOW_STATUS_TABLE_MAX_ENTRIES);
- if (entry) {
+ entry = search_status_table(sa, sid, flags, hash, XFLOW_STATUS_TABLE_MAX_ENTRIES);
+ if (entry && update) {
update_status_table(entry, seq);
entry->inc = 1;
}
@@ -2048,6 +2104,27 @@
return (char *) entry;
}
+pm_class_t NF_evaluate_classifiers(struct xflow_status_entry_class *entry, pm_class_t *class_id, struct xflow_status_entry *gentry)
+{
+ struct xflow_status_entry_class *centry;
+
+ /* Try #1: let's see if we have a matching class for the given SourceId/ObservedDomainId */
+ centry = search_class_id_status_table(entry, *class_id);
+ if (centry) {
+ return centry->class_int_id;
+ }
+
+ /* Try #2: let's chance if we have a global option */
+ if (gentry) {
+ centry = search_class_id_status_table(gentry->class, *class_id);
+ if (centry) {
+ return centry->class_int_id;
+ }
+ }
+
+ return 0;
+}
+
/* Dummy objects here - ugly to see but well portable */
void SF_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
{
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/nfacctd.h
^
|
@@ -403,7 +403,8 @@
#define NF_TIME_SECS 1 /* times are in secs */
#define NF_TIME_NEW 2 /* ignore netflow engine times and generate new ones */
-#define IPFIX_TPL_EBIT 0x8000 /* IPFIX telmplate enterprise bit */
+#define IPFIX_TPL_EBIT 0x8000 /* IPFIX telmplate enterprise bit */
+#define IPFIX_VARIABLE_LENGTH 65535
/* NetFlow V9 stuff */
#define NF9_TEMPLATE_FLOWSET_ID 0
@@ -411,6 +412,12 @@
#define NF9_MIN_RECORD_FLOWSET_ID 256
#define NF9_MAX_DEFINED_FIELD 384
+#define IES_PER_TPL_EXT_DB_ENTRY 32
+#define TPL_EXT_DB_ENTRIES 8
+#define TPL_LIST_ENTRIES 256
+#define TPL_TYPE_LEGACY 0
+#define TPL_TYPE_EXT_DB 1
+
/* Flowset record types the we care about */
#define NF9_IN_BYTES 1
#define NF9_IN_PACKETS 2
@@ -490,11 +497,6 @@
#define NF9_CUST_TAG 201
#define NF9_CUST_TAG2 202
/* ... */
-#define NF9_XLATE_IPV4_SRC_ADDR 225
-#define NF9_XLATE_IPV4_DST_ADDR 226
-#define NF9_XLATE_L4_SRC_PORT 227
-#define NF9_XLATE_L4_DST_PORT 228
-/* ... */
#define NF9_ETHERTYPE 256
/* ... */
#define NF9_XLATE_IPV6_SRC_ADDR 281
@@ -650,17 +652,41 @@
struct otpl_field {
u_int16_t off;
u_int16_t len;
+ u_int16_t tpl_len;
+};
+
+/* Unsorted Template field */
+struct utpl_field {
+ u_int32_t pen;
+ u_int16_t type;
+ u_int16_t off;
+ u_int16_t len;
+ u_int16_t tpl_len;
+};
+
+/* Template field database */
+struct tpl_field_db {
+ struct utpl_field ie[IES_PER_TPL_EXT_DB_ENTRY];
+};
+
+/* Template field ordered list */
+struct tpl_field_list {
+ u_int8_t type;
+ char *ptr;
};
struct template_cache_entry {
- struct host_addr agent; /* NetFlow Exporter agent */
- u_int32_t source_id; /* Exporter Observation Domain */
- u_int16_t template_id; /* template ID */
- u_int16_t template_type; /* Data = 0, Options = 1 */
- u_int16_t num; /* number of fields described into template */
- u_int16_t len; /* total length of the described flowset */
+ struct host_addr agent; /* NetFlow Exporter agent */
+ u_int32_t source_id; /* Exporter Observation Domain */
+ u_int16_t template_id; /* template ID */
+ u_int16_t template_type; /* Data = 0, Options = 1 */
+ u_int16_t num; /* number of fields described into template */
+ u_int16_t len; /* total length of the described flowset */
+ u_int8_t vlen; /* flag for variable-length fields */
struct otpl_field tpl[NF9_MAX_DEFINED_FIELD];
- struct template_cache_entry *next;
+ struct tpl_field_db ext_db[TPL_EXT_DB_ENTRIES];
+ struct tpl_field_list list[TPL_LIST_ENTRIES];
+ struct template_cache_entry *next;
};
struct template_cache {
@@ -689,15 +715,16 @@
EXT void process_raw_packet(unsigned char *, u_int16_t, struct packet_ptrs_vector *, struct plugin_requests *);
EXT u_int16_t NF_evaluate_flow_type(struct template_cache_entry *, struct packet_ptrs *);
EXT u_int16_t NF_evaluate_direction(struct template_cache_entry *, struct packet_ptrs *);
+EXT pm_class_t NF_evaluate_classifiers(struct xflow_status_entry_class *, pm_class_t *, struct xflow_status_entry *);
EXT void reset_mac(struct packet_ptrs *);
EXT void reset_mac_vlan(struct packet_ptrs *);
EXT void reset_ip4(struct packet_ptrs *);
EXT void reset_ip6(struct packet_ptrs *);
EXT void notify_malf_packet(short int, char *, struct sockaddr *);
-EXT void NF_find_id(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
+EXT int NF_find_id(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
EXT char *nfv578_check_status(struct packet_ptrs *);
-EXT char *nfv9_check_status(struct packet_ptrs *, u_int32_t, u_int32_t);
+EXT char *nfv9_check_status(struct packet_ptrs *, u_int32_t, u_int32_t, u_int32_t, u_int8_t);
EXT struct template_cache tpl_cache;
EXT struct v8_handler_entry v8_handlers[15];
@@ -708,14 +735,17 @@
#else
#define EXT
#endif
-EXT void handle_template_v9(struct template_hdr_v9 *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int16_t *);
-EXT struct template_cache_entry *find_template_v9(u_int16_t, struct packet_ptrs *, u_int16_t, u_int32_t);
-EXT struct template_cache_entry *insert_template_v9(struct template_hdr_v9 *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int16_t *);
-EXT void refresh_template_v9(struct template_hdr_v9 *, struct template_cache_entry *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int16_t *);
-EXT void log_template_v9_header(struct template_cache_entry *, struct packet_ptrs *, u_int16_t, u_int32_t);
-EXT void log_opt_template_v9_field(u_int16_t, u_int16_t, u_int16_t);
-EXT void log_template_v9_field(u_int16_t, u_int16_t, u_int16_t);
-EXT void log_template_v9_footer(u_int16_t);
-EXT struct template_cache_entry *insert_opt_template_v9(void *, struct packet_ptrs *, u_int16_t, u_int32_t);
-EXT void refresh_opt_template_v9(void *, struct template_cache_entry *, struct packet_ptrs *, u_int16_t, u_int32_t);
+EXT void handle_template(struct template_hdr_v9 *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int16_t *);
+EXT struct template_cache_entry *find_template(u_int16_t, struct packet_ptrs *, u_int16_t, u_int32_t);
+EXT struct template_cache_entry *insert_template(struct template_hdr_v9 *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int16_t *, u_int8_t);
+EXT void refresh_template(struct template_hdr_v9 *, struct template_cache_entry *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int16_t *, u_int8_t);
+EXT void log_template_header(struct template_cache_entry *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int8_t);
+EXT void log_opt_template_field(u_int16_t, u_int16_t, u_int16_t, u_int8_t);
+EXT void log_template_field(u_int8_t, u_int32_t *, u_int16_t, u_int16_t, u_int16_t, u_int8_t);
+EXT void log_template_footer(u_int16_t, u_int8_t);
+EXT struct template_cache_entry *insert_opt_template(void *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int8_t);
+EXT void refresh_opt_template(void *, struct template_cache_entry *, struct packet_ptrs *, u_int16_t, u_int32_t, u_int8_t);
+
+EXT void resolve_vlen_template(char *, struct template_cache_entry *);
+EXT u_int8_t get_ipfix_vlen(char *, u_int16_t *);
#undef EXT
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/nfprobe_plugin/netflow9.c
^
|
@@ -29,7 +29,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* $Id: netflow9.c,v 1.22 2012/04/10 14:53:22 paolo Exp $ */
+/* $Id: netflow9.c,v 1.23 2012/04/23 16:31:49 paolo Exp $ */
#define __NFPROBE_NETFLOW9_C
@@ -201,16 +201,18 @@
static struct NF9_INTERNAL_TEMPLATE v4_int_template;
static struct NF9_SOFTFLOWD_TEMPLATE v4_template_out;
static struct NF9_INTERNAL_TEMPLATE v4_int_template_out;
+#if defined ENABLE_IPV6
static struct NF9_SOFTFLOWD_TEMPLATE v6_template;
static struct NF9_INTERNAL_TEMPLATE v6_int_template;
static struct NF9_SOFTFLOWD_TEMPLATE v6_template_out;
static struct NF9_INTERNAL_TEMPLATE v6_int_template_out;
+#endif
static struct NF9_OPTIONS_TEMPLATE sampling_option_template;
static struct NF9_INTERNAL_OPTIONS_TEMPLATE sampling_option_int_template;
static struct NF9_OPTIONS_TEMPLATE class_option_template;
static struct NF9_INTERNAL_OPTIONS_TEMPLATE class_option_int_template;
-static char ftoft_buf_0[sizeof(struct NF9_SOFTFLOWD_DATA_V6)];
-static char ftoft_buf_1[sizeof(struct NF9_SOFTFLOWD_DATA_V6)];
+static char ftoft_buf_0[NF9_SOFTFLOWD_MAX_PACKET_SIZE*2];
+static char ftoft_buf_1[NF9_SOFTFLOWD_MAX_PACKET_SIZE*2];
static int nf9_pkts_until_template = -1;
static u_int8_t send_options = FALSE;
@@ -733,6 +735,7 @@
v4_int_template_out.tot_rec_len += v4_int_template_out.r[idx].length;
}
+#if defined ENABLE_IPV6
rcount = 0;
bzero(&v6_template, sizeof(v6_template));
bzero(&v6_int_template, sizeof(v6_int_template));
@@ -1043,6 +1046,7 @@
v6_int_template.tot_rec_len += v6_int_template.r[idx].length;
v6_int_template_out.tot_rec_len += v6_int_template_out.r[idx].length;
}
+#endif
}
static void
@@ -1180,39 +1184,41 @@
memcpy(ftoft_ptr_0, &rec8, 1);
ftoft_ptr_0 += 1;
if (flow_direction[0] == DIRECTION_IN) {
- for (idx = 5; v4_int_template.r[idx].length; idx++) {
+ for (idx = 5; v4_int_template.r[idx].handler; idx++) {
v4_int_template.r[idx].handler(ftoft_ptr_0, flow, 0, v4_int_template.r[idx].length);
ftoft_ptr_0 += v4_int_template.r[idx].length;
}
freclen = v4_int_template.tot_rec_len;
}
else if (flow_direction[0] == DIRECTION_OUT) {
- for (idx = 5; v4_int_template_out.r[idx].length; idx++) {
+ for (idx = 5; v4_int_template_out.r[idx].handler; idx++) {
v4_int_template_out.r[idx].handler(ftoft_ptr_0, flow, 0, v4_int_template_out.r[idx].length);
ftoft_ptr_0 += v4_int_template_out.r[idx].length;
}
freclen = v4_int_template_out.tot_rec_len;
}
break;
+#if defined ENABLE_IPV6
case AF_INET6:
rec8 = 6;
memcpy(ftoft_ptr_0, &rec8, 1);
ftoft_ptr_0 += 1;
if (flow_direction[0] == DIRECTION_IN) {
- for (idx = 5; v6_int_template.r[idx].length; idx++) {
+ for (idx = 5; v6_int_template.r[idx].handler; idx++) {
v6_int_template.r[idx].handler(ftoft_ptr_0, flow, 0, v6_int_template.r[idx].length);
ftoft_ptr_0 += v6_int_template.r[idx].length;
}
freclen = v6_int_template.tot_rec_len;
}
else if (flow_direction[0] == DIRECTION_OUT) {
- for (idx = 5; v6_int_template_out.r[idx].length; idx++) {
+ for (idx = 5; v6_int_template_out.r[idx].handler; idx++) {
v6_int_template_out.r[idx].handler(ftoft_ptr_0, flow, 0, v6_int_template_out.r[idx].length);
ftoft_ptr_0 += v6_int_template_out.r[idx].length;
}
freclen = v6_int_template_out.tot_rec_len;
}
break;
+#endif
default:
return (-1);
}
@@ -1241,39 +1247,41 @@
memcpy(ftoft_ptr_1, &rec8, 1);
ftoft_ptr_1 += 1;
if (flow_direction[1] == DIRECTION_IN) {
- for (idx = 5; v4_int_template.r[idx].length; idx++) {
+ for (idx = 5; v4_int_template.r[idx].handler; idx++) {
v4_int_template.r[idx].handler(ftoft_ptr_1, flow, 1, v4_int_template.r[idx].length);
ftoft_ptr_1 += v4_int_template.r[idx].length;
}
freclen = v4_int_template.tot_rec_len;
}
else if (flow_direction[1] == DIRECTION_OUT) {
- for (idx = 5; v4_int_template_out.r[idx].length; idx++) {
+ for (idx = 5; v4_int_template_out.r[idx].handler; idx++) {
v4_int_template_out.r[idx].handler(ftoft_ptr_1, flow, 1, v4_int_template_out.r[idx].length);
ftoft_ptr_1 += v4_int_template_out.r[idx].length;
}
freclen = v4_int_template_out.tot_rec_len;
}
break;
+#if defined ENABLE_IPV6
case AF_INET6:
rec8 = 6;
memcpy(ftoft_ptr_1, &rec8, 1);
ftoft_ptr_1 += 1;
if (flow_direction[1] == DIRECTION_IN) {
- for (idx = 5; v6_int_template.r[idx].length; idx++) {
+ for (idx = 5; v6_int_template.r[idx].handler; idx++) {
v6_int_template.r[idx].handler(ftoft_ptr_1, flow, 1, v6_int_template.r[idx].length);
ftoft_ptr_1 += v6_int_template.r[idx].length;
}
freclen = v6_int_template.tot_rec_len;
}
else if (flow_direction[1] == DIRECTION_OUT) {
- for (idx = 5; v6_int_template_out.r[idx].length; idx++) {
+ for (idx = 5; v6_int_template_out.r[idx].handler; idx++) {
v6_int_template_out.r[idx].handler(ftoft_ptr_1, flow, 1, v6_int_template_out.r[idx].length);
ftoft_ptr_1 += v6_int_template_out.r[idx].length;
}
freclen = v6_int_template_out.tot_rec_len;
}
break;
+#endif
default:
return (-1);
}
@@ -1485,15 +1493,16 @@
offset += v4_template_out.tot_len;
flows++;
tot_len += v4_template_out.tot_len;
+#if defined ENABLE_IPV6
memcpy(packet + offset, &v6_template, v6_template.tot_len);
offset += v6_template.tot_len;
flows++;
- /*XXX: shall v6 templates be issued only if v6 is enabled? */
tot_len += v6_template.tot_len;
memcpy(packet + offset, &v6_template_out, v6_template_out.tot_len);
offset += v6_template_out.tot_len;
flows++;
tot_len += v6_template_out.tot_len;
+#endif
if (config.sampling_rate || config.ext_sampling_rate) {
memcpy(packet + offset, &sampling_option_template, sampling_option_template.tot_len);
offset += sampling_option_template.tot_len;
@@ -1555,12 +1564,14 @@
else if (direction == DIRECTION_OUT)
dh->c.flowset_id = v4_template_out.h.template_id;
}
+#if defined ENABLE_IPV6
else if (flows[flow_i + flow_j]->af == AF_INET6) {
if (direction == DIRECTION_IN)
dh->c.flowset_id = v6_template.h.template_id;
else if (direction == DIRECTION_OUT)
dh->c.flowset_id = v6_template_out.h.template_id;
}
+#endif
// last_af = flows[flow_i + flow_j]->af; /* XXX */
}
last_valid = offset;
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/nfv9_template.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -27,27 +27,31 @@
#include "nfacctd.h"
#include "pmacct-data.h"
-void handle_template_v9(struct template_hdr_v9 *hdr, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int16_t *pens)
+void handle_template(struct template_hdr_v9 *hdr, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int16_t *pens)
{
struct template_cache_entry *tpl;
+ u_int8_t version = 0;
if (pens) *pens = FALSE;
+ if (tpl_type == 0 || tpl_type == 1) version = 9;
+ else if (tpl_type == 2 || tpl_type == 3) version = 10;
+
/* 0 NetFlow v9, 2 IPFIX */
if (tpl_type == 0 || tpl_type == 2) {
- if (tpl = find_template_v9(hdr->template_id, pptrs, tpl_type, sid))
- refresh_template_v9(hdr, tpl, pptrs, tpl_type, sid, pens);
- else insert_template_v9(hdr, pptrs, tpl_type, sid, pens);
+ if (tpl = find_template(hdr->template_id, pptrs, tpl_type, sid))
+ refresh_template(hdr, tpl, pptrs, tpl_type, sid, pens, version);
+ else insert_template(hdr, pptrs, tpl_type, sid, pens, version);
}
/* 1 NetFlow v9, 3 IPFIX */
else if (tpl_type == 1 || tpl_type == 3) {
- if (tpl = find_template_v9(hdr->template_id, pptrs, tpl_type, sid))
- refresh_opt_template_v9(hdr, tpl, pptrs, tpl_type, sid);
- else insert_opt_template_v9(hdr, pptrs, tpl_type, sid);
+ if (tpl = find_template(hdr->template_id, pptrs, tpl_type, sid))
+ refresh_opt_template(hdr, tpl, pptrs, tpl_type, sid, version);
+ else insert_opt_template(hdr, pptrs, tpl_type, sid, version);
}
}
-struct template_cache_entry *find_template_v9(u_int16_t id, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid)
+struct template_cache_entry *find_template(u_int16_t id, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid)
{
struct template_cache_entry *ptr;
u_int16_t modulo = (ntohs(id)%tpl_cache.num);
@@ -64,12 +68,13 @@
return NULL;
}
-struct template_cache_entry *insert_template_v9(struct template_hdr_v9 *hdr, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int16_t *pens)
+struct template_cache_entry *insert_template(struct template_hdr_v9 *hdr, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int16_t *pens, u_int8_t version)
{
struct template_cache_entry *ptr, *prevptr = NULL;
struct template_field_v9 *field;
u_int16_t modulo = (ntohs(hdr->template_id)%tpl_cache.num), count;
u_int16_t num = ntohs(hdr->num), type, port;
+ u_int32_t *pen;
u_int8_t ipfix_ebit;
u_char *tpl;
@@ -93,48 +98,82 @@
ptr->template_type = 0;
ptr->num = num;
- log_template_v9_header(ptr, pptrs, tpl_type, sid);
+ log_template_header(ptr, pptrs, tpl_type, sid, version);
- count = num;
+ count = 0;
tpl = (u_char *) hdr;
tpl += NfTplHdrV9Sz;
field = (struct template_field_v9 *)tpl;
- while (count) {
+ while (count < num) {
+ pen = NULL;
ipfix_ebit = FALSE;
type = ntohs(field->type);
- if (type & IPFIX_TPL_EBIT) {
+
+ if (type & IPFIX_TPL_EBIT && version == 10) {
ipfix_ebit = TRUE;
type ^= IPFIX_TPL_EBIT;
if (pens) (*pens)++;
+ pen = (u_int32_t *) field;
+ pen++;
}
- log_template_v9_field(type, ptr->len, ntohs(field->len));
- /* Cisco ASA hack */
- switch (type) {
- case NF9_ASA_XLATE_IPV4_SRC_ADDR:
- type = NF9_XLATE_IPV4_SRC_ADDR;
- break;
- case NF9_ASA_XLATE_IPV4_DST_ADDR:
- type = NF9_XLATE_IPV4_DST_ADDR;
- break;
- case NF9_ASA_XLATE_L4_SRC_PORT:
- type = NF9_XLATE_L4_SRC_PORT;
- break;
- case NF9_ASA_XLATE_L4_DST_PORT:
- type = NF9_XLATE_L4_DST_PORT;
- break;
- default:
- break;
- }
+ log_template_field(ptr->vlen, pen, type, ptr->len, ntohs(field->len), version);
- if (type < NF9_MAX_DEFINED_FIELD) {
+ /* Let's determine if we use legacy template registry or the
+ new template database (ie. if we have a PEN or high field
+ value, >= 384) */
+ if (type < NF9_MAX_DEFINED_FIELD && !pen) {
ptr->tpl[type].off = ptr->len;
- ptr->tpl[type].len = ntohs(field->len);
- ptr->len += ptr->tpl[type].len;
+ ptr->tpl[type].tpl_len = ntohs(field->len);
+
+ if (ptr->vlen) ptr->tpl[type].off = 0;
+
+ if (ptr->tpl[type].tpl_len == IPFIX_VARIABLE_LENGTH) {
+ ptr->tpl[type].len = 0;
+ ptr->vlen = TRUE;
+ ptr->len = 0;
+ }
+ else {
+ ptr->tpl[type].len = ptr->tpl[type].tpl_len;
+ if (!ptr->vlen) ptr->len += ptr->tpl[type].len;
+ }
+ ptr->list[count].ptr = (char *) &ptr->tpl[type];
+ ptr->list[count].type = TPL_TYPE_LEGACY;
+ }
+ else {
+ u_int16_t ie_idx, ext_db_modulo = (type%TPL_EXT_DB_ENTRIES);
+ struct utpl_field *ext_db_ptr = NULL;
+
+ for (ie_idx = 0; ie_idx < IES_PER_TPL_EXT_DB_ENTRY; ie_idx++) {
+ if (ptr->ext_db[ext_db_modulo].ie[ie_idx].type == 0) {
+ ext_db_ptr = &ptr->ext_db[ext_db_modulo].ie[ie_idx];
+ break;
+ }
+ }
+
+ if (ext_db_ptr) {
+ if (pen) ext_db_ptr->pen = ntohl(*pen);
+ ext_db_ptr->type = type;
+ ext_db_ptr->off = ptr->len;
+ ext_db_ptr->tpl_len = ntohs(field->len);
+
+ if (ptr->vlen) ext_db_ptr->off = 0;
+
+ if (ext_db_ptr->tpl_len == IPFIX_VARIABLE_LENGTH) {
+ ext_db_ptr->len = 0;
+ ptr->vlen = TRUE;
+ ptr->len = 0;
+ }
+ else {
+ ext_db_ptr->len = ext_db_ptr->tpl_len;
+ if (!ptr->vlen) ptr->len += ext_db_ptr->len;
+ }
+ }
+ ptr->list[count].ptr = (char *) ext_db_ptr;
+ ptr->list[count].type = TPL_TYPE_EXT_DB;
}
- else ptr->len += ntohs(field->len);
- count--;
+ count++;
if (ipfix_ebit) field++; /* skip 32-bits ahead */
field++;
}
@@ -142,16 +181,17 @@
if (prevptr) prevptr->next = ptr;
else tpl_cache.c[modulo] = ptr;
- log_template_v9_footer(ptr->len);
+ log_template_footer(ptr->len, version);
return ptr;
}
-void refresh_template_v9(struct template_hdr_v9 *hdr, struct template_cache_entry *tpl, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int16_t *pens)
+void refresh_template(struct template_hdr_v9 *hdr, struct template_cache_entry *tpl, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int16_t *pens, u_int8_t version)
{
struct template_cache_entry *next;
struct template_field_v9 *field;
u_int16_t count, num = ntohs(hdr->num), type, port;
+ u_int32_t *pen;
u_int8_t ipfix_ebit;
u_char *ptr;
@@ -164,84 +204,132 @@
tpl->num = num;
tpl->next = next;
- log_template_v9_header(tpl, pptrs, tpl_type, sid);
+ log_template_header(tpl, pptrs, tpl_type, sid, version);
- count = num;
+ count = 0;
ptr = (u_char *) hdr;
ptr += NfTplHdrV9Sz;
field = (struct template_field_v9 *)ptr;
- while (count) {
+ while (count < num) {
+ pen = NULL;
ipfix_ebit = FALSE;
type = ntohs(field->type);
- if (type & IPFIX_TPL_EBIT) {
+
+ if (type & IPFIX_TPL_EBIT && version == 10) {
ipfix_ebit = TRUE;
type ^= IPFIX_TPL_EBIT;
if (pens) (*pens)++;
+ pen = (u_int32_t *) field; pen++;
}
- log_template_v9_field(type, tpl->len, ntohs(field->len));
-
- /* Cisco ASA hack */
- switch (type) {
- case NF9_ASA_XLATE_IPV4_SRC_ADDR:
- type = NF9_XLATE_IPV4_SRC_ADDR;
- break;
- case NF9_ASA_XLATE_IPV4_DST_ADDR:
- type = NF9_XLATE_IPV4_DST_ADDR;
- break;
- case NF9_ASA_XLATE_L4_SRC_PORT:
- type = NF9_XLATE_L4_SRC_PORT;
- break;
- case NF9_ASA_XLATE_L4_DST_PORT:
- type = NF9_XLATE_L4_DST_PORT;
- break;
- default:
- break;
- }
+ log_template_field(tpl->vlen, pen, type, tpl->len, ntohs(field->len), version);
- if (type < NF9_MAX_DEFINED_FIELD) {
+ if (type < NF9_MAX_DEFINED_FIELD && !pen) {
tpl->tpl[type].off = tpl->len;
- tpl->tpl[type].len = ntohs(field->len);
- tpl->len += tpl->tpl[type].len;
+ tpl->tpl[type].tpl_len = ntohs(field->len);
+
+ if (tpl->vlen) tpl->tpl[type].off = 0;
+
+ if (tpl->tpl[type].tpl_len == IPFIX_VARIABLE_LENGTH) {
+ tpl->tpl[type].len = 0;
+ tpl->vlen = TRUE;
+ tpl->len = 0;
+ }
+ else {
+ tpl->tpl[type].len = tpl->tpl[type].tpl_len;
+ if (!tpl->vlen) tpl->len += tpl->tpl[type].len;
+ }
+ tpl->list[count].ptr = (char *) &tpl->tpl[type];
+ tpl->list[count].type = TPL_TYPE_LEGACY;
+ }
+ else {
+ u_int16_t ie_idx, ext_db_modulo = (type%TPL_EXT_DB_ENTRIES);
+ struct utpl_field *ext_db_ptr = NULL;
+
+ for (ie_idx = 0; ie_idx < IES_PER_TPL_EXT_DB_ENTRY; ie_idx++) {
+ if (tpl->ext_db[ext_db_modulo].ie[ie_idx].type == 0) {
+ ext_db_ptr = &tpl->ext_db[ext_db_modulo].ie[ie_idx];
+ break;
+ }
+ }
+
+ if (ext_db_ptr) {
+ if (pen) ext_db_ptr->pen = ntohl(*pen);
+ ext_db_ptr->type = type;
+ ext_db_ptr->off = tpl->len;
+ ext_db_ptr->tpl_len = ntohs(field->len);
+
+ if (tpl->vlen) ext_db_ptr->off = 0;
+
+ if (ext_db_ptr->tpl_len == IPFIX_VARIABLE_LENGTH) {
+ ext_db_ptr->len = 0;
+ tpl->vlen = TRUE;
+ tpl->len = 0;
+ }
+ else {
+ ext_db_ptr->len = ext_db_ptr->tpl_len;
+ if (!tpl->vlen) tpl->len += ext_db_ptr->len;
+ }
+ }
+ tpl->list[count].ptr = (char *) ext_db_ptr;
+ tpl->list[count].type = TPL_TYPE_EXT_DB;
}
- else tpl->len += ntohs(field->len);
- count--;
+ count++;
if (ipfix_ebit) field++; /* skip 32-bits ahead */
field++;
}
- log_template_v9_footer(tpl->len);
+ log_template_footer(tpl->len, version);
}
-void log_template_v9_header(struct template_cache_entry *tpl, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid)
+void log_template_header(struct template_cache_entry *tpl, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int8_t version)
{
struct host_addr a;
u_char agent_addr[50];
u_int16_t agent_port, count, size;
- u_int8_t nf_version = 0;
sa_to_addr((struct sockaddr *)pptrs->f_agent, &a, &agent_port);
addr_to_str(agent_addr, &a);
- if (tpl_type == 0 || tpl_type == 1) nf_version = 9;
- else if (tpl_type == 2 || tpl_type == 3) nf_version = 10;
-
- Log(LOG_DEBUG, "DEBUG ( default/core ): NfV%u agent : %s:%u\n", nf_version, agent_addr, sid);
- Log(LOG_DEBUG, "DEBUG ( default/core ): NfV%u template type : %s\n", nf_version, ( tpl->template_type == 0 || tpl->template_type == 2 ) ? "flow" : "options");
- Log(LOG_DEBUG, "DEBUG ( default/core ): NfV%u template ID : %u\n", nf_version, ntohs(tpl->template_id));
- Log(LOG_DEBUG, "DEBUG ( default/core ): ----------------------------------------\n");
- Log(LOG_DEBUG, "DEBUG ( default/core ): | field type | offset | size |\n");
+ Log(LOG_DEBUG, "DEBUG ( default/core ): NfV%u agent : %s:%u\n", version, agent_addr, sid);
+ Log(LOG_DEBUG, "DEBUG ( default/core ): NfV%u template type : %s\n", version, ( tpl->template_type == 0 || tpl->template_type == 2 ) ? "flow" : "options");
+ Log(LOG_DEBUG, "DEBUG ( default/core ): NfV%u template ID : %u\n", version, ntohs(tpl->template_id));
+
+ if ( tpl->template_type == 0 || tpl->template_type == 2 ) {
+ Log(LOG_DEBUG, "DEBUG ( default/core ): -----------------------------------------------------\n");
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | pen | field type | offset | size |\n");
+ }
+ else {
+ Log(LOG_DEBUG, "DEBUG ( default/core ): ----------------------------------------\n");
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | field type | offset | size |\n");
+ }
}
-void log_template_v9_field(u_int16_t type, u_int16_t off, u_int16_t len)
+void log_template_field(u_int8_t vlen, u_int32_t *pen, u_int16_t type, u_int16_t off, u_int16_t len, u_int8_t version)
{
- if (type <= MAX_TPL_DESC_LIST && strlen(tpl_desc_list[type]))
- Log(LOG_DEBUG, "DEBUG ( default/core ): | %-18s | %6u | %6u |\n", tpl_desc_list[type], off, len);
- else
- Log(LOG_DEBUG, "DEBUG ( default/core ): | %-18u | %6u | %6u |\n", type, off, len);
+ if (!pen) {
+ if (type <= MAX_TPL_DESC_LIST && strlen(tpl_desc_list[type])) {
+ if (!off && vlen)
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | %-10u | %-18s | %6s | %6u |\n", 0, tpl_desc_list[type], "tbd", len);
+ else
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | %-10u | %-18s | %6u | %6u |\n", 0, tpl_desc_list[type], off, len);
+ }
+ else {
+ if (!off && vlen)
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | %-10u | %-18u | %6s | %6u |\n", 0, type, "tbd", len);
+ else
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | %-10u | %-18u | %6u | %6u |\n", 0, type, off, len);
+ }
+ }
+ else {
+ if (!off && vlen)
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | %-10u | %-18u | %6s | %6u |\n", ntohl(*pen), type, "tbd", len);
+ else
+ Log(LOG_DEBUG, "DEBUG ( default/core ): | %-10u | %-18u | %6u | %6u |\n", ntohl(*pen), type, off, len);
+ }
}
-void log_opt_template_v9_field(u_int16_t type, u_int16_t off, u_int16_t len)
+void log_opt_template_field(u_int16_t type, u_int16_t off, u_int16_t len, u_int8_t version)
{
if (type <= MAX_OPT_TPL_DESC_LIST && strlen(opt_tpl_desc_list[type]))
Log(LOG_DEBUG, "DEBUG ( default/core ): | %-18s | %6u | %6u |\n", opt_tpl_desc_list[type], off, len);
@@ -249,14 +337,17 @@
Log(LOG_DEBUG, "DEBUG ( default/core ): | %-18u | %6u | %6u |\n", type, off, len);
}
-void log_template_v9_footer(u_int16_t size)
+void log_template_footer(u_int16_t size, u_int8_t version)
{
- Log(LOG_DEBUG, "DEBUG ( default/core ): ----------------------------------------\n");
- Log(LOG_DEBUG, "DEBUG ( default/core ): Netflow V9/IPFIX record size : %u\n", size);
+ Log(LOG_DEBUG, "DEBUG ( default/core ): -----------------------------------------------------\n");
+ if (!size)
+ Log(LOG_DEBUG, "DEBUG ( default/core ): Netflow V9/IPFIX record size : %s\n", "tbd");
+ else
+ Log(LOG_DEBUG, "DEBUG ( default/core ): Netflow V9/IPFIX record size : %u\n", size);
Log(LOG_DEBUG, "DEBUG ( default/core ): \n");
}
-struct template_cache_entry *insert_opt_template_v9(void *hdr, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid)
+struct template_cache_entry *insert_opt_template(void *hdr, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int8_t version)
{
struct options_template_hdr_v9 *hdr_v9 = (struct options_template_hdr_v9 *) hdr;
struct options_template_hdr_ipfix *hdr_v10 = (struct options_template_hdr_ipfix *) hdr;
@@ -300,7 +391,7 @@
ptr->template_type = 1;
ptr->num = olen+slen;
- log_template_v9_header(ptr, pptrs, tpl_type, sid);
+ log_template_header(ptr, pptrs, tpl_type, sid, version);
count = ptr->num;
tpl = (u_char *) hdr;
@@ -308,7 +399,7 @@
field = (struct template_field_v9 *)tpl;
while (count) {
type = ntohs(field->type);
- log_opt_template_v9_field(type, ptr->len, ntohs(field->len));
+ log_opt_template_field(type, ptr->len, ntohs(field->len), version);
if (type < NF9_MAX_DEFINED_FIELD) {
ptr->tpl[type].off = ptr->len;
ptr->tpl[type].len = ntohs(field->len);
@@ -323,12 +414,12 @@
if (prevptr) prevptr->next = ptr;
else tpl_cache.c[modulo] = ptr;
- log_template_v9_footer(ptr->len);
+ log_template_footer(ptr->len, version);
return ptr;
}
-void refresh_opt_template_v9(void *hdr, struct template_cache_entry *tpl, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid)
+void refresh_opt_template(void *hdr, struct template_cache_entry *tpl, struct packet_ptrs *pptrs, u_int16_t tpl_type, u_int32_t sid, u_int8_t version)
{
struct options_template_hdr_v9 *hdr_v9 = (struct options_template_hdr_v9 *) hdr;
struct options_template_hdr_ipfix *hdr_v10 = (struct options_template_hdr_ipfix *) hdr;
@@ -359,7 +450,7 @@
tpl->num = olen+slen;
tpl->next = next;
- log_template_v9_header(tpl, pptrs, tpl_type, sid);
+ log_template_header(tpl, pptrs, tpl_type, sid, version);
count = tpl->num;
ptr = (u_char *) hdr;
@@ -367,7 +458,7 @@
field = (struct template_field_v9 *)ptr;
while (count) {
type = ntohs(field->type);
- log_opt_template_v9_field(type, tpl->len, ntohs(field->len));
+ log_opt_template_field(type, tpl->len, ntohs(field->len), version);
if (type < NF9_MAX_DEFINED_FIELD) {
tpl->tpl[type].off = tpl->len;
tpl->tpl[type].len = ntohs(field->len);
@@ -379,5 +470,68 @@
field++;
}
- log_template_v9_footer(tpl->len);
+ log_template_footer(tpl->len, version);
+}
+
+void resolve_vlen_template(char *ptr, struct template_cache_entry *tpl)
+{
+ struct otpl_field *otpl_ptr;
+ struct utpl_field *utpl_ptr;
+ u_int16_t idx = 0, len = 0;
+ u_int8_t vlen = 0, add_len;
+
+ while (idx < tpl->num) {
+ add_len = 0;
+ if (tpl->list[idx].type == TPL_TYPE_LEGACY) {
+ otpl_ptr = (struct otpl_field *) tpl->list[idx].ptr;
+ if (vlen) otpl_ptr->off = len;
+
+ if (otpl_ptr->tpl_len == IPFIX_VARIABLE_LENGTH) {
+ vlen = TRUE;
+ add_len = get_ipfix_vlen(ptr+len, &otpl_ptr->len);
+ otpl_ptr->off = len+add_len;
+ }
+
+ len += (otpl_ptr->len+add_len);
+ }
+ else if (tpl->list[idx].type == TPL_TYPE_EXT_DB) {
+ utpl_ptr = (struct utpl_field *) tpl->list[idx].ptr;
+ if (vlen) utpl_ptr->off = len;
+
+ if (utpl_ptr->tpl_len == IPFIX_VARIABLE_LENGTH) {
+ vlen = TRUE;
+ add_len = get_ipfix_vlen(ptr+len, &utpl_ptr->len);
+ utpl_ptr->off = len+add_len;
+ }
+
+ len += (utpl_ptr->len+add_len);
+ }
+
+ idx++;
+ }
+
+ tpl->len = len;
+}
+
+u_int8_t get_ipfix_vlen(char *base, u_int16_t *len)
+{
+ char *ptr = base;
+ u_int8_t *len8, ret = 0;
+ u_int16_t *len16;
+
+ if (ptr && len) {
+ len8 = (u_int8_t *) ptr;
+ if (*len8 < 255) {
+ ret = 1;
+ *len = *len8;
+ }
+ else {
+ ptr++;
+ len16 = (u_int16_t *) ptr;
+ ret = 3;
+ *len = *len16;
+ }
+ }
+
+ return ret;
}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/nl.c
^
|
@@ -49,7 +49,7 @@
pptrs.mac_ptr = 0; pptrs.vlan_ptr = 0; pptrs.mpls_ptr = 0;
pptrs.pf = 0; pptrs.shadow = 0; pptrs.tag = 0; pptrs.tag2 = 0;
pptrs.class = 0; pptrs.bpas = 0, pptrs.bta = 0; pptrs.blp = 0;
- pptrs.bmed = 0; pptrs.bitr = 0;
+ pptrs.bmed = 0; pptrs.bitr = 0; pptrs.bta2 = 0; pptrs.bta_af = 0;
pptrs.tun_layer = 0; pptrs.tun_stack = 0;
pptrs.f_agent = cb_data->f_agent;
pptrs.idtable = cb_data->idt;
@@ -68,7 +68,7 @@
isis_srcdst_lookup(&pptrs);
}
if (config.nfacctd_bgp) {
- PM_find_id((struct id_table *)pptrs.bta_table, &pptrs, &pptrs.bta, NULL);
+ BTA_find_id((struct id_table *)pptrs.bta_table, &pptrs, &pptrs.bta, &pptrs.bta2);
bgp_srcdst_lookup(&pptrs);
}
if (config.nfacctd_bgp_peer_as_src_map) PM_find_id((struct id_table *)pptrs.bpas_table, &pptrs, &pptrs.bpas, NULL);
@@ -82,7 +82,11 @@
}
if (reload_map) {
+ bta_map_caching = FALSE;
+ sampling_map_caching = FALSE;
+
load_networks(config.networks_file, &nt, &nc);
+
if (config.nfacctd_bgp && config.nfacctd_bgp_peer_as_src_map)
load_id_file(MAP_BGP_PEER_AS_SRC, config.nfacctd_bgp_peer_as_src_map, (struct id_table *)cb_data->bpas_table, &req, &bpas_map_allocated);
if (config.nfacctd_bgp && config.nfacctd_bgp_src_local_pref_map)
@@ -93,7 +97,9 @@
load_id_file(MAP_BGP_TO_XFLOW_AGENT, config.nfacctd_bgp_to_agent_map, (struct id_table *)cb_data->bta_table, &req, &bta_map_allocated);
if (config.pre_tag_map)
load_id_file(config.acct_type, config.pre_tag_map, (struct id_table *) pptrs.idtable, &req, &tag_map_allocated);
+
reload_map = FALSE;
+ gettimeofday(&reload_map_tstamp, NULL);
}
}
@@ -331,12 +337,12 @@
}
#endif
-void PM_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
+int PM_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
{
int x, j, stop;
pm_id_t id;
- if (!t) return;
+ if (!t) return 0;
id = 0;
if (tag) *tag = 0;
@@ -353,6 +359,11 @@
if (t->e[x].stack.func) id = (*t->e[x].stack.func)(id, *tag2);
*tag2 = id;
}
+ else if (stop == BTA_MAP_RCODE_ID_ID2) {
+ // stack not applicable here
+ *tag = id;
+ *tag2 = t->e[x].id2;
+ }
if (t->e[x].jeq.ptr) {
if (t->e[x].ret) {
@@ -368,6 +379,8 @@
else break;
}
}
+
+ return stop;
}
void compute_once()
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pgsql_plugin.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -36,7 +36,6 @@
struct ports_table pt;
struct pollfd pfd;
struct insert_data idata;
- struct timezone tz;
time_t refresh_deadline;
int timeout;
int ret, num;
@@ -143,7 +142,7 @@
exit(0);
default: /* Parent */
if (pqq_ptr) sql_cache_flush_pending(pending_queries_queue, pqq_ptr, &idata);
- gettimeofday(&idata.flushtime, &tz);
+ gettimeofday(&idata.flushtime, NULL);
while (idata.now > refresh_deadline)
refresh_deadline += config.sql_refresh_time;
while (idata.now > idata.triggertime && idata.t_timeslot > 0) {
@@ -226,7 +225,7 @@
exit(0);
default: /* Parent */
if (pqq_ptr) sql_cache_flush_pending(pending_queries_queue, pqq_ptr, &idata);
- gettimeofday(&idata.flushtime, &tz);
+ gettimeofday(&idata.flushtime, NULL);
while (idata.now > refresh_deadline)
refresh_deadline += config.sql_refresh_time;
while (idata.now > idata.triggertime && idata.t_timeslot > 0) {
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pkt_handlers.c
^
|
@@ -1147,10 +1147,14 @@
switch(hdr->version) {
case 10:
case 9:
- memcpy(&pdata->primitives.etype, pptrs->f_data+tpl->tpl[NF9_ETHERTYPE].off, MIN(tpl->tpl[NF9_ETHERTYPE].len, 2));
- pdata->primitives.etype = ntohs(pdata->primitives.etype);
+ if (tpl->tpl[NF9_ETHERTYPE].len == 2) {
+ memcpy(&pdata->primitives.etype, pptrs->f_data+tpl->tpl[NF9_ETHERTYPE].off, MIN(tpl->tpl[NF9_ETHERTYPE].len, 2));
+ pdata->primitives.etype = ntohs(pdata->primitives.etype);
+ }
+ else pdata->primitives.etype = pptrs->l3_proto;
break;
default:
+ pdata->primitives.etype = pptrs->l3_proto;
break;
}
}
@@ -1170,8 +1174,8 @@
case 10:
case 9:
if (pptrs->l3_proto == ETHERTYPE_IP) {
- if (chptr->plugin->cfg.xlate_src && tpl->tpl[NF9_XLATE_IPV4_SRC_ADDR].len) {
- memcpy(&pdata->primitives.src_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_XLATE_IPV4_SRC_ADDR].off, MIN(tpl->tpl[NF9_XLATE_IPV4_SRC_ADDR].len, 4));
+ if (chptr->plugin->cfg.xlate_src && tpl->tpl[NF9_ASA_XLATE_IPV4_SRC_ADDR].len) {
+ memcpy(&pdata->primitives.src_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_ASA_XLATE_IPV4_SRC_ADDR].off, MIN(tpl->tpl[NF9_ASA_XLATE_IPV4_SRC_ADDR].len, 4));
src_mask = 32; /* no xlate mask field exists atm */
}
else {
@@ -1183,14 +1187,9 @@
}
#if defined ENABLE_IPV6
if (pptrs->l3_proto == ETHERTYPE_IPV6) {
- if (chptr->plugin->cfg.xlate_src && tpl->tpl[NF9_XLATE_IPV6_SRC_ADDR].len) {
- memcpy(&pdata->primitives.src_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_XLATE_IPV6_SRC_ADDR].off, MIN(tpl->tpl[NF9_XLATE_IPV6_SRC_ADDR].len, 16));
- src_mask = 128;
- }
- else {
- memcpy(&pdata->primitives.src_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_ADDR].off, MIN(tpl->tpl[NF9_IPV6_SRC_ADDR].len, 16));
- memcpy(&src_mask, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_MASK].off, tpl->tpl[NF9_IPV6_SRC_MASK].len);
- }
+ memcpy(&pdata->primitives.src_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_ADDR].off, MIN(tpl->tpl[NF9_IPV6_SRC_ADDR].len, 16));
+ memcpy(&src_mask, pptrs->f_data+tpl->tpl[NF9_IPV6_SRC_MASK].off, tpl->tpl[NF9_IPV6_SRC_MASK].len);
+
pdata->primitives.src_ip.family = AF_INET6;
break;
}
@@ -1281,8 +1280,8 @@
case 10:
case 9:
if (pptrs->l3_proto == ETHERTYPE_IP) {
- if (chptr->plugin->cfg.xlate_dst && tpl->tpl[NF9_XLATE_IPV4_DST_ADDR].len) {
- memcpy(&pdata->primitives.dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_XLATE_IPV4_DST_ADDR].off, MIN(tpl->tpl[NF9_XLATE_IPV4_DST_ADDR].len, 4));
+ if (chptr->plugin->cfg.xlate_dst && tpl->tpl[NF9_ASA_XLATE_IPV4_DST_ADDR].len) {
+ memcpy(&pdata->primitives.dst_ip.address.ipv4, pptrs->f_data+tpl->tpl[NF9_ASA_XLATE_IPV4_DST_ADDR].off, MIN(tpl->tpl[NF9_ASA_XLATE_IPV4_DST_ADDR].len, 4));
dst_mask = 32; /* no xlate mask field exists atm */
}
else {
@@ -1294,14 +1293,9 @@
}
#if defined ENABLE_IPV6
if (pptrs->l3_proto == ETHERTYPE_IPV6) {
- if (chptr->plugin->cfg.xlate_dst && tpl->tpl[NF9_XLATE_IPV6_DST_ADDR].len) {
- memcpy(&pdata->primitives.dst_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_XLATE_IPV6_DST_ADDR].off, MIN(tpl->tpl[NF9_XLATE_IPV6_DST_ADDR].len, 16));
- dst_mask = 128;
- }
- else {
- memcpy(&pdata->primitives.dst_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_ADDR].off, MIN(tpl->tpl[NF9_IPV6_DST_ADDR].len, 16));
- memcpy(&dst_mask, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_MASK].off, tpl->tpl[NF9_IPV6_DST_MASK].len);
- }
+ memcpy(&pdata->primitives.dst_ip.address.ipv6, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_ADDR].off, MIN(tpl->tpl[NF9_IPV6_DST_ADDR].len, 16));
+ memcpy(&dst_mask, pptrs->f_data+tpl->tpl[NF9_IPV6_DST_MASK].off, tpl->tpl[NF9_IPV6_DST_MASK].len);
+
pdata->primitives.dst_ip.family = AF_INET6;
break;
}
@@ -1726,8 +1720,8 @@
memcpy(&l4_proto, pptrs->f_data+tpl->tpl[NF9_L4_PROTOCOL].off, 1);
if (l4_proto == IPPROTO_UDP || l4_proto == IPPROTO_TCP) {
- if (chptr->plugin->cfg.xlate_src && tpl->tpl[NF9_XLATE_L4_SRC_PORT].len)
- memcpy(&pdata->primitives.src_port, pptrs->f_data+tpl->tpl[NF9_XLATE_L4_SRC_PORT].off, MIN(tpl->tpl[NF9_XLATE_L4_SRC_PORT].len, 2));
+ if (chptr->plugin->cfg.xlate_src && tpl->tpl[NF9_ASA_XLATE_L4_SRC_PORT].len)
+ memcpy(&pdata->primitives.src_port, pptrs->f_data+tpl->tpl[NF9_ASA_XLATE_L4_SRC_PORT].off, MIN(tpl->tpl[NF9_ASA_XLATE_L4_SRC_PORT].len, 2));
else if (tpl->tpl[NF9_L4_SRC_PORT].len)
memcpy(&pdata->primitives.src_port, pptrs->f_data+tpl->tpl[NF9_L4_SRC_PORT].off, MIN(tpl->tpl[NF9_L4_SRC_PORT].len, 2));
else if (l4_proto == IPPROTO_UDP && tpl->tpl[NF9_UDP_SRC_PORT].len)
@@ -1790,8 +1784,8 @@
memcpy(&l4_proto, pptrs->f_data+tpl->tpl[NF9_L4_PROTOCOL].off, 1);
if (l4_proto == IPPROTO_UDP || l4_proto == IPPROTO_TCP) {
- if (chptr->plugin->cfg.xlate_dst && tpl->tpl[NF9_XLATE_L4_DST_PORT].len)
- memcpy(&pdata->primitives.dst_port, pptrs->f_data+tpl->tpl[NF9_XLATE_L4_DST_PORT].off, MIN(tpl->tpl[NF9_XLATE_L4_DST_PORT].len, 2));
+ if (chptr->plugin->cfg.xlate_dst && tpl->tpl[NF9_ASA_XLATE_L4_DST_PORT].len)
+ memcpy(&pdata->primitives.dst_port, pptrs->f_data+tpl->tpl[NF9_ASA_XLATE_L4_DST_PORT].off, MIN(tpl->tpl[NF9_ASA_XLATE_L4_DST_PORT].len, 2));
else if (tpl->tpl[NF9_L4_DST_PORT].len)
memcpy(&pdata->primitives.dst_port, pptrs->f_data+tpl->tpl[NF9_L4_DST_PORT].off, MIN(tpl->tpl[NF9_L4_DST_PORT].len, 2));
else if (l4_proto == IPPROTO_UDP && tpl->tpl[NF9_UDP_DST_PORT].len)
@@ -2633,10 +2627,21 @@
void NF_counters_map_renormalize_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
{
struct pkt_data *pdata = (struct pkt_data *) *data;
+ struct xflow_status_entry *xsentry = (struct xflow_status_entry *) pptrs->f_status;
if (pptrs->renormalized) return;
- NF_find_id((struct id_table *)pptrs->sampling_table, pptrs, &pptrs->st, NULL);
+ if (sampling_map_caching && xsentry && timeval_cmp(&xsentry->st.stamp, &reload_map_tstamp) > 0) {
+ pptrs->st = xsentry->st.id;
+ }
+ else {
+ NF_find_id((struct id_table *)pptrs->sampling_table, pptrs, &pptrs->st, NULL);
+
+ if (xsentry) {
+ xsentry->st.id = pptrs->st;
+ gettimeofday(&xsentry->st.stamp, NULL);
+ }
+ }
if (pptrs->st) {
pdata->pkt_len = pdata->pkt_len * pptrs->st;
@@ -3188,10 +3193,21 @@
void SF_counters_map_renormalize_handler(struct channels_list_entry *chptr, struct packet_ptrs *pptrs, char **data)
{
struct pkt_data *pdata = (struct pkt_data *) *data;
+ struct xflow_status_entry *xsentry = (struct xflow_status_entry *) pptrs->f_status;
if (pptrs->renormalized) return;
- SF_find_id((struct id_table *)pptrs->sampling_table, pptrs, &pptrs->st, NULL);
+ if (sampling_map_caching && xsentry && timeval_cmp(&xsentry->st.stamp, &reload_map_tstamp) > 0) {
+ pptrs->st = xsentry->st.id;
+ }
+ else {
+ SF_find_id((struct id_table *)pptrs->sampling_table, pptrs, &pptrs->st, NULL);
+
+ if (xsentry) {
+ xsentry->st.id = pptrs->st;
+ gettimeofday(&xsentry->st.stamp, NULL);
+ }
+ }
if (pptrs->st) {
pdata->pkt_len = pdata->pkt_len * pptrs->st;
@@ -3440,3 +3456,17 @@
return FALSE;
}
}
+
+char *lookup_tpl_ext_db(void *entry, u_int32_t pen, u_int16_t type)
+{
+ struct template_cache_entry *tpl = (struct template_cache_entry *) entry;
+ u_int16_t ie_idx, ext_db_modulo = (type%TPL_EXT_DB_ENTRIES);
+
+ for (ie_idx = 0; ie_idx < IES_PER_TPL_EXT_DB_ENTRY; ie_idx++) {
+ if (tpl->ext_db[ext_db_modulo].ie[ie_idx].type == type &&
+ tpl->ext_db[ext_db_modulo].ie[ie_idx].pen == pen)
+ return (char *) &tpl->ext_db[ext_db_modulo].ie[ie_idx];
+ }
+
+ return NULL;
+}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pkt_handlers.h
^
|
@@ -151,4 +151,5 @@
EXT void sfprobe_sampling_handler(struct channels_list_entry *, struct packet_ptrs *, char **);
EXT int evaluate_lm_method(struct packet_ptrs *, u_int8_t, u_int32_t, u_int32_t);
+EXT char *lookup_tpl_ext_db(void *, u_int32_t, u_int16_t);
#undef EXT
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/plugin_hooks.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -514,9 +514,9 @@
void init_random_seed()
{
- struct timeval tv; struct timezone tz;
+ struct timeval tv;
- gettimeofday(&tv, &tz);
+ gettimeofday(&tv, NULL);
srandom((unsigned int)tv.tv_usec);
}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pmacct-defines.h
^
|
@@ -60,13 +60,13 @@
#define LARGEBUFLEN (8192+MOREBUFSZ)
#define MANTAINER "Paolo Lucente <paolo@pmacct.net>"
-#define PMACCTD_USAGE_HEADER "Promiscuous Mode Accounting Daemon, pmacctd 0.14.0"
-#define UACCTD_USAGE_HEADER "Linux NetFilter ULOG Accounting Daemon, pmacctd 0.14.0"
-#define PMACCT_USAGE_HEADER "pmacct, pmacct client 0.14.0"
-#define PMMYPLAY_USAGE_HEADER "pmmyplay, pmacct MySQL logfile player 0.14.0"
-#define PMPGPLAY_USAGE_HEADER "pmpgplay, pmacct PGSQL logfile player 0.14.0"
-#define NFACCTD_USAGE_HEADER "NetFlow Accounting Daemon, nfacctd 0.14.0"
-#define SFACCTD_USAGE_HEADER "sFlow Accounting Daemon, sfacctd 0.14.0"
+#define PMACCTD_USAGE_HEADER "Promiscuous Mode Accounting Daemon, pmacctd 0.14.1"
+#define UACCTD_USAGE_HEADER "Linux NetFilter ULOG Accounting Daemon, pmacctd 0.14.1"
+#define PMACCT_USAGE_HEADER "pmacct, pmacct client 0.14.1"
+#define PMMYPLAY_USAGE_HEADER "pmmyplay, pmacct MySQL logfile player 0.14.1"
+#define PMPGPLAY_USAGE_HEADER "pmpgplay, pmacct PGSQL logfile player 0.14.1"
+#define NFACCTD_USAGE_HEADER "NetFlow Accounting Daemon, nfacctd 0.14.1"
+#define SFACCTD_USAGE_HEADER "sFlow Accounting Daemon, sfacctd 0.14.1"
#ifndef TRUE
#define TRUE 1
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pmacct.c
^
|
@@ -78,7 +78,7 @@
printf(" -O\tShow output in CSV format (applies to -M and -s)\n");
printf(" -u\tLeave IP protocols in numerical format\n");
printf("\n");
- printf(" See EXAMPLES file in the distribution for examples\n");
+ printf(" See QUICKSTART file in the distribution for examples\n");
printf("\n");
printf("For suggestions, critics, bugs, contact me: %s.\n", MANTAINER);
}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pmacct.h
^
|
@@ -277,7 +277,7 @@
EXT int gtp_tunnel_configurator(struct tunnel_handler *, char *);
EXT void tunnel_registry_init();
EXT void pcap_cb(u_char *, const struct pcap_pkthdr *, const u_char *);
-EXT void PM_find_id(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
+EXT int PM_find_id(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
EXT void compute_once();
#undef EXT
@@ -288,6 +288,7 @@
#endif
EXT struct host_addr mcast_groups[MAX_MCAST_GROUPS];
EXT int reload_map, reload_map_bgp_thread, data_plugins, tee_plugins;
+EXT struct timeval reload_map_tstamp;
EXT struct child_ctl sql_writers;
#undef EXT
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pmacctd.c
^
|
@@ -81,7 +81,7 @@
printf(" -r \tRefresh time (in seconds)\n");
printf(" -O \t[ formatted | csv ] \n\tOutput format\n");
printf("\n");
- printf(" See EXAMPLES or visit http://wiki.pmacct.net/ for examples.\n");
+ printf(" See QUICKSTART or visit http://wiki.pmacct.net/ for examples.\n");
printf("\n");
printf("For suggestions, critics, bugs, contact me: %s.\n", MANTAINER);
}
@@ -131,6 +131,8 @@
blp_map_allocated = FALSE;
bmed_map_allocated = FALSE;
biss_map_allocated = FALSE;
+ bta_map_caching = FALSE;
+ sampling_map_caching = FALSE;
find_id_func = PM_find_id;
errflag = 0;
@@ -151,6 +153,7 @@
memset(&client, 0, sizeof(client));
memset(&cb_data, 0, sizeof(cb_data));
memset(&tunnel_registry, 0, sizeof(tunnel_registry));
+ memset(&reload_map_tstamp, 0, sizeof(reload_map_tstamp));
config.acct_type = ACCT_PM;
rows = 0;
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pmmyplay.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -156,7 +156,7 @@
char default_pwd[] = "arealsmartpwd";
int have_pwd = 0, have_logfile = 0, n;
int result = 0, position = 0, howmany = 0;
- int do_nothing = 0;
+ int do_nothing = 0, ret;
char *cl_sql_host = NULL, *cl_sql_user = NULL, *cl_sql_db = NULL, *cl_sql_table = NULL;
char sql_pwd[SRVBUFLEN];
@@ -271,7 +271,10 @@
exit(1);
}
- fread(&lh, sizeof(lh), 1, f);
+ if ((ret = fread(&lh, sizeof(lh), 1, f)) != 1) {
+ printf("ERROR: Short read from %s\nExiting...\n", logfile);
+ exit(1);
+ }
lh.sql_table_version = ntohs(lh.sql_table_version);
lh.sql_optimize_clauses = ntohs(lh.sql_optimize_clauses);
lh.sql_history = ntohs(lh.sql_history);
@@ -306,7 +309,10 @@
if (cl_sql_host) sql_host = cl_sql_host;
else sql_host = lh.sql_host;
- fread(&th, sizeof(th), 1, f);
+ if ((ret = fread(&th, sizeof(th), 1, f)) != 1) {
+ printf("ERROR: Short read from %s\nExiting...\n", logfile);
+ exit(1);
+ }
th.magic = ntohl(th.magic);
th.num = ntohs(th.num);
th.sz = ntohs(th.sz);
@@ -319,7 +325,10 @@
}
te = malloc(th.num*sizeof(struct template_entry));
memset(te, 0, th.num*sizeof(struct template_entry));
- fread(te, th.num*sizeof(struct template_entry), 1, f);
+ if ((ret = fread(te, th.num*sizeof(struct template_entry), 1, f)) != 1) {
+ printf("ERROR: Short read from %s\nExiting...\n", logfile);
+ exit(1);
+ }
}
else {
if (debug) printf("ERROR: no template header found.\n");
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/preprocess.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2009 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -460,7 +460,7 @@
int check_fsrc(struct db_cache *queue[], int *num, int seq)
{
struct fsrc_queue_elem *ptr, *last_seen, *new;
- struct timeval tv; struct timezone tz;
+ struct timeval tv;
float w /* random variable */, z;
u_int32_t max = prep.fsrc+1; /* maximum number of allowed flows */
int x, queueElemSz = sizeof(struct fsrc_queue_elem);
@@ -482,7 +482,7 @@
/* 1st stage: computing the m+1==max flows with highest z */
for (x = 0; x < *num; x++) {
if (queue[x]->valid == SQL_CACHE_FREE || queue[x]->valid == SQL_CACHE_COMMITTED) {
- gettimeofday(&tv, &tz);
+ gettimeofday(&tv, NULL);
srandom((unsigned int)tv.tv_usec);
w = (float) (random()/(RAND_MAX+1.0));
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pretag-data.h
^
|
@@ -75,6 +75,7 @@
const struct _map_dictionary_line bta_map_dictionary[] = {
{"id", PT_map_id_handler},
{"ip", PT_map_ip_handler},
+ {"filter", PT_map_filter_handler},
{"", NULL}
};
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pretag.h
^
|
@@ -46,9 +46,10 @@
#define PRETAG_MPLS_VPN_RD 0x00080000
#define PRETAG_SAMPLE_TYPE 0x00100000
-#define PRETAG_MAP_RCODE_ID 100
-#define PRETAG_MAP_RCODE_ID2 101
-#define BPAS_MAP_RCODE_BGP 102
+#define PRETAG_MAP_RCODE_ID 100
+#define PRETAG_MAP_RCODE_ID2 101
+#define BTA_MAP_RCODE_ID_ID2 102
+#define BPAS_MAP_RCODE_BGP 103
typedef int (*pretag_handler) (struct packet_ptrs *, void *, void *);
typedef pm_id_t (*pretag_stack_handler) (pm_id_t, pm_id_t);
@@ -170,6 +171,9 @@
EXT int bta_map_allocated;
EXT int bitr_map_allocated;
EXT int sampling_map_allocated;
-EXT void (*find_id_func)(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
+EXT int bta_map_caching;
+EXT int sampling_map_caching;
+
+EXT int (*find_id_func)(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
#undef EXT
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/pretag_handlers.c
^
|
@@ -33,22 +33,40 @@
{
struct host_addr a;
char *endptr = NULL;
- pm_id_t j = 0;
+ pm_id_t j = 0, z = 0;
e->id = 0;
e->flags = FALSE;
/* If we parse a bgp_agent_map and spot a '.' within the string let's
- check if we are given a valid IP address */
+ check if we are given a valid IPv4 address */
if (acct_type == MAP_BGP_TO_XFLOW_AGENT && strchr(value, '.')) {
memset(&a, 0, sizeof(a));
str_to_addr(value, &a);
if (a.family == AF_INET) j = a.address.ipv4.s_addr;
else {
- Log(LOG_ERR, "ERROR ( %s ): Agent ID does not appear to be a valid IPv4 address. ", filename);
+ Log(LOG_ERR, "ERROR ( %s ): ID does not appear to be a valid IPv4 address. ", filename);
return TRUE;
}
}
+ /* If we parse a bgp_agent_map and spot a ':' within the string let's
+ check if we are given a valid IPv6 address */
+#if defined ENABLE_IPV6
+ else if (acct_type == MAP_BGP_TO_XFLOW_AGENT && strchr(value, ':')) {
+ memset(&a, 0, sizeof(a));
+ str_to_addr(value, &a);
+ if (a.family == AF_INET6) {
+ ip6_addr_32bit_cpy(&j, &a.address.ipv6, 0, 0, 1);
+ ip6_addr_32bit_cpy(&z, &a.address.ipv6, 0, 2, 3);
+
+ e->flags = BTA_MAP_RCODE_ID_ID2;
+ }
+ else {
+ Log(LOG_ERR, "ERROR ( %s ): ID does not appear to be a valid IPv6 address. ", filename);
+ return TRUE;
+ }
+ }
+#endif
else if (acct_type == MAP_BGP_IFACE_TO_RD && strchr(value, ':')) {
rd_t rd;
@@ -63,11 +81,13 @@
else {
j = strtoull(value, &endptr, 10);
if (!j || j > UINT32_MAX) {
- Log(LOG_ERR, "ERROR ( %s ): Invalid Agent ID specified. ", filename);
+ Log(LOG_ERR, "ERROR ( %s ): Invalid ID specified. ", filename);
return TRUE;
}
}
+
e->id = j;
+ if (z) e->id2 = z;
return FALSE;
}
@@ -79,7 +99,7 @@
j = strtoull(value, &endptr, 10);
if (!j || j > UINT32_MAX) {
- Log(LOG_ERR, "ERROR ( %s ): Invalid Agent ID2 specified. ", filename);
+ Log(LOG_ERR, "ERROR ( %s ): Invalid ID2 specified. ", filename);
return TRUE;
}
e->id2 = j;
@@ -102,6 +122,8 @@
int x = 0, len;
char *endptr;
+ if (acct_type == MAP_SAMPLING) sampling_map_caching = FALSE;
+
e->input.neg = pt_check_neg(&value);
len = strlen(value);
@@ -133,6 +155,8 @@
int x = 0, len;
char *endptr;
+ if (acct_type == MAP_SAMPLING) sampling_map_caching = FALSE;
+
e->output.neg = pt_check_neg(&value);
len = strlen(value);
@@ -201,19 +225,21 @@
}
}
- if (config.nfacctd_as & NF_AS_BGP) {
+ if (config.nfacctd_net & NF_NET_BGP) {
e->func[x] = pretag_bgp_bgp_nexthop_handler;
have_bgp = TRUE;
e->func_type[x] = PRETAG_BGP_NEXTHOP;
x++;
}
- if (config.nfacctd_as & NF_AS_KEEP && config.acct_type == ACCT_NF) {
+ /* XXX: IGP? */
+
+ if (config.nfacctd_net & NF_NET_KEEP && config.acct_type == ACCT_NF) {
e->func[x] = pretag_bgp_nexthop_handler;
e->func_type[x] = PRETAG_BGP_NEXTHOP;
return FALSE;
}
- else if (config.nfacctd_as & NF_AS_KEEP && config.acct_type == ACCT_SF) {
+ else if (config.nfacctd_net & NF_NET_KEEP && config.acct_type == ACCT_SF) {
e->func[x] = SF_pretag_bgp_nexthop_handler;
e->func_type[x] = PRETAG_BGP_NEXTHOP;
return FALSE;
@@ -347,7 +373,7 @@
for (x = 0; e->func[x]; x++) {
if (e->func_type[x] == PRETAG_ENGINE_ID) {
- Log(LOG_ERR, "ERROR ( %s ): Multiple 'bgp_nexthop' clauses part of the same statement. ", filename);
+ Log(LOG_ERR, "ERROR ( %s ): Multiple 'engine_id' clauses part of the same statement. ", filename);
return TRUE;
}
}
@@ -365,6 +391,13 @@
char errbuf[PCAP_ERRBUF_SIZE];
int x, link_type;
+ if (acct_type == MAP_BGP_TO_XFLOW_AGENT) {
+ if (strncmp(value, "ip", 2) && strncmp(value, "ip6", 3)) {
+ Log(LOG_ERR, "ERROR ( %s ): bgp_agent_map filter supports only 'ip' and 'ip6' keywords\n", filename);
+ return TRUE;
+ }
+ }
+
memset(&device, 0, sizeof(struct pcap_device));
if (glob_pcapt) device.link_type = pcap_datalink(glob_pcapt);
else if (config.uacctd_group) device.link_type = DLT_RAW;
@@ -1033,6 +1066,9 @@
if (entry->last_matched == PRETAG_BGP_NEXTHOP) return FALSE;
+ /* check network-related primitives against fallback scenarios */
+ if (!evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_KEEP)) return;
+
switch(hdr->version) {
case 9:
if (entry->bgp_nexthop.a.family == AF_INET) {
@@ -1063,6 +1099,9 @@
struct bgp_info *info;
int ret = -1;
+ /* check network-related primitives against fallback scenarios */
+ if (!evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_BGP)) return;
+
if (dst_ret) {
if (pptrs->bgp_nexthop_info)
info = (struct bgp_info *) pptrs->bgp_nexthop_info;
@@ -1564,6 +1603,10 @@
}
}
+ if (entry->flags == BTA_MAP_RCODE_ID_ID2) {
+ return BTA_MAP_RCODE_ID_ID2; /* cap */
+ }
+
return PRETAG_MAP_RCODE_ID; /* cap */
}
@@ -1616,8 +1659,8 @@
struct id_entry *entry = e;
SFSample *sample = (SFSample *) pptrs->f_data;
- /* If in a fallback scenario, ie. NF_AS_BGP + NF_AS_KEEP set, check BGP first */
- if (config.nfacctd_as & NF_AS_BGP && pptrs->bgp_dst) return FALSE;
+ /* check network-related primitives against fallback scenarios */
+ if (!evaluate_lm_method(pptrs, TRUE, config.nfacctd_net, NF_NET_KEEP)) return;
if (entry->bgp_nexthop.a.family == AF_INET) {
if (!memcmp(&entry->bgp_nexthop.a.address.ipv4, &sample->bgp_nextHop.address.ip_v4, 4)) return (FALSE | entry->bgp_nexthop.neg);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/print_plugin.c
^
|
@@ -39,7 +39,6 @@
struct ports_table pt;
unsigned char *pipebuf;
struct pollfd pfd;
- struct timezone tz;
time_t t, now;
int timeout, ret, num;
struct ring *rg = &((struct channels_list_entry *)ptr)->rg;
@@ -169,7 +168,7 @@
exit(0);
default: /* Parent */
P_cache_flush(queries_queue, qq_ptr);
- gettimeofday(&flushtime, &tz);
+ gettimeofday(&flushtime, NULL);
refresh_deadline += config.print_refresh_time;
qq_ptr = FALSE;
if (reload_map) {
@@ -225,7 +224,7 @@
exit(0);
default: /* Parent */
P_cache_flush(queries_queue, qq_ptr);
- gettimeofday(&flushtime, &tz);
+ gettimeofday(&flushtime, NULL);
refresh_deadline += config.print_refresh_time;
qq_ptr = FALSE;
if (reload_map) {
@@ -461,14 +460,16 @@
if (config.sql_table) {
f = open_print_output_file(config.sql_table, refresh_deadline-config.print_refresh_time);
- if (config.print_output == PRINT_OUTPUT_FORMATTED)
- P_write_stats_header_formatted(f);
- else if (config.print_output == PRINT_OUTPUT_CSV)
- P_write_stats_header_csv(f);
+ if (f) {
+ if (config.print_output == PRINT_OUTPUT_FORMATTED)
+ P_write_stats_header_formatted(f);
+ else if (config.print_output == PRINT_OUTPUT_CSV)
+ P_write_stats_header_csv(f);
+ }
}
else f = stdout; /* write to standard output */
- if (config.print_markers) fprintf(f, "--START (%ld+%d)--\n", refresh_deadline-config.print_refresh_time,
+ if (f && config.print_markers) fprintf(f, "--START (%ld+%d)--\n", refresh_deadline-config.print_refresh_time,
config.print_refresh_time);
for (j = 0; j < index; j++) {
@@ -479,7 +480,7 @@
if (!queue[j]->bytes_counter && !queue[j]->packet_counter && !queue[j]->flow_counter)
continue;
- if (config.print_output == PRINT_OUTPUT_FORMATTED) {
+ if (f && config.print_output == PRINT_OUTPUT_FORMATTED) {
fprintf(f, "%-10llu ", data->id);
fprintf(f, "%-10llu ", data->id2);
fprintf(f, "%-16s ", ((data->class && class[(data->class)-1].id) ? class[(data->class)-1].protocol : "unknown" ));
@@ -572,7 +573,7 @@
fprintf(f, "%lu\n", queue[j]->bytes_counter);
#endif
}
- else if (config.print_output == PRINT_OUTPUT_CSV) {
+ else if (f && config.print_output == PRINT_OUTPUT_CSV) {
fprintf(f, "%llu,", data->id);
fprintf(f, "%llu,", data->id2);
fprintf(f, "%s,", ((data->class && class[(data->class)-1].id) ? class[(data->class)-1].protocol : "unknown" ));
@@ -649,9 +650,9 @@
}
}
- if (config.print_markers) fprintf(f, "--END--\n");
+ if (f && config.print_markers) fprintf(f, "--END--\n");
- if (config.sql_table) fclose(f);
+ if (f && config.sql_table) fclose(f);
if (config.sql_trigger_exec) P_trigger_exec(config.sql_trigger_exec);
}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/sfacctd.c
^
|
@@ -83,7 +83,7 @@
printf(" -r \tRefresh time (in seconds)\n");
printf(" -O \t[ formatted | csv ] \n\tOutput format\n");
printf("\n");
- printf(" See EXAMPLES or visit http://wiki.pmacct.net/ for examples.\n");
+ printf(" See QUICKSTART or visit http://wiki.pmacct.net/ for examples.\n");
printf("\n");
printf("For suggestions, critics, bugs, contact me: %s.\n", MANTAINER);
}
@@ -158,6 +158,8 @@
biss_map_allocated = FALSE;
bta_map_allocated = FALSE;
bitr_map_allocated = FALSE;
+ bta_map_caching = TRUE;
+ sampling_map_caching = TRUE;
find_id_func = SF_find_id;
data_plugins = 0;
@@ -185,6 +187,7 @@
memset(&bta_table, 0, sizeof(bta_table));
memset(&bitr_table, 0, sizeof(bitr_table));
memset(&sampling_table, 0, sizeof(sampling_table));
+ memset(&reload_map_tstamp, 0, sizeof(reload_map_tstamp));
config.acct_type = ACCT_SF;
rows = 0;
@@ -790,7 +793,11 @@
if (!allowed) continue;
if (reload_map) {
+ bta_map_caching = TRUE;
+ sampling_map_caching = TRUE;
+
load_networks(config.networks_file, &nt, &nc);
+
if (config.nfacctd_bgp && config.nfacctd_bgp_peer_as_src_map)
load_id_file(MAP_BGP_PEER_AS_SRC, config.nfacctd_bgp_peer_as_src_map, &bpas_table, &req, &bpas_map_allocated);
if (config.nfacctd_bgp && config.nfacctd_bgp_src_local_pref_map)
@@ -807,7 +814,9 @@
load_id_file(MAP_SAMPLING, config.sampling_map, &sampling_table, &req, &sampling_map_allocated);
set_sampling_table(&pptrs, (u_char *) &sampling_table);
}
+
reload_map = FALSE;
+ gettimeofday(&reload_map_tstamp, NULL);
}
if (data_plugins) {
@@ -2173,7 +2182,7 @@
pptrs->l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(pptrs);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, pptrs, &pptrs->bta, &pptrs->bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, pptrs, &pptrs->bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(pptrs);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, pptrs, &pptrs->bpas, NULL);
@@ -2208,7 +2217,7 @@
pptrsv->v6.l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->v6);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->v6, &pptrsv->v6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->v6, &pptrsv->v6.bta, &pptrsv->v6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->v6, &pptrsv->v6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->v6);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->v6, &pptrsv->v6.bpas, NULL);
@@ -2244,7 +2253,7 @@
pptrsv->vlan4.l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlan4);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan4, &pptrsv->vlan4.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan4, &pptrsv->vlan4.bta, &pptrsv->vlan4.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlan4, &pptrsv->vlan4.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlan4);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlan4, &pptrsv->vlan4.bpas, NULL);
@@ -2280,7 +2289,7 @@
pptrsv->vlan6.l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlan6);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan6, &pptrsv->vlan6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlan6, &pptrsv->vlan6.bta, &pptrsv->vlan6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlan6, &pptrsv->vlan6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlan6);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlan6, &pptrsv->vlan6.bpas, NULL);
@@ -2329,7 +2338,7 @@
pptrsv->mpls4.l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->mpls4);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls4, &pptrsv->mpls4.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls4, &pptrsv->mpls4.bta, &pptrsv->mpls4.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->mpls4, &pptrsv->mpls4.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->mpls4);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->mpls4, &pptrsv->mpls4.bpas, NULL);
@@ -2377,7 +2386,7 @@
pptrsv->mpls6.l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->mpls6);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls6, &pptrsv->mpls6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->mpls6, &pptrsv->mpls6.bta, &pptrsv->mpls6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->mpls6, &pptrsv->mpls6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->mpls6);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->mpls6, &pptrsv->mpls6.bpas, NULL);
@@ -2426,7 +2435,7 @@
pptrsv->vlanmpls4.l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlanmpls4);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bta, &pptrsv->vlanmpls4.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlanmpls4);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlanmpls4, &pptrsv->vlanmpls4.bpas, NULL);
@@ -2475,7 +2484,7 @@
pptrsv->vlanmpls6.l4_proto = sample->dcd_ipProtocol;
if (config.nfacctd_isis) isis_srcdst_lookup(&pptrsv->vlanmpls6);
- if (config.nfacctd_bgp_to_agent_map) SF_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bta, NULL);
+ if (config.nfacctd_bgp_to_agent_map) BTA_find_id((struct id_table *)pptrs->bta_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bta, &pptrsv->vlanmpls6.bta2);
if (config.nfacctd_bgp_iface_to_rd_map) SF_find_id((struct id_table *)pptrs->bitr_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bitr, NULL);
if (config.nfacctd_bgp) bgp_srcdst_lookup(&pptrsv->vlanmpls6);
if (config.nfacctd_bgp_peer_as_src_map) SF_find_id((struct id_table *)pptrs->bpas_table, &pptrsv->vlanmpls6, &pptrsv->vlanmpls6.bpas, NULL);
@@ -2491,13 +2500,13 @@
}
}
-void SF_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
+int SF_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
{
SFSample *sample = (SFSample *)pptrs->f_data;
int x, j, stop;
pm_id_t id;
- if (!t) return;
+ if (!t) return 0;
/* The id_table is shared between by IPv4 and IPv6 sFlow collectors.
IPv4 ones are in the lower part (0..x), IPv6 ones are in the upper
@@ -2521,6 +2530,11 @@
if (t->e[x].stack.func) id = (*t->e[x].stack.func)(id, *tag2);
*tag2 = id;
}
+ else if (stop == BTA_MAP_RCODE_ID_ID2) {
+ // stack not applicable here
+ *tag = id;
+ *tag2 = t->e[x].id2;
+ }
if (t->e[x].jeq.ptr) {
if (t->e[x].ret) {
@@ -2552,6 +2566,11 @@
if (t->e[x].stack.func) id = (*t->e[x].stack.func)(id, *tag2);
*tag2 = id;
}
+ else if (stop == BTA_MAP_RCODE_ID_ID2) {
+ // stack not applicable here
+ *tag = id;
+ *tag2 = t->e[x].id2;
+ }
if (t->e[x].jeq.ptr) {
if (t->e[x].ret) {
@@ -2570,6 +2589,8 @@
}
}
#endif
+
+ return stop;
}
u_int16_t SF_evaluate_flow_type(struct packet_ptrs *pptrs)
@@ -2651,7 +2672,7 @@
hash = hash_status_table(aux1, &salocal, XFLOW_STATUS_TABLE_SZ);
if (hash >= 0) {
- entry = search_status_table(&salocal, aux1, hash, XFLOW_STATUS_TABLE_MAX_ENTRIES);
+ entry = search_status_table(&salocal, aux1, 0, hash, XFLOW_STATUS_TABLE_MAX_ENTRIES);
if (entry) {
update_status_table(entry, spp->sequenceNo);
entry->inc = 1;
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/sfacctd.h
^
|
@@ -243,7 +243,7 @@
EXT void reset_ip4(struct packet_ptrs *);
EXT void reset_ip6(struct packet_ptrs *);
EXT void notify_malf_packet(short int, char *, struct sockaddr *);
-EXT void SF_find_id(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
+EXT int SF_find_id(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
EXT u_int32_t getData32(SFSample *);
EXT u_int32_t getData32_nobswap(SFSample *);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/sql_common.c
^
|
@@ -653,7 +653,7 @@
return;
safe_action:
- Log(LOG_DEBUG, "DEBUG ( %s/%s ): purging process (CAUSE: safe action)\n", config.name, config.type);
+ Log(LOG_WARNING, "WARN ( %s/%s ): purging process (CAUSE: safe action)\n", config.name, config.type);
if (qq_ptr) sql_cache_flush(queries_queue, qq_ptr, idata, FALSE);
switch (fork()) {
@@ -960,8 +960,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "mac_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -984,8 +984,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "mac_dst", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1011,8 +1011,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "vlan", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1026,8 +1026,8 @@
if (what_to_count & COUNT_COS) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "cos", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1040,8 +1040,8 @@
if (what_to_count & COUNT_ETHERTYPE) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "etype", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%x\'", SPACELEFT(values[primitive].string));
@@ -1064,8 +1064,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
@@ -1098,8 +1098,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
@@ -1123,8 +1123,8 @@
if (what_to_count & (COUNT_SRC_AS|COUNT_SUM_AS)) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if (config.sql_table_version >= 6) {
@@ -1152,8 +1152,8 @@
if (what_to_count & COUNT_IN_IFACE) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "iface_in", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1166,8 +1166,8 @@
if (what_to_count & COUNT_OUT_IFACE) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "iface_out", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1180,8 +1180,8 @@
if (what_to_count & COUNT_SRC_NMASK) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "mask_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1194,8 +1194,8 @@
if (what_to_count & COUNT_DST_NMASK) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "mask_dst", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1208,8 +1208,8 @@
if (what_to_count & COUNT_DST_AS) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if (config.sql_table_version >= 6) {
@@ -1246,8 +1246,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "comms", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1267,8 +1267,8 @@
if (what_to_count & (COUNT_SRC_STD_COMM|COUNT_SRC_EXT_COMM)) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "comms_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1296,8 +1296,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "as_path", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1311,8 +1311,8 @@
if (what_to_count & COUNT_SRC_AS_PATH) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "as_path_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1337,8 +1337,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "local_pref", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1352,8 +1352,8 @@
if (what_to_count & COUNT_SRC_LOCAL_PREF) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "local_pref_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1378,8 +1378,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "med", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1393,8 +1393,8 @@
if (what_to_count & COUNT_SRC_MED) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "med_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1407,8 +1407,8 @@
if (what_to_count & COUNT_MPLS_VPN_RD) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "mpls_vpn_rd", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1430,8 +1430,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "peer_as_src", SPACELEFT(insert_clause));
@@ -1455,8 +1455,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "peer_as_dst", SPACELEFT(insert_clause));
@@ -1480,8 +1480,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "peer_ip_src", SPACELEFT(insert_clause));
@@ -1514,8 +1514,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "peer_ip_dst", SPACELEFT(insert_clause));
@@ -1554,8 +1554,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3")) && config.sql_table_version != 8) {
strncat(insert_clause, "src_port", SPACELEFT(insert_clause));
@@ -1587,8 +1587,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3")) && config.sql_table_version != 8) {
strncat(insert_clause, "dst_port", SPACELEFT(insert_clause));
@@ -1620,7 +1620,7 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
}
strncat(insert_clause, "tcp_flags", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1645,8 +1645,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "tos", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%u", SPACELEFT(values[primitive].string));
@@ -1672,8 +1672,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "ip_proto", SPACELEFT(insert_clause));
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && !config.num_protos) {
@@ -1706,8 +1706,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "agent_id", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%llu", SPACELEFT(values[primitive].string));
@@ -1721,8 +1721,8 @@
if (what_to_count & COUNT_ID2) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "agent_id2", SPACELEFT(insert_clause));
strncat(values[primitive].string, "%llu", SPACELEFT(values[primitive].string));
@@ -1747,8 +1747,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "class_id", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1771,8 +1771,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "mac_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1794,8 +1794,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "mac_dst", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1818,8 +1818,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
@@ -1851,8 +1851,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
@@ -1876,8 +1876,8 @@
if (fakes & FAKE_SRC_AS) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "ip_src", SPACELEFT(insert_clause));
if (!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3") ||
@@ -1897,8 +1897,8 @@
if (fakes & FAKE_DST_AS) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "ip_dst", SPACELEFT(insert_clause));
if (!strcmp(config.type, "mysql") || !strcmp(config.type, "sqlite3") ||
@@ -1926,8 +1926,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "comms", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1949,8 +1949,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "as_path", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1972,8 +1972,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "peer_as_src", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -1995,8 +1995,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
strncat(insert_clause, "peer_as_dst", SPACELEFT(insert_clause));
strncat(values[primitive].string, "\'%s\'", SPACELEFT(values[primitive].string));
@@ -2018,8 +2018,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "peer_ip_src", SPACELEFT(insert_clause));
@@ -2051,8 +2051,8 @@
if (count_it) {
if (primitive) {
strncat(insert_clause, ", ", SPACELEFT(insert_clause));
- strncat(values[primitive].string, delim_buf, sizeof(values[primitive].string));
- strncat(where[primitive].string, " AND ", sizeof(where[primitive].string));
+ strncat(values[primitive].string, delim_buf, SPACELEFT(values[primitive].string));
+ strncat(where[primitive].string, " AND ", SPACELEFT(where[primitive].string));
}
if ((!strcmp(config.type, "sqlite3") || !strcmp(config.type, "mysql")) && config.num_hosts) {
strncat(insert_clause, "peer_ip_dst", SPACELEFT(insert_clause));
@@ -2153,7 +2153,7 @@
file_open:
f = fopen(path, "a+");
if (f) {
- chown(path, owner, group);
+ ret = chown(path, owner, group);
if (file_lock(fileno(f))) {
Log(LOG_ALERT, "ALERT ( %s/%s ): Unable to obtain lock of '%s'.\n", config.name, config.type, path);
goto close;
@@ -2188,12 +2188,18 @@
}
else {
rewind(f);
- fread(&lh, sizeof(lh), 1, f);
+ if ((ret = fread(&lh, sizeof(lh), 1, f)) != 1) {
+ Log(LOG_ALERT, "ALERT ( %s/%s ): Unable to read header: '%s'.\n", config.name, config.type, path);
+ goto close;
+ }
if (ntohl(lh.magic) != MAGIC) {
Log(LOG_ALERT, "ALERT ( %s/%s ): Invalid magic number: '%s'.\n", config.name, config.type, path);
goto close;
}
- fread(&tth, sizeof(tth), 1, f);
+ if ((ret = fread(&tth, sizeof(tth), 1, f)) != 1) {
+ Log(LOG_ALERT, "ALERT ( %s/%s ): Unable to read template: '%s'.\n", config.name, config.type, path);
+ goto close;
+ }
if ((tth.num != th.num) || (tth.sz != th.sz)) {
Log(LOG_ALERT, "ALERT ( %s/%s ): Invalid template in: '%s'.\n", config.name, config.type, path);
goto close;
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/sqlite3_plugin.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -36,7 +36,6 @@
struct ports_table pt;
struct pollfd pfd;
struct insert_data idata;
- struct timezone tz;
time_t refresh_deadline;
int timeout;
int ret, num;
@@ -141,7 +140,7 @@
exit(0);
default: /* Parent */
if (pqq_ptr) sql_cache_flush_pending(pending_queries_queue, pqq_ptr, &idata);
- gettimeofday(&idata.flushtime, &tz);
+ gettimeofday(&idata.flushtime, NULL);
while (idata.now > refresh_deadline)
refresh_deadline += config.sql_refresh_time;
while (idata.now > idata.triggertime && idata.t_timeslot > 0) {
@@ -223,7 +222,7 @@
exit(0);
default: /* Parent */
if (pqq_ptr) sql_cache_flush_pending(pending_queries_queue, pqq_ptr, &idata);
- gettimeofday(&idata.flushtime, &tz);
+ gettimeofday(&idata.flushtime, NULL);
while (idata.now > refresh_deadline)
refresh_deadline += config.sql_refresh_time;
while (idata.now > idata.triggertime && idata.t_timeslot > 0) {
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/uacctd.c
^
|
@@ -79,7 +79,7 @@
printf(" -r \tRefresh time (in seconds)\n");
printf(" -O \t[ formatted | csv ] \n\tOutput format\n");
printf("\n");
- printf(" See EXAMPLES or visit http://wiki.pmacct.net/ for examples.\n");
+ printf(" See QUICKSTART or visit http://wiki.pmacct.net/ for examples.\n");
printf("\n");
printf("For suggestions, critics, bugs, contact me: %s.\n", MANTAINER);
}
@@ -145,6 +145,8 @@
blp_map_allocated = FALSE;
bmed_map_allocated = FALSE;
biss_map_allocated = FALSE;
+ bta_map_caching = FALSE;
+ sampling_map_caching = FALSE;
find_id_func = PM_find_id;
errflag = 0;
@@ -165,6 +167,7 @@
memset(&client, 0, sizeof(client));
memset(&cb_data, 0, sizeof(cb_data));
memset(&tunnel_registry, 0, sizeof(tunnel_registry));
+ memset(&reload_map_tstamp, 0, sizeof(reload_map_tstamp));
config.acct_type = ACCT_PM;
rows = 0;
@@ -741,12 +744,12 @@
hdr.len = ulog_pkt->data_len;
if (strlen(ulog_pkt->indev_name) > 1) {
- cb_data.ifindex_in = get_ifindex(ulog_pkt->indev_name);
+ cb_data.ifindex_in = cache_ifindex(ulog_pkt->indev_name, tv.tv_sec);
}
else cb_data.ifindex_in = 0;
if (strlen(ulog_pkt->outdev_name) > 1) {
- cb_data.ifindex_out = get_ifindex(ulog_pkt->outdev_name);
+ cb_data.ifindex_out = cache_ifindex(ulog_pkt->outdev_name, tv.tv_sec);
}
else cb_data.ifindex_out = 0;
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/util.c
^
|
@@ -381,17 +381,32 @@
FILE *open_print_output_file(char *filename, time_t now)
{
- char buf[LARGEBUFLEN];
+ char buf[LARGEBUFLEN], *fname_ptr, *fname_ptr_tmp;
+ char latest_fname[LARGEBUFLEN], latest_pname[LARGEBUFLEN];
FILE *file = NULL;
struct tm *tmnow;
uid_t owner = -1;
gid_t group = -1;
+ u_int16_t offset;
if (config.files_uid) owner = config.files_uid;
if (config.files_gid) group = config.files_gid;
tmnow = localtime(&now);
- strftime(buf, LARGEBUFLEN, filename, tmnow);
+ strftime(buf, LARGEBUFLEN-10, filename, tmnow);
+
+ /* Check: filename is not making use of the reserved word 'latest' */
+ for (fname_ptr_tmp = buf, fname_ptr = NULL; fname_ptr_tmp; fname_ptr_tmp = strchr(fname_ptr_tmp, '/')) {
+ if (*fname_ptr_tmp == '/') fname_ptr_tmp++;
+ fname_ptr = fname_ptr_tmp;
+ }
+
+ strcpy(latest_fname, config.name);
+ strcat(latest_fname, "-latest");
+ if (!strcmp(fname_ptr, latest_fname)) {
+ Log(LOG_WARNING, "WARN: Invalid print_ouput_file '%s': reserved word\n", buf);
+ return NULL;
+ }
file = fopen(buf, "w");
if (file) {
@@ -402,6 +417,18 @@
Log(LOG_ALERT, "ALERT: Unable to obtain lock for print_ouput_file '%s'.\n", buf);
file = NULL;
}
+
+ /* Let's point 'latest' to the newly opened file */
+ if (file) {
+ memcpy(latest_pname, buf, LARGEBUFLEN);
+ offset = strlen(buf)-strlen(fname_ptr);
+ if (strlen(latest_fname) < LARGEBUFLEN-offset) {
+ strcpy(latest_pname+offset, latest_fname);
+ unlink(latest_pname);
+ symlink(fname_ptr, latest_pname);
+ }
+ else Log(LOG_WARNING, "WARN: Unable to link latest file for print_ouput_file '%s'\n", buf);
+ }
}
else {
Log(LOG_ERR, "ERROR: Unable to open print_ouput_file '%s'\n", buf);
@@ -1185,3 +1212,43 @@
return FALSE;
}
+
+int BTA_find_id(struct id_table *t, struct packet_ptrs *pptrs, pm_id_t *tag, pm_id_t *tag2)
+{
+ struct xflow_status_entry *xsentry = (struct xflow_status_entry *) pptrs->f_status;
+ struct xflow_status_map_cache *xsmc = NULL;
+ int ret = 0;
+
+ pptrs->bta_af = 0;
+
+ if (bta_map_caching && xsentry) {
+ if (pptrs->l3_proto == ETHERTYPE_IP) xsmc = &xsentry->bta_v4;
+#if defined ENABLE_IPV6
+ else if (pptrs->l3_proto == ETHERTYPE_IPV6) xsmc = &xsentry->bta_v6;
+#endif
+ }
+
+ if (bta_map_caching && xsmc && timeval_cmp(&xsmc->stamp, &reload_map_tstamp) > 0) {
+ *tag = xsmc->id;
+ *tag2 = xsmc->id2;
+ ret = xsmc->ret;
+ }
+ else {
+ if (find_id_func) {
+ ret = find_id_func(t, pptrs, tag, tag2);
+ if (xsmc) {
+ xsmc->id = *tag;
+ xsmc->id2 = *tag2;
+ xsmc->ret = ret;
+ gettimeofday(&xsmc->stamp, NULL);
+ }
+ }
+ }
+
+ if (ret == PRETAG_MAP_RCODE_ID) pptrs->bta_af = ETHERTYPE_IP;
+#if defined ENABLE_IPV6
+ else if (ret == BTA_MAP_RCODE_ID_ID2) pptrs->bta_af = ETHERTYPE_IPV6;
+#endif
+
+ return ret;
+}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/util.h
^
|
@@ -82,6 +82,7 @@
EXT int check_allow(struct hosts_table *, struct sockaddr *);
EXT void load_bgp_md5_file(char *, struct bgp_md5_table *);
EXT void unload_bgp_md5_file(struct bgp_md5_table *);
+EXT int BTA_find_id(struct id_table *, struct packet_ptrs *, pm_id_t *, pm_id_t *);
EXT unsigned int str_to_addr(const char *, struct host_addr *);
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/xflow_status.c
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2011 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -44,7 +44,7 @@
return hash;
}
-struct xflow_status_entry *search_status_table(struct sockaddr *sa, u_int32_t aux1, int hash, int num_entries)
+struct xflow_status_entry *search_status_table(struct sockaddr *sa, u_int32_t aux1, u_int32_t aux2, int hash, int num_entries)
{
struct xflow_status_entry *entry = xflow_status_table[hash], *saved = NULL;
u_int16_t port;
@@ -52,7 +52,7 @@
cycle_again:
if (entry) {
saved = entry;
- if (!sa_addr_cmp(sa, &entry->agent_addr) && aux1 == entry->aux1); /* FOUND IT: we are finished */
+ if (!sa_addr_cmp(sa, &entry->agent_addr) && aux1 == entry->aux1 && aux2 == entry->aux2); /* FOUND IT: we are done */
else {
entry = entry->next;
goto cycle_again;
@@ -66,6 +66,7 @@
memset(entry, 0, sizeof(struct xflow_status_entry));
sa_to_addr(sa, &entry->agent_addr, &port);
entry->aux1 = aux1;
+ entry->aux2 = aux2;
entry->seqno = 0;
entry->next = FALSE;
if (!saved) xflow_status_table[hash] = entry;
@@ -232,7 +233,12 @@
struct xflow_status_entry_class *
search_class_id_status_table(struct xflow_status_entry_class *centry, pm_class_t class_id)
{
+ pm_class_t needle, haystack;
+
while (centry) {
+ needle = ntohl(class_id);
+ haystack = ntohl(centry->class_id);
+
if (centry->class_id == class_id) return centry;
centry = centry->next;
}
@@ -269,18 +275,6 @@
return new;
}
-pm_class_t NF_evaluate_classifiers(struct xflow_status_entry_class *entry, pm_class_t *class_id)
-{
- struct xflow_status_entry_class *centry;
-
- centry = search_class_id_status_table(entry, *class_id);
- if (centry) {
- return centry->class_int_id;
- }
-
- return 0;
-}
-
void set_vector_f_status(struct packet_ptrs_vector *pptrsv)
{
pptrsv->vlan4.f_status = pptrsv->v4.f_status;
@@ -293,3 +287,16 @@
pptrsv->mpls6.f_status = pptrsv->v4.f_status;
#endif
}
+
+void set_vector_f_status_g(struct packet_ptrs_vector *pptrsv)
+{
+ pptrsv->vlan4.f_status_g = pptrsv->v4.f_status_g;
+ pptrsv->mpls4.f_status_g = pptrsv->v4.f_status_g;
+ pptrsv->vlanmpls4.f_status_g = pptrsv->v4.f_status_g;
+#if defined ENABLE_IPV6
+ pptrsv->v6.f_status_g = pptrsv->v4.f_status_g;
+ pptrsv->vlan6.f_status_g = pptrsv->v4.f_status_g;
+ pptrsv->vlanmpls6.f_status_g = pptrsv->v4.f_status_g;
+ pptrsv->mpls6.f_status_g = pptrsv->v4.f_status_g;
+#endif
+}
|
[-]
[+]
|
Changed |
pmacct-0.14.1.tar.bz2/src/xflow_status.h
^
|
@@ -1,6 +1,6 @@
/*
pmacct (Promiscuous mode IP Accounting package)
- pmacct is Copyright (C) 2003-2010 by Paolo Lucente
+ pmacct is Copyright (C) 2003-2012 by Paolo Lucente
*/
/*
@@ -49,6 +49,14 @@
struct xflow_status_entry_class *next;
};
+struct xflow_status_map_cache
+{
+ pm_id_t id;
+ pm_id_t id2;
+ int ret;
+ struct timeval stamp;
+};
+
struct xflow_status_entry
{
struct host_addr agent_addr; /* xFlow agent IP address */
@@ -56,9 +64,15 @@
u_int32_t aux1; /* Some more distinguishing fields:
NetFlow v5-v8: Engine Type + Engine ID
NetFlow v9: Source ID
+ IPFIX: ObservedDomainID
sFlow v5: agentSubID */
+ u_int32_t aux2; /* Some more distinguishing (internal) flags */
u_int16_t inc; /* increment, NetFlow v5: required by flow sequence number */
- u_int32_t peer_idx; /* last known BGP peer index */
+ u_int32_t peer_v4_idx; /* last known BGP peer index for ipv4 address family */
+ u_int32_t peer_v6_idx; /* last known BGP peer index for ipv6 address family */
+ struct xflow_status_map_cache bta_v4; /* last known bgp_agent_map IPv4 result */
+ struct xflow_status_map_cache bta_v6; /* last known bgp_agent_map IPv6 result */
+ struct xflow_status_map_cache st; /* last known sampling_map result */
struct xflow_status_entry_counters counters;
struct xflow_status_entry_sampling *sampling;
struct xflow_status_entry_class *class;
@@ -72,7 +86,7 @@
#define EXT
#endif
EXT u_int32_t hash_status_table(u_int32_t, struct sockaddr *, u_int32_t);
-EXT struct xflow_status_entry *search_status_table(struct sockaddr *, u_int32_t, int, int);
+EXT struct xflow_status_entry *search_status_table(struct sockaddr *, u_int32_t, u_int32_t, int, int);
EXT void update_good_status_table(struct xflow_status_entry *, u_int32_t);
EXT void update_bad_status_table(struct xflow_status_entry *);
EXT void print_status_table(time_t, int);
@@ -81,7 +95,6 @@
EXT struct xflow_status_entry_sampling *create_smp_entry_status_table(struct xflow_status_entry *);
EXT struct xflow_status_entry_class *search_class_id_status_table(struct xflow_status_entry_class *, pm_class_t);
EXT struct xflow_status_entry_class *create_class_entry_status_table(struct xflow_status_entry *);
-EXT pm_class_t NF_evaluate_classifier(struct xflow_status_entry_class *, pm_class_t *);
EXT struct xflow_status_entry *xflow_status_table[XFLOW_STATUS_TABLE_SZ];
EXT u_int32_t xflow_status_table_entries;
@@ -89,4 +102,5 @@
EXT u_int32_t xflow_tot_bad_datagrams;
EXT u_int8_t smp_entry_status_table_memerr, class_entry_status_table_memerr;
EXT void set_vector_f_status(struct packet_ptrs_vector *);
+EXT void set_vector_f_status_g(struct packet_ptrs_vector *);
#undef EXT
|