
Index: net-snmp-5.4.2.1/apps/snmptrapd_handlers.c
===================================================================
--- net-snmp-5.4.2.1.orig/apps/snmptrapd_handlers.c
+++ net-snmp-5.4.2.1/apps/snmptrapd_handlers.c
@@ -990,6 +990,12 @@ int   forward_handler( netsnmp_pdu
     netsnmp_pdu *pdu2;
     char buf[BUFSIZ], *cp;
 
+    int last_snmpTrapAddress_index = -1;  /* .0  in .1.3.6.1.6.3.18.1.3 .0 */
+    const oid      snmpTrapAddress_oid[]   = { 1,3,6,1,6,3,18,1,3};  /* snmpTrapAddress_oid.0 is also defined as agentaddr_oid */
+    oid            forwarder_oid[]   =       { 1,3,6,1,6,3,18,1,3,0};  /* each forwarder will add this OID with changed last index */
+    const size_t   snmpTrapAddress_oid_size = OID_LENGTH(snmpTrapAddress_oid);
+    const size_t   forwarder_oid_len = OID_LENGTH(forwarder_oid);
+
     DEBUGMSGTL(( "snmptrapd", "forward_handler (%s)\n", handler->token));
 
     snmp_sess_init( &session );
@@ -1010,6 +1016,71 @@ int   forward_handler( netsnmp_pdu
        INFORMS which may require engineID probing */
 
     pdu2 = snmp_clone_pdu(pdu);
+
+    //  bsc#1116807
+    struct sockaddr_in *to1 = NULL;
+    netsnmp_udp_addr_pair *addr_pair =  NULL;
+    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+                               NETSNMP_DS_LIB_ADD_FORWARDER_INFO)) {
+        if (pdu && pdu->transport_data) {
+            addr_pair = (netsnmp_udp_addr_pair *) pdu->transport_data;
+            if (addr_pair != NULL) {
+		/* get the IP address of the host, that this trap was sent to = this forwarder's IP address */
+                to1 = (struct sockaddr_in *) &(addr_pair->remote_addr);
+	    }
+	}
+
+        if (NULL != to1)
+        {
+            char agent_addr[5] = "0000";  /* store the decoded IP address here */
+            agent_addr[3] = (to1->sin_addr.s_addr >> 24) & 0xFF;
+            agent_addr[2] = (to1->sin_addr.s_addr >> 16) & 0xFF;
+            agent_addr[1] = (to1->sin_addr.s_addr >> 8) & 0xFF;
+            agent_addr[0] = (to1->sin_addr.s_addr) & 0xFF;
+            if (pdu2->agent_addr[0] == 0 && pdu2->agent_addr[1] == 0 && pdu2->agent_addr[2] == 0 && pdu2->agent_addr[3] == 0)  //agent_addr is "0.0.0.0"
+            {  /* there was no agent address defined in PDU */
+                memcpy (pdu2->agent_addr, agent_addr, 4);  /* copy the forwarding agent IP address from the transport socket. */
+            }
+            else
+            { /*  there is already agent address in PDU*/
+	                /* do nothing */
+            }
+
+            netsnmp_variable_list *var = NULL;
+            netsnmp_variable_list *vblist = NULL;
+            vblist = pdu2->variables;
+
+            /* go via all OIDs in the payload, to see if the info about forwarder is already there - look for snmpTrapAddress_oid.x */
+            for (var = vblist; var; var = var->next_variable) {
+                if (var) {
+                    if (!snmp_oid_ncompare(var->name, var->name_length,
+                        snmpTrapAddress_oid, snmpTrapAddress_oid_size, snmpTrapAddress_oid_size))
+                    {
+                        int my_last_snmpTrapAddress_index = var->name[var->name_length];  /* .x  in .1.3.6.1.6.3.18.1.3.x */
+                        if (last_snmpTrapAddress_index < my_last_snmpTrapAddress_index)
+                            last_snmpTrapAddress_index = my_last_snmpTrapAddress_index;  /* in case the indexes are out-of-order in PDU */
+
+                        forwarder_oid [forwarder_oid_len-1] = last_snmpTrapAddress_index+1;  // indexing starts from zero, so at last index, insert next number for forwarder IP address
+                    }
+                } /* var is not NULL */
+            } /* for var in vblist */
+
+
+            forwarder_oid [forwarder_oid_len-1] = last_snmpTrapAddress_index+1;  /* change the last index of this OID to the next avaiable number. Indexing starts from zero, that is why forwarder_oid_len-1 */
+
+
+            /*add forwarder IP address as OID to trap payload */
+
+/*            snmp_pdu_add_variable(pdu2, forwarder_oid, forwarder_oid_len,
+                ASN_IPADDRESS, (u_char*)&pdu2->agent_addr, 4); */
+
+            /* use the value from transport, so if v1 PDU is sent, the same IP is not duplicated
+               - you want every forwarder to add this OID with its own IP address */
+            snmp_pdu_add_variable(pdu2, forwarder_oid, forwarder_oid_len,
+                ASN_IPADDRESS, (u_char*)agent_addr, 4);
+        }
+    }   /* NETSNMP_DS_LIB_ADD_FORWARDER_INFO is defined as true */
+
     if (pdu2->transport_data) {
         free(pdu2->transport_data);
         pdu2->transport_data        = NULL;
Index: net-snmp-5.4.2.1/apps/snmptrapd.c
===================================================================
--- net-snmp-5.4.2.1.orig/apps/snmptrapd.c
+++ net-snmp-5.4.2.1/apps/snmptrapd.c
@@ -308,6 +308,7 @@ usage(void)
     fprintf(stderr, "\tWeb:      http://www.net-snmp.org/\n");
     fprintf(stderr, "\tEmail:    net-snmp-coders@lists.sourceforge.net\n");
     fprintf(stderr, "\n");
+    fprintf(stderr, "  --add-forwarder-info\tadd info to SNMP payload about forwarder\n");
     fprintf(stderr, "  -a\t\t\tignore authentication failure traps\n");
     fprintf(stderr, "  -A\t\t\tappend to log file rather than truncating it\n");
     fprintf(stderr, "  -c FILE\t\tread FILE as a configuration file\n");
@@ -475,6 +476,15 @@ snmptrapd_add_session(netsnmp_transport
     return rc;
 }
 
+void
+parse_config_addForwarderInfo(const char *token, char *cptr)
+{
+  if (netsnmp_ds_parse_boolean(cptr) == 1) {
+    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+                           NETSNMP_DS_LIB_ADD_FORWARDER_INFO, 1);
+  }
+}
+
 static void
 snmptrapd_close_sessions(netsnmp_session * sess_list)
 {
@@ -701,6 +711,11 @@ main(int argc, char *argv[])
     signal(SIGHUP, SIG_IGN);   /* do not terminate on early SIGHUP */
 #endif
 
+    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+                           NETSNMP_DS_LIB_ADD_FORWARDER_INFO, 0);
+    register_config_handler("snmptrapd", "addForwarderInfo",
+                            parse_config_addForwarderInfo, NULL, "(1|yes|true|0|no|false)");
+
     /*
      * register our configuration handlers now so -H properly displays them 
      */
@@ -771,6 +786,11 @@ main(int argc, char *argv[])
                 version();
                 exit(0);
             }
+            if (strcasecmp(optarg, "add-forwarder-info") == 0) {
+                netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+                                       NETSNMP_DS_LIB_ADD_FORWARDER_INFO, 1);
+		break;
+            }
 
             handle_long_opt(optarg);
             break;
Index: net-snmp-5.4.2.1/include/net-snmp/library/default_store.h
===================================================================
--- net-snmp-5.4.2.1.orig/include/net-snmp/library/default_store.h
+++ net-snmp-5.4.2.1/include/net-snmp/library/default_store.h
@@ -87,6 +87,7 @@ extern          "C" {
 #define NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD  35 /* don't load persistent file */
 #define NETSNMP_DS_LIB_DISABLE_PERSISTENT_SAVE  36 /* don't save persistent file */
 #define NETSNMP_DS_LIB_APPEND_LOGFILES     37 /* append, don't overwrite, log files */
+#define NETSNMP_DS_LIB_ADD_FORWARDER_INFO   38 /* add info about forwarder to SNMP packets */
 
     /*
      * library integers 
Index: net-snmp-5.4.2.1/include/net-snmp/library/snmpUDPDomain.h
===================================================================
--- net-snmp-5.4.2.1.orig/include/net-snmp/library/snmpUDPDomain.h
+++ net-snmp-5.4.2.1/include/net-snmp/library/snmpUDPDomain.h
@@ -15,6 +15,12 @@ extern          "C" {
 #include <netinet/in.h>
 #endif
 
+typedef struct netsnmp_udp_addr_pair_s {
+    struct sockaddr_in remote_addr;
+    struct in_addr local_addr;
+} netsnmp_udp_addr_pair;
+
+
 netsnmp_transport *netsnmp_udp_transport(struct sockaddr_in *addr, int local);
 
 
Index: net-snmp-5.4.2.1/snmplib/snmpUDPDomain.c
===================================================================
--- net-snmp-5.4.2.1.orig/snmplib/snmpUDPDomain.c
+++ net-snmp-5.4.2.1/snmplib/snmpUDPDomain.c
@@ -67,11 +67,6 @@
 
 static netsnmp_tdomain udpDomain;
 
-typedef struct netsnmp_udp_addr_pair_s {
-    struct sockaddr_in remote_addr;
-    struct in_addr local_addr;
-} netsnmp_udp_addr_pair;
-
 /*
  * not static, since snmpUDPIPv6Domain needs it, but not public, either.
  * (ie don't put it in a public header.)
Index: net-snmp-5.4.2.1/snmplib/snmpTCPDomain.c
===================================================================
--- net-snmp-5.4.2.1.orig/snmplib/snmpTCPDomain.c
+++ net-snmp-5.4.2.1/snmplib/snmpTCPDomain.c
@@ -44,12 +44,6 @@
 #include <net-snmp/library/snmpUDPDomain.h>
 #include <net-snmp/library/snmpTCPDomain.h>
 
-/* Copied from snmpUDPDomain.c */
-typedef struct netsnmp_udp_addr_pair_s {
-    struct sockaddr_in remote_addr;
-    struct in_addr local_addr;
-} netsnmp_udp_addr_pair;
-
 oid netsnmp_snmpTCPDomain[] = { TRANSPORT_DOMAIN_TCP_IP };
 static netsnmp_tdomain tcpDomain;
 
