Skip to content

Commit e855e01

Browse files
AdamZvarasedmicha
authored andcommitted
ASN: process message
1 parent 2cc9de4 commit e855e01

File tree

1 file changed

+189
-9
lines changed
  • src/plugins/intermediate/asn

1 file changed

+189
-9
lines changed

src/plugins/intermediate/asn/asn.c

Lines changed: 189 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ mmdb_lookup(MMDB_s *db, struct sockaddr *address, int *err)
9999
{
100100
assert(db != NULL && address != NULL && err != NULL);
101101

102-
int rc = MMDB_SUCCESS;
102+
int rc;
103+
*err = MMDB_SUCCESS;
103104
MMDB_lookup_result_s result;
104105

105106
// Search for address
@@ -166,15 +167,21 @@ get_asn(MMDB_s *db, struct ipx_modifier_output *out, uint8_t *address, size_t le
166167
return IPX_ERR_ARG;
167168
}
168169

169-
asn = mmdb_lookup(db, addr, &rc);
170+
asn = htonl(mmdb_lookup(db, addr, &rc));
170171
if (rc) {
171172
// MMDB error
172173
return IPX_ERR_DENIED;
173174
}
174175

176+
if (asn == 0) {
177+
// Not found
178+
return IPX_OK;
179+
}
180+
175181
int len = 4;
176182
memcpy(out->raw, &asn, len);
177183
out->length = len;
184+
return IPX_OK;
178185
}
179186

180187

@@ -224,6 +231,8 @@ modifier_asn_callback(const struct fds_drec *rec, struct ipx_modifier_output out
224231
if (rc) {
225232
return rc;
226233
}
234+
235+
return IPX_OK;
227236
}
228237

229238
/**
@@ -279,6 +288,120 @@ process_session(ipx_ctx_t *ctx, ipx_modifier_t *modifier, ipx_msg_session_t *msg
279288
return IPX_OK;
280289
}
281290

291+
/**
292+
* \brief Free modified record
293+
*
294+
* \param[in] rec Data record
295+
*/
296+
void
297+
free_modified_record(struct fds_drec *rec)
298+
{
299+
free(rec->data);
300+
free(rec);
301+
}
302+
303+
/**
304+
* \brief Estimate size of new message based on old message
305+
*
306+
* Estimation counts with worst case scenario, which is that in new message,
307+
* for each data record new set is created and both AS numbers are added
308+
* \param[in] msg IPFIX message
309+
* \return Estimated size
310+
*/
311+
int
312+
estimate_new_length(ipx_msg_ipfix_t *msg)
313+
{
314+
const struct fds_ipfix_msg_hdr *hdr = (struct fds_ipfix_msg_hdr *) ipx_msg_ipfix_get_packet(msg);
315+
uint32_t rec_cnt = ipx_msg_ipfix_get_drec_cnt(msg);
316+
uint32_t msg_size = ntohs(hdr->length);
317+
318+
if (rec_cnt == 0) {
319+
return msg_size;
320+
}
321+
322+
//for each record * (size of new header + 2x ASN + size of single record)
323+
return rec_cnt * (FDS_IPFIX_SET_HDR_LEN + 8 + msg_size / rec_cnt);
324+
}
325+
326+
/**
327+
* \brief Add new session context from current message to modifier
328+
*
329+
* \param[in] ctx Plugin context
330+
* \param[in] modifier Modifier
331+
* \param[in] msg IPFIX message
332+
* \return #IPX_OK on success
333+
* \return #IPX_ERR_ARG on invalid arguments
334+
* \return #IPX_ERR_NOMEM on memory allocation error
335+
*/
336+
int
337+
ipfix_add_session(ipx_ctx_t *ctx, ipx_modifier_t *modifier, ipx_msg_ipfix_t *msg)
338+
{
339+
int rc;
340+
341+
// Update modifier session context
342+
ipx_msg_garbage_t *session_garbage;
343+
rc = ipx_modifier_add_session(modifier, msg, &session_garbage);
344+
if (session_garbage) {
345+
ipx_ctx_msg_pass(ctx, ipx_msg_garbage2base(session_garbage));
346+
}
347+
348+
if (rc) {
349+
switch (rc) {
350+
case IPX_ERR_ARG:
351+
IPX_CTX_ERROR(ctx, "Invalid arguments passed to ipx_modifier_add_session (%s:%d)",
352+
__FILE__, __LINE__);
353+
return rc;
354+
case IPX_ERR_FORMAT:
355+
// Setting time in history for TCP should be blocked by parser
356+
assert(false);
357+
case IPX_ERR_NOMEM:
358+
IPX_CTX_ERROR(ctx, "Memory allocation error (%s:%d)", __FILE__, __LINE__);
359+
return rc;
360+
default:
361+
IPX_CTX_ERROR(ctx, "Unexpected error from ipx_modifier_add_session (%s:%d)",
362+
__FILE__, __LINE__);
363+
return rc;
364+
}
365+
}
366+
367+
return IPX_OK;
368+
}
369+
370+
/**
371+
* \brief Start building new message
372+
*
373+
* \param[in] ctx Plugin context
374+
* \param[in] modifier Modifier
375+
* \param[in] msg IPFIX message
376+
* \return #IPX_OK on success
377+
* \return #IPX_ERR_ARG on invalid arguments
378+
* \return #IPX_ERR_NOMEM on memory allocation error
379+
*/
380+
int
381+
ipfix_start_builder(ipx_ctx_t *ctx, ipx_msg_builder_t *builder,
382+
const struct fds_ipfix_msg_hdr *hdr, const size_t maxsize)
383+
{
384+
int rc = ipx_msg_builder_start(builder, hdr, maxsize, 0);
385+
386+
if (rc) {
387+
switch(rc) {
388+
case IPX_ERR_ARG:
389+
IPX_CTX_ERROR(ctx, "Invalid arguments passed to ipx_modifier_add_session (%s:%d)",
390+
__FILE__, __LINE__);
391+
return rc;
392+
case IPX_ERR_NOMEM:
393+
IPX_CTX_ERROR(ctx, "Memory allocation error (%s:%d)", __FILE__, __LINE__);
394+
return rc;
395+
default:
396+
IPX_CTX_ERROR(ctx, "Unexpected error from ipx_modifier_add_session (%s:%d)",
397+
__FILE__, __LINE__);
398+
return rc;
399+
}
400+
}
401+
402+
return IPX_OK;
403+
}
404+
282405
/**
283406
* \brief Process IPFIX message
284407
*
@@ -288,26 +411,81 @@ process_session(ipx_ctx_t *ctx, ipx_modifier_t *modifier, ipx_msg_session_t *msg
288411
* \param[in] modifier Modifier component
289412
* \param[in] builder Message builder
290413
* \param[in] msg IPFIX message
291-
* \return
414+
* \return #IPX_OK on success
415+
* \return #IPX_ERR_DENIED on any error
292416
*/
293417
static int
294418
process_ipfix(ipx_ctx_t *ctx, ipx_modifier_t *modifier, ipx_msg_builder_t *builder,
295419
ipx_msg_ipfix_t *msg)
296420
{
421+
int rc;
297422

298-
ipx_msg_garbage_t *session_garbage;
299-
ipx_modifier_add_session(modifier, msg, &session_garbage);
423+
// Add session
424+
rc = ipfix_add_session(ctx, modifier, msg);
425+
if (rc) {
426+
return rc;
427+
}
300428

301-
uint32_t rec_cnt = ipx_msg_ipfix_get_drec_cnt(msg);
429+
// Estimate size of new message
430+
size_t new_msg_size = estimate_new_length(msg);
302431

432+
// Start builder
433+
const struct fds_ipfix_msg_hdr *hdr = (struct fds_ipfix_msg_hdr *) ipx_msg_ipfix_get_packet(msg);
434+
rc = ipfix_start_builder(ctx, builder, hdr, new_msg_size);
435+
if (rc) {
436+
return rc;
437+
}
438+
439+
// Modify each record in IPFIX message and store modified record in builder
440+
uint32_t rec_cnt = ipx_msg_ipfix_get_drec_cnt(msg);
303441
struct ipx_ipfix_record *rec;
442+
struct fds_drec *modified_rec;
304443
ipx_msg_garbage_t *ipfix_garbage;
305444
for (uint32_t i = 0; i < rec_cnt; i++) {
306445
rec = ipx_msg_ipfix_get_drec(msg, i);
307446

308-
ipx_modifier_modify(modifier, &(rec->rec), &ipfix_garbage);
447+
// Modify record
448+
modified_rec = ipx_modifier_modify(modifier, &(rec->rec), &ipfix_garbage);
449+
if (ipfix_garbage) {
450+
ipx_ctx_msg_pass(ctx, ipx_msg_garbage2base(ipfix_garbage));
451+
}
452+
if (!modified_rec) {
453+
// Proper message has been already printed
454+
return rc;
455+
}
456+
457+
// Store modified record in builder
458+
rc = ipx_msg_builder_add_drec(builder, modified_rec);
459+
460+
if (rc) {
461+
free_modified_record(modified_rec);
462+
switch(rc) {
463+
case IPX_ERR_DENIED:
464+
// Exceeded builder limit
465+
IPX_CTX_ERROR(ctx, "Exceeded message builder limit", __FILE__, __LINE__);
466+
return rc;
467+
case IPX_ERR_NOMEM:
468+
IPX_CTX_ERROR(ctx, "Memory allocation error (%s:%d)", __FILE__, __LINE__);
469+
return rc;
470+
default:
471+
IPX_CTX_ERROR(ctx, "Unexpected error from ipx_modifier_add_session (%s:%d)",
472+
__FILE__, __LINE__);
473+
return rc;
474+
}
475+
}
476+
477+
free_modified_record(modified_rec);
309478
}
310479

480+
// Create new message with modified records
481+
const struct ipx_msg_ctx *msg_ctx = ipx_msg_ipfix_get_ctx(msg);
482+
ipx_msg_ipfix_t *new_msg = ipx_msg_builder_end(builder, ctx, msg_ctx);
483+
if (!new_msg) {
484+
return IPX_ERR_DENIED;
485+
}
486+
487+
ipx_msg_ipfix_destroy(msg);
488+
ipx_ctx_msg_pass(ctx, ipx_msg_ipfix2base(new_msg));
311489
return IPX_OK;
312490
}
313491

@@ -419,8 +597,10 @@ ipx_plugin_process(ipx_ctx_t *ctx, void *cfg, ipx_msg_t *msg)
419597
}
420598

421599
if (rc) {
422-
// Any problem occured in processing message
423-
return IPX_ERR_DENIED;
600+
// Any problem occured when modifying message
601+
// pass original message
602+
ipx_ctx_msg_pass(ctx, msg);
603+
return IPX_OK;
424604
}
425605

426606
return IPX_OK;

0 commit comments

Comments
 (0)