2 ** exporter.c - example exporter
4 ** Copyright Fraunhofer FOKUS
13 #include <ipfix_def.h>
14 #include <ipfix_def_fokus.h>
15 #include <ipfix_fields_fokus.h>
22 static ipfix_datarecord_t g_data = { NULL, NULL, 0 };
23 static int do_close = 0;
25 struct wprobe_mapping {
29 const char *wprobe_id;
30 struct wprobe_value *val;
34 #define ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0]))
37 #define WMAP(_id, _name, ...) \
41 .id = IPFIX_FT_WPROBE_##_id##_AVG, \
46 #define WMAP_COUNTER(_id, _name, ...) \
50 .id = IPFIX_FT_WPROBE_##_id, \
56 #define WPROBE_OFFSET 2
58 static struct wprobe_mapping map_globals[] = {
60 WMAP(PHY_BUSY, "phy_busy"),
61 WMAP(PHY_RX, "phy_rx"),
62 WMAP(PHY_TX, "phy_tx"),
63 WMAP_COUNTER(FRAMES, "frames"),
64 WMAP_COUNTER(PROBEREQ, "probereq"),
67 static struct wprobe_mapping map_perlink[] = {
68 WMAP(IEEE_TX_RATE, "tx_rate", .scale = 10.0f),
69 WMAP(IEEE_RX_RATE, "rx_rate", .scale = 10.0f),
71 WMAP(SIGNAL, "signal"),
72 WMAP(RETRANSMIT_200, "retransmit_200"),
73 WMAP(RETRANSMIT_400, "retransmit_400"),
74 WMAP(RETRANSMIT_800, "retransmit_800"),
75 WMAP(RETRANSMIT_1600, "retransmit_1600"),
78 static unsigned char link_local[6];
79 static char link_default[6];
80 static LIST_HEAD(global_attr);
81 static LIST_HEAD(link_attr);
82 static LIST_HEAD(links);
83 static int nfields = 0;
85 #define FOKUS_USERID 12325
88 match_template(struct wprobe_mapping *map, int n, struct list_head *list)
90 struct wprobe_attribute *attr;
93 list_for_each_entry(attr, list, list) {
94 for (i = 0; i < n; i++) {
95 j = (last + 1 + i) % n;
96 if (!strcmp(attr->name, map[j].wprobe_id))
102 map[j].val = &attr->val;
103 memset(&attr->val, 0, sizeof(attr->val));
108 /* name: export_ipfix_get_template()
110 static ipfix_template_t *
111 prepare_template(ipfix_t *handle)
113 ipfix_template_t *t = NULL;
114 int size = 3 * nfields + WPROBE_OFFSET;
117 if (ipfix_new_data_template( handle, &t, size) < 0) {
118 mlogf( 0, "ipfix_new_template() failed: %s\n", strerror(errno) );
122 ipfix_add_field(handle, t, 0, IPFIX_FT_SOURCEMACADDRESS, 6);
123 ipfix_add_field(handle, t, 0, IPFIX_FT_DESTINATIONMACADDRESS, 6);
125 g_data.lens = calloc(size, sizeof(g_data.lens[0]));
128 for (i = WPROBE_OFFSET; i < size; i++)
131 g_data.addrs = calloc(size, sizeof(g_data.addrs[0]));
132 g_data.addrs[0] = link_local;
133 g_data.maxfields = WPROBE_OFFSET;
138 add_template_fields(ipfix_t *handle, ipfix_template_t *t, struct wprobe_mapping *map, int n)
140 int f = g_data.maxfields;
143 for (i = 0; i < n; i++) {
148 g_data.addrs[f++] = &map[i].val->U32;
150 g_data.addrs[f++] = &map[i].val->avg;
152 if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 0, 4) < 0)
158 g_data.addrs[f++] = &map[i].val->stdev;
159 g_data.addrs[f++] = &map[i].val->n;
160 if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 1, 4) < 0)
162 if (ipfix_add_field( handle, t, FOKUS_USERID, map[i].id + 2, 4) < 0)
165 g_data.maxfields = f;
169 wprobe_dump_data(ipfix_t *ipfixh, ipfix_template_t *ipfixt, const char *ifname, struct list_head *gl, struct list_head *ll, struct list_head *ls)
171 struct wprobe_link *link;
173 wprobe_update_links(ifname, ls);
174 wprobe_request_data(ifname, gl, NULL, 2);
175 if (list_empty(ls)) {
176 g_data.addrs[1] = link_default;
177 ipfix_export_array(ipfixh, ipfixt, g_data.maxfields, g_data.addrs, g_data.lens);
178 ipfix_export_flush(ipfixh);
180 list_for_each_entry(link, ls, list) {
181 g_data.addrs[1] = link->addr;
182 wprobe_request_data(ifname, ll, link->addr, 2);
183 ipfix_export_array(ipfixh, ipfixt, g_data.maxfields, g_data.addrs, g_data.lens);
184 ipfix_export_flush(ipfixh);
188 int main ( int argc, char **argv )
190 ipfix_template_t *ipfixt = NULL;
191 ipfix_t *ipfixh = NULL;
192 int protocol = IPFIX_PROTO_TCP;
195 int sourceid = 12345;
196 int port = IPFIX_PORTNO;
197 int verbose_level = 0;
200 while ((opt = getopt(argc, argv, "hi:c:p:vstu")) != EOF) {
203 if ((port=atoi(optarg)) <0) {
204 fprintf( stderr, "Invalid -p argument!\n" );
216 protocol = IPFIX_PROTO_SCTP;
220 protocol = IPFIX_PROTO_TCP;
224 protocol = IPFIX_PROTO_UDP;
233 fprintf(stderr, "usage: %s [-hstuv] -i <interface> -c <collector> [-p portno]\n"
235 " -i <interface> wprobe interface\n"
236 " -c <collector> collector address\n"
237 " -p <portno> collector port number (default=%d)\n"
238 " -s send data via SCTP\n"
239 " -t send data via TCP (default)\n"
240 " -u send data via UDP\n"
241 " -v increase verbose level\n\n",
242 argv[0], IPFIX_PORTNO );
248 fprintf(stderr, "No interface specified\n");
253 fprintf(stderr, "No collector specified\n");
257 if (wprobe_init() != 0) {
258 fprintf(stderr, "wprobe init failed\n");
262 wprobe_dump_attributes(ifname, false, &global_attr, (char *) link_local);
263 wprobe_dump_attributes(ifname, true, &link_attr, NULL);
264 if (list_empty(&global_attr) && list_empty(&link_attr)) {
265 fprintf(stderr, "Cannot connect to wprobe on interface '%s'\n", ifname);
269 match_template(map_globals, ARRAY_SIZE(map_globals), &global_attr);
270 match_template(map_perlink, ARRAY_SIZE(map_perlink), &link_attr);
272 fprintf(stderr, "No usable attributes found\n");
276 mlog_set_vlevel( verbose_level );
277 if (ipfix_init() < 0) {
278 fprintf( stderr, "cannot init ipfix module: %s\n", strerror(errno) );
282 ipfix_add_vendor_information_elements(ipfix_ft_fokus);
283 if (ipfix_open(&ipfixh, sourceid, IPFIX_VERSION) < 0) {
284 fprintf( stderr, "ipfix_open() failed: %s\n", strerror(errno) );
288 if (ipfix_add_collector( ipfixh, chost, port, protocol ) < 0) {
289 fprintf( stderr, "ipfix_add_collector(%s,%d) failed: %s\n",
290 chost, port, strerror(errno));
294 fprintf(stderr, "Local link address: %02x:%02x:%02x:%02x:%02x:%02x\n",
295 link_local[0], link_local[1], link_local[2],
296 link_local[3], link_local[4], link_local[5]);
298 ipfixt = prepare_template(ipfixh);
299 add_template_fields(ipfixh, ipfixt, map_globals, ARRAY_SIZE(map_globals));
300 add_template_fields(ipfixh, ipfixt, map_perlink, ARRAY_SIZE(map_perlink));
304 wprobe_measure(ifname);
310 wprobe_dump_data(ipfixh, ipfixt, ifname, &global_attr, &link_attr, &links);
313 ipfix_delete_template( ipfixh, ipfixt );
314 ipfix_close( ipfixh );