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
);