We've encountered unexpected behavior with sockaddr_in (old api) not netsnmp_indexed_addr_pair in pdu->transport_data used in PDU send via snmp_sess_send (UDP transport).
In such scenario we fall in line 450, where sockaddr_in of size 16 bytes will be casted to netsnmp_indexed_addr_pair of size 36 bytes, where 17+ bytes will be actually random values.
Because of that to from line 456 will be set correctly, but second and third argument to the netsnmp_udp_sendto will be random values.
IMHO the lines 469 and 470 should looks like the following:
469 (*olength == sizeof(netsnmp_indexed_addr_pair)) ? &(addr_pair->local_addr.sin.sin_addr) : NULL, 470 (*olength == sizeof(netsnmp_indexed_addr_pair)) ? addr_pair->if_index : 0, to, buf, size);
Also if you want to check addr_pair for NULL you should do that first in line:
456 to = &addr_pair->remote_addr.sa;
snmplib/transports/snmpUDPBaseDomain.c:
439 int 440 netsnmp_udpbase_send(netsnmp_transport *t, void *buf, int size, 441 void **opaque, int *olength) 442 { 443 int rc = -1; 444 netsnmp_indexed_addr_pair *addr_pair = NULL; 445 struct sockaddr *to = NULL; 446 447 if (opaque != NULL && *opaque != NULL && 448 ((*olength == sizeof(netsnmp_indexed_addr_pair) || 449 (*olength == sizeof(struct sockaddr_in))))) { 450 addr_pair = (netsnmp_indexed_addr_pair *) (*opaque); 451 } else if (t != NULL && t->data != NULL && 452 t->data_length == sizeof(netsnmp_indexed_addr_pair)) { 453 addr_pair = (netsnmp_indexed_addr_pair *) (t->data); 454 } 455 456 to = &addr_pair->remote_addr.sa; 457 458 if (to != NULL && t != NULL && t->sock >= 0) { 459 DEBUGIF("netsnmp_udp") { 460 char *str = netsnmp_udp_fmtaddr(NULL, (void *) addr_pair, 461 sizeof(netsnmp_indexed_addr_pair)); 462 DEBUGMSGTL(("netsnmp_udp", "send %d bytes from %p to %s on fd %d\n", 463 size, buf, str, t->sock)); 464 free(str); 465 } 466 while (rc < 0) { 467 #ifdef netsnmp_udpbase_recvfrom_sendto_defined 468 rc = netsnmp_udp_sendto(t->sock, 469 addr_pair ? &(addr_pair->local_addr.sin.sin_addr) : NULL, 470 addr_pair ? addr_pair->if_index : 0, to, buf, size); 471 #else 472 rc = sendto(t->sock, buf, size, 0, to, sizeof(struct sockaddr)); 473 #endif /* netsnmp_udpbase_recvfrom_sendto_defined */ 474 if (rc < 0 && errno != EINTR) { 475 DEBUGMSGTL(("netsnmp_udp", "sendto error, rc %d (errno %d)\n", 476 rc, errno)); 477 break; 478 } 479 } 480 } 481 return rc; 482 }
One another thing:
Should be replaced with: