/* * Create two connections to bent pipe and make sure they reflect */ LONGBOW_TEST_CASE(System, two_connections) { struct fdstate state[CONN_COUNT]; fd_set fdset, readset; int number_writes = 100; int count_writes = 0; int i; struct timeval timeout = { 0, 10000 }; unsigned pending_expected = 0; assertNotNull(system_bp, "%s running with null system_bp\n", __func__); FD_ZERO(&fdset); for (i = 0; i < CONN_COUNT; i++) { memset(&state[i], 0, sizeof(struct fdstate)); state[i].fd = connect_to_bentpipe(local_name); FD_SET(state[i].fd, &fdset); } sleep(1); assertTrue(system_bp->conn_count == CONN_COUNT, "bp conn count wrong"); while (count_writes < number_writes || pending_expected > 0) { int res; memcpy(&readset, &fdset, sizeof(readset)); res = select(FD_SETSIZE, &readset, NULL, NULL, &timeout); if (res < 0) { perror("select"); abort(); } if (res > 0) { if (CHATTY) { printf("%s got res %d\n", __func__, res); } for (i = 0; i < CONN_COUNT; i++) { if (FD_ISSET(state[i].fd, &readset)) { ssize_t res; localhdr *hdr = (localhdr *) state[i].pbuff; if (state[i].total_read_length == 0) { size_t remaining = sizeof(localhdr) - state[i].current_read_length; // we need to read a header res = read(state[i].fd, state[i].pbuff + state[i].current_read_length, remaining); assertFalse(res < 0, "%s got read error: %s", __func__, strerror(errno)); state[i].current_read_length += res; if (state[i].current_read_length == sizeof(localhdr)) { state[i].total_read_length = sizeof(localhdr) + hdr->length; if (CHATTY) { printf("%s conn %d fd %d set total length %zu\n", __func__, i, state[i].fd, state[i].total_read_length); } } } if (state[i].current_read_length < state[i].total_read_length) { size_t remaining = state[i].total_read_length - state[i].current_read_length; // we need to read a header res = read(state[i].fd, state[i].pbuff + state[i].current_read_length, remaining); assertFalse(res < 0, "%s got read error: %s", __func__, strerror(errno)); state[i].current_read_length += res; } if (state[i].current_read_length == state[i].total_read_length) { // verify that it's the same as the top expected stack res = compare_sends(&state[i], state[i].pbuff, state[i].total_read_length); assertTrue(res == 0, "%s invalid receive compare\n", __func__); state[i].count_recv++; state[i].count_expected--; if (CHATTY) { printf("%s conn %d fd %d cnt_recv %u cnt_expected %u\n", __func__, i, state[i].fd, state[i].count_recv, state[i].count_expected); } // done with it state[i].current_read_length = 0; state[i].total_read_length = 0; } } } } if ((random() % 4) == 0) { // do a write int out = random() % CONN_COUNT; if (CHATTY) { printf("%s sendbuffer for conn %d fd %d\n", __func__, out, state[out].fd); } sendbuffer(state[out].fd, state); count_writes++; } pending_expected = 0; for (i = 0; i < CONN_COUNT; i++) { pending_expected += state[i].count_expected; } } for (i = 0; i < CONN_COUNT; i++) { printf("conn %2d fd %2d send %4u recv %4u\n", i, state[i].fd, state[i].count_send, state[i].count_recv); assertTrue(state[i].count_recv == number_writes - state[i].count_send + 1, "%s conn %d incorrect counts\n", __func__); close(state[i].fd); } }
// Send a report message. int v3MP::send_report(unsigned char* scopedPDU, int scopedPDULength, struct snmp_pdu *pdu, int errorCode, int sLevel, int sModel, OctetStr &sName, UdpAddress &destination, Snmp *snmp_session) { debugprintf(2, "v3MP::send_report: Sending report message."); unsigned char *data; int dataLength; int pdu_type = 0; unsigned char cEngineID[MAXLENGTH_ENGINEID+1]; unsigned char cName[MAXLENGTH_CONTEXT_NAME+1]; int cEngineIDLength = MAXLENGTH_ENGINEID+1; int cNameLength = MAXLENGTH_CONTEXT_NAME+1; debugprintf(2, "v3MP::send_report: securityLevel %d",sLevel); if (scopedPDULength != MAX_SNMP_PACKET) { // try to get scopedPDU and PDU data = asn1_parse_scoped_pdu(scopedPDU, &scopedPDULength, cEngineID, &cEngineIDLength, cName, &cNameLength); if (data == NULL) { debugprintf(1, "mp: Error while trying to parse scopedPDU!"); cEngineID[0] = '\0'; cEngineIDLength = 0; cName[0] = '\0'; cNameLength = 0; // Dont send encrypted report if decryption failed: //if (sLevel == SNMP_SECURITY_LEVEL_AUTH_PRIV) // sLevel = SNMP_SECURITY_LEVEL_AUTH_NOPRIV; } else { // data != NULL dataLength = scopedPDULength; // parse data of scopedPDU snmp_parse_data_pdu(pdu, data, dataLength); pdu_type = pdu->command; if (!data) { debugprintf(0, "mp: Error while trying to parse PDU!"); } } // end of: if (data == NULL) } // end if (scopedPDULength != MAX_SNMP_PACKET) else { // scopedPDULength == MAX_SNMP_PACKET cEngineID[0] = '\0'; cEngineIDLength = 0; cName[0] = '\0'; cNameLength = 0; pdu->reqid = 0; } clear_pdu(pdu); // Clear pdu and free all content debugprintf(4, "pdu->reqid = %ld",pdu->reqid); pdu->errstat = 0; pdu->errindex = 0; pdu->command = REPORT_MSG; Vb counterVb; Oid counterOid; SmiLPOID smioid; SmiVALUE smival; switch (errorCode) { case SNMPv3_MP_INVALID_MESSAGE: case SNMPv3_USM_PARSE_ERROR: { counterVb.set_oid(oidSnmpInvalidMsgs); counterVb.set_value(Counter32(get_stats_invalid_msgs())); break; } case SNMPv3_USM_NOT_IN_TIME_WINDOW: case SNMPv3_MP_NOT_IN_TIME_WINDOW: { counterVb.set_oid(oidUsmStatsNotInTimeWindows); counterVb.set_value(Counter32(usm->get_stats_not_in_time_windows())); break; } case SNMPv3_USM_DECRYPTION_ERROR: { counterVb.set_oid(oidUsmStatsDecryptionErrors); counterVb.set_value(Counter32(usm->get_stats_decryption_errors())); //sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } case SNMPv3_USM_AUTHENTICATION_ERROR: case SNMPv3_USM_AUTHENTICATION_FAILURE: { counterVb.set_oid(oidUsmStatsWrongDigests); counterVb.set_value(Counter32(usm->get_stats_wrong_digests())); //sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } case SNMPv3_USM_UNKNOWN_ENGINEID: case SNMPv3_MP_INVALID_ENGINEID: { //sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; counterVb.set_oid(oidUsmStatsUnknownEngineIDs); counterVb.set_value(Counter32(usm->get_stats_unknown_engine_ids())); break; } case SNMPv3_MP_UNSUPPORTED_SECURITY_MODEL: { counterVb.set_oid(oidSnmpUnknownSecurityModels); counterVb.set_value(Counter32(get_stats_unknown_security_models())); sModel = SNMP_SECURITY_MODEL_USM; sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } case SNMPv3_USM_UNKNOWN_SECURITY_NAME: { counterVb.set_oid(oidUsmStatsUnknownUserNames); counterVb.set_value(Counter32(usm->get_stats_unknown_user_names())); sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; debugprintf(2, "Report: SecurityName: %s",sName.get_printable()); break; } case SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL: { counterVb.set_oid(oidUsmStatsUnsupportedSecLevels); counterVb.set_value(Counter32(usm->get_stats_unsupported_sec_levels())); sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; break; } default: { counterVb.set_oid(oidSnmpInvalidMsgs); counterVb.set_value(Counter32(get_stats_invalid_msgs())); sModel = SNMP_SECURITY_MODEL_USM; sLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; sName.set_data(0, 0); debugprintf(2, "ErrorCode was %i in snmp_parse", errorCode); } } // end switch counterVb.get_oid(counterOid); smioid = counterOid.oidval(); int status = convertVbToSmival(counterVb, &smival); if (status != SNMP_CLASS_SUCCESS) { return SNMPv3_MP_ERROR; } snmp_add_var(pdu, smioid->ptr, (int) smioid->len, &smival); freeSmivalDescriptor(&smival); Buffer<unsigned char> sendbuffer(MAX_SNMP_PACKET); int sendbufferlen= MAX_SNMP_PACKET; status = snmp_build( pdu, sendbuffer.get_ptr(), &sendbufferlen, own_engine_id_oct, sName, sModel, sLevel, OctetStr(cEngineID, cEngineIDLength), OctetStr(cName, cNameLength)); if (status != SNMPv3_MP_OK) { debugprintf(2, "v3MP::send_report: error serializing message (mpSnmpBuild returns: %i).", status); return SNMPv3_MP_ERROR; } SnmpSocket send_fd = INVALID_SOCKET; if (pdu_type == sNMP_PDU_INFORM) { debugprintf(4, "Received a snmpInform pdu."); if (snmp_session->get_eventListHolder()->notifyEventList()) send_fd = snmp_session->get_eventListHolder()->notifyEventList()->get_notify_fd(); } status = snmp_session->send_raw_data(sendbuffer.get_ptr(), (size_t)sendbufferlen,// pdu to send destination, // target address send_fd); // the fd to use if ( status != 0) { debugprintf(1, "v3MP::send_report: error sending message (%i)", status); return SNMPv3_MP_ERROR; } debugprintf(3, "v3MP::send_report: Report sent."); return SNMPv3_MP_OK; }