23 #include "ncap.pb-c.h"
28 ncap_msg_load(nmsg_message_t m,
void **msg_clos);
31 ncap_msg_fini(nmsg_message_t m,
void *msg_clos);
34 ncap_ipdg_to_payload(
void *,
const struct nmsg_ipdg *, uint8_t **pay,
size_t *);
36 static NMSG_MSGMOD_FIELD_PRINTER(ncap_print_payload);
38 static NMSG_MSGMOD_FIELD_GETTER(ncap_get_srcip);
39 static NMSG_MSGMOD_FIELD_GETTER(ncap_get_dstip);
40 static NMSG_MSGMOD_FIELD_GETTER(ncap_get_srcport);
41 static NMSG_MSGMOD_FIELD_GETTER(ncap_get_dstport);
42 static NMSG_MSGMOD_FIELD_GETTER(ncap_get_proto);
43 static NMSG_MSGMOD_FIELD_GETTER(ncap_get_dns);
61 .get = ncap_get_srcip,
66 .get = ncap_get_dstip,
81 .get = ncap_get_srcport,
86 .get = ncap_get_dstport,
91 .get = ncap_get_proto,
97 .print = ncap_print_payload
105 NMSG_MSGMOD_FIELD_END
111 NMSG_MSGMOD_REQUIRED_INIT,
112 .vendor = NMSG_VENDOR_BASE,
113 .msgtype = { NMSG_VENDOR_BASE_NCAP_ID, NMSG_VENDOR_BASE_NCAP_NAME },
115 .msg_load = ncap_msg_load,
116 .msg_fini = ncap_msg_fini,
117 .pbdescr = &nmsg__base__ncap__descriptor,
118 .fields = ncap_fields,
119 .ipdg_to_payload = ncap_ipdg_to_payload
124 static nmsg_res ncap_pbuf_inet_ntop(ProtobufCBinaryData *bdata,
char *str);
127 ncap_print_udp(nmsg_strbuf_t,
const char *srcip,
const char *dstip,
128 uint16_t srcport, uint16_t dstport,
129 const u_char *payload,
size_t paylen,
const char *el);
141 ProtobufCBinaryData srcip;
142 ProtobufCBinaryData dstip;
147 ncap_msg_load(nmsg_message_t m,
void **msg_clos) {
148 Nmsg__Base__Ncap *ncap;
150 const struct ip6_hdr *ip6;
156 if (ncap == NULL || ncap->payload.data == NULL || ncap->payload.len == 0)
159 *msg_clos = p = calloc(1,
sizeof(
struct ncap_priv));
164 switch (ncap->type) {
165 case NMSG__BASE__NCAP_TYPE__IPV4:
166 etype = ETHERTYPE_IP;
168 ip = (
const struct nmsg_iphdr *) p->dg.network;
173 p->srcip.data = (uint8_t *) &ip->ip_src;
174 p->dstip.data = (uint8_t *) &ip->ip_dst;
177 case NMSG__BASE__NCAP_TYPE__IPV6:
178 etype = ETHERTYPE_IPV6;
180 ip6 = (
const struct ip6_hdr *) p->dg.network;
185 p->srcip.data = (uint8_t *) &ip6->ip6_src;
186 p->dstip.data = (uint8_t *) &ip6->ip6_dst;
187 p->proto = ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
189 case NMSG__BASE__NCAP_TYPE__Legacy:
196 switch (ncap->type) {
197 case NMSG__BASE__NCAP_TYPE__IPV4:
198 case NMSG__BASE__NCAP_TYPE__IPV6:
199 switch (p->dg.proto_transport) {
201 udp = (
const struct nmsg_udphdr *) p->dg.transport;
202 p->has_srcport =
true;
203 p->has_dstport =
true;
204 p->srcport = ntohs(udp->uh_sport);
205 p->dstport = ntohs(udp->uh_dport);
209 case NMSG__BASE__NCAP_TYPE__Legacy:
210 switch (ncap->ltype) {
211 case NMSG__BASE__NCAP_LEGACY_TYPE__UDP:
212 case NMSG__BASE__NCAP_LEGACY_TYPE__TCP:
213 if (ncap->has_lint0) {
214 p->has_srcport =
true;
215 p->srcport = ncap->lint0;
217 if (ncap->has_lint1) {
218 p->has_dstport =
true;
219 p->dstport = ncap->lint1;
221 case NMSG__BASE__NCAP_LEGACY_TYPE__ICMP:
226 switch (ncap->ltype) {
227 case NMSG__BASE__NCAP_LEGACY_TYPE__UDP:
228 p->proto = IPPROTO_UDP;
230 case NMSG__BASE__NCAP_LEGACY_TYPE__TCP:
231 p->proto = IPPROTO_TCP;
233 case NMSG__BASE__NCAP_LEGACY_TYPE__ICMP:
234 p->proto = IPPROTO_ICMP;
248 ncap_msg_fini(nmsg_message_t m,
void *msg_clos) {
254 ncap_get_srcip(nmsg_message_t m,
262 struct ncap_priv *p = msg_clos;
264 if (ncap == NULL || p == NULL)
268 switch (ncap->type) {
269 case NMSG__BASE__NCAP_TYPE__IPV4:
270 case NMSG__BASE__NCAP_TYPE__IPV6:
271 *data = p->srcip.data;
275 case NMSG__BASE__NCAP_TYPE__Legacy:
276 if (ncap->has_srcip) {
277 *data = ncap->srcip.data;
279 *len = ncap->srcip.len;
292 ncap_get_dstip(nmsg_message_t m,
300 struct ncap_priv *p = msg_clos;
302 if (ncap == NULL || p == NULL)
306 switch (ncap->type) {
307 case NMSG__BASE__NCAP_TYPE__IPV4:
308 case NMSG__BASE__NCAP_TYPE__IPV6:
309 *data = p->dstip.data;
313 case NMSG__BASE__NCAP_TYPE__Legacy:
314 if (ncap->has_dstip) {
315 *data = ncap->dstip.data;
317 *len = ncap->dstip.len;
330 ncap_get_srcport(nmsg_message_t m,
337 struct ncap_priv *p = msg_clos;
339 if (p != NULL && val_idx == 0 && p->has_srcport) {
342 *len =
sizeof(p->srcport);
350 ncap_get_dstport(nmsg_message_t m,
357 struct ncap_priv *p = msg_clos;
359 if (p != NULL && val_idx == 0 && p->has_dstport) {
362 *len =
sizeof(p->dstport);
370 ncap_get_proto(nmsg_message_t m,
377 struct ncap_priv *p = msg_clos;
379 if (p != NULL && val_idx == 0) {
382 *len =
sizeof(p->proto);
390 ncap_get_dns(nmsg_message_t m,
398 struct ncap_priv *p = msg_clos;
400 if (ncap == NULL || p == NULL)
406 if (p->srcport == 53 || p->srcport == 5353 ||
407 p->dstport == 53 || p->dstport == 5353)
409 switch (ncap->type) {
410 case NMSG__BASE__NCAP_TYPE__IPV4:
411 case NMSG__BASE__NCAP_TYPE__IPV6:
412 *data = (
void *) p->dg.payload;
414 *len = p->dg.len_payload;
417 case NMSG__BASE__NCAP_TYPE__Legacy:
418 *data = (
void *) ncap->payload.data;
420 *len = ncap->payload.len;
431 ncap_pbuf_inet_ntop(ProtobufCBinaryData *bdata,
char *str) {
432 socklen_t strsz = INET6_ADDRSTRLEN;
434 if (bdata->len == 4) {
435 if (inet_ntop(AF_INET, bdata->data, str, strsz) == NULL)
437 }
else if (bdata->len == 16) {
438 if (inet_ntop(AF_INET6, bdata->data, str, strsz) == NULL)
446 ncap_print_udp(nmsg_strbuf_t sb,
const char *srcip,
const char *dstip,
447 uint16_t srcport, uint16_t dstport,
448 const u_char *payload,
size_t paylen,
const char *el)
455 srcip, srcport, dstip, dstport, paylen, el);
459 if (srcport == 53 || srcport == 5353 ||
460 dstport == 53 || dstport == 5353)
466 status = wdns_parse_message(&m, payload, paylen);
467 if (status != wdns_res_success)
469 s = wdns_message_to_str(&m);
475 wdns_clear_message(&m);
485 ncap_print_payload(nmsg_message_t msg,
487 void *ptr __attribute__((unused)),
491 Nmsg__Base__Ncap *ncap;
492 char dstip[INET6_ADDRSTRLEN];
493 char srcip[INET6_ADDRSTRLEN];
494 const char *err_str =
"unknown";
496 const struct ip6_hdr *ip6;
503 if (ncap == NULL || ncap->payload.data == NULL || ncap->payload.len == 0) {
516 switch (ncap->type) {
517 case NMSG__BASE__NCAP_TYPE__IPV4:
518 etype = ETHERTYPE_IP;
521 inet_ntop(AF_INET, &ip->ip_src, srcip,
sizeof(srcip));
522 inet_ntop(AF_INET, &ip->ip_dst, dstip,
sizeof(dstip));
524 case NMSG__BASE__NCAP_TYPE__IPV6:
525 etype = ETHERTYPE_IPV6;
527 ip6 = (
const struct ip6_hdr *) dg.network;
528 inet_ntop(AF_INET6, ip6->ip6_src.s6_addr, srcip,
sizeof(srcip));
529 inet_ntop(AF_INET6, ip6->ip6_dst.s6_addr, dstip,
sizeof(dstip));
531 case NMSG__BASE__NCAP_TYPE__Legacy:
532 if (ncap->has_srcip == 0) {
533 err_str =
"legacy ncap payload missing srcip field";
536 if (ncap->has_dstip == 0) {
537 err_str =
"legacy ncap payload missing dstip field";
542 err_str =
"unable to decode legacy ncap srcip field";
547 err_str =
"unable to decode legacy ncap dstip field";
552 goto unknown_ncap_type;
557 switch (ncap->type) {
558 case NMSG__BASE__NCAP_TYPE__IPV4:
559 case NMSG__BASE__NCAP_TYPE__IPV6:
560 switch (dg.proto_transport) {
563 res = ncap_print_udp(sb, srcip, dstip,
564 ntohs(udp->uh_sport),
565 ntohs(udp->uh_dport),
566 dg.payload, dg.len_payload, endline);
568 err_str =
"payload parse failed";
574 case NMSG__BASE__NCAP_TYPE__Legacy:
575 switch (ncap->ltype) {
576 case NMSG__BASE__NCAP_LEGACY_TYPE__UDP:
577 if (ncap->has_lint0 == 0) {
578 err_str =
"legacy ncap payload missing lint0 field";
581 if (ncap->has_lint1 == 0) {
582 err_str =
"legacy ncap payload missing lint1 field";
585 res = ncap_print_udp(sb, srcip, dstip,
586 ncap->lint0, ncap->lint1,
588 ncap->payload.len, endline);
590 err_str =
"legacy payload parse failed";
594 case NMSG__BASE__NCAP_LEGACY_TYPE__TCP:
595 case NMSG__BASE__NCAP_LEGACY_TYPE__ICMP:
597 ncap->ltype, endline);
605 goto unknown_ncap_type;
617 ncap->type, endline);
622 ncap_ipdg_to_payload(
void *clos __attribute__((unused)),
624 uint8_t **pbuf,
size_t *sz)
630 nmsg__base__ncap__init(&nc);
635 nc.type = NMSG__BASE__NCAP_TYPE__IPV4;
638 nc.type = NMSG__BASE__NCAP_TYPE__IPV6;
645 nc.payload.data = (uint8_t *) dg->
network;
649 estsz = nc.payload.len + 64 ;
650 *pbuf = malloc(estsz);
653 *sz = nmsg__base__ncap__pack(&nc, *pbuf);
Structure exported by message modules to implement a new message type.
unsigned len_network
length starting from network
nmsg_res nmsg_ipdg_parse(struct nmsg_ipdg *dg, unsigned etype, size_t len, const u_char *pkt)
Parse IP packets from the network layer, discarding fragments.
Structure mapping protocol buffer schema fields to nmsg_msgmod_field_type values for "transparent" mo...
#define NMSG_MSGMOD_FIELD_HIDDEN
hide field from the message API
const u_char * network
pointer to network header
a pbuf is ready to be written
nmsg_msgmod_field_type type
Intended (nmsg) type of this protobuf field.
void * nmsg_message_get_payload(nmsg_message_t msg)
WARNING: experts only.
#define NMSG_MSGMOD_FIELD_REQUIRED
field is required
int proto_network
PF_* value.
#define NMSG_MSGMOD_FIELD_NOPRINT
don't print the field
nmsg_res nmsg_strbuf_append(struct nmsg_strbuf *sb, const char *fmt,...)
Append to a string buffer.