@@ -871,6 +871,57 @@ translate_internal_odid(translator_t *trans)
871871 return 0 ;
872872}
873873
874+ /**
875+ * \brief Convert (fill) EXPORTER_IP field with IPv4 or IPv6 address from IPFIX
876+ * message session.
877+ *
878+ * \note This function uses a message context configured by the user. It's independent on the
879+ * content of an IPFIX record.
880+ * \param[in] trans Internal translator structure
881+ * \return On success returns 0. Otherwise returns non-zero value!
882+ */
883+ static int
884+ translate_internal_exporter_ip (translator_t * trans )
885+ {
886+ if (!trans -> msg_context .ctx ) {
887+ return 1 ; // Message context is not available!
888+ }
889+
890+ const struct ipx_session * session = trans -> msg_context .ctx -> session ;
891+
892+ const struct ipx_session_net * session_net ;
893+ switch (session -> type )
894+ {
895+ case FDS_SESSION_UDP :
896+ session_net = & session -> udp .net ;
897+ break ;
898+ case FDS_SESSION_TCP :
899+ session_net = & session -> tcp .net ;
900+ break ;
901+ case FDS_SESSION_SCTP :
902+ session_net = & session -> sctp .net ;
903+ break ;
904+ default :
905+ // Uncompatible type of message session. E.g. messages from file.
906+ return 1 ;
907+ }
908+
909+ // Get pointer to save result IP
910+ ur_field_type_t ur_id = trans -> extra_conv .exporter_ip .field_id ;
911+ void * field_ptr = ur_get_ptr_by_id (trans -> record .ur_tmplt , trans -> record .data , ur_id );
912+
913+ if (session -> udp .net .l3_proto == AF_INET ) {
914+ * ((ip_addr_t * ) field_ptr ) = ip_from_4_bytes_be ((char * ) & session_net -> addr_src .ipv4 .s_addr );
915+ } else if (session -> udp .net .l3_proto == AF_INET6 ) {
916+ * ((ip_addr_t * ) field_ptr ) = ip_from_16_bytes_be ((char * ) session_net -> addr_src .ipv6 .s6_addr );
917+ } else {
918+ // Unknown IP protocol
919+ return 1 ;
920+ }
921+
922+ return 0 ;
923+ }
924+
874925/**
875926 * \brief Get size of UniRec numeric data types
876927 * \param type UniRec data types
0 commit comments