/*
* Class: com_zjwang_snmp_Snmp
* Method: get
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/JNIEXPORTjstringJNICALLsnmp_get(JNIEnv*env,jclassobj,jstringjPeer,jstringjCommunity,jstringjOid){char*peer=(char*)(*env)->GetStringUTFChars(env,jPeer,0);char*community=(char*)(*env)->GetStringUTFChars(env,jCommunity,0);char*oid=(char*)(*env)->GetStringUTFChars(env,jOid,0);LOGD("called snmp_get %s %s %s",peer,community,oid);char*read_buffer=malloc(256);if(read_buffer==NULL){printf("error, no memory\n");exit(1);}memset(read_buffer,0,256);get(peer,community,oid,read_buffer);// 这是实际干活的函数
(*env)->ReleaseStringUTFChars(env,jPeer,peer);(*env)->ReleaseStringUTFChars(env,jCommunity,community);(*env)->ReleaseStringUTFChars(env,jOid,oid);return(*env)->NewStringUTF(env,read_buffer);}// 这个函数是参考了Net-SNMP的例子
// See: http://www.net-snmp.org/wiki/index.php/TUT:Simple_Application
intget(constchar*peer,constchar*community,constchar*id,char*result){netsnmp_sessionsession,*ss;netsnmp_pdu*pdu;netsnmp_pdu*response;oidanOID[MAX_OID_LEN];size_tanOID_len;netsnmp_variable_list*vars;intstatus;intcount=1;u_char*buf=NULL;size_tbuf_len=256,out_len=0;if((buf=(u_char*)calloc(buf_len,1))==NULL){sprintf(result,"[ERROR][no memory]\n");return-1;}// Initialize the SNMP library
init_snmp("snmpdemoapp");// Initialize a "session" that defines who we're going to talk to
snmp_sess_init(&session);// set up defaults
session.peername=strdup(peer);// set up the authentication parameters for talking to the server
#ifdef DEMO_USE_SNMP_VERSION_3
/* Use SNMPv3 to talk to the experimental server *//* set the SNMP version number */session.version=SNMP_VERSION_3;/* set the SNMPv3 user name */session.securityName=strdup("MD5User");session.securityNameLen=strlen(session.securityName);/* set the security level to authenticated, but not encrypted */session.securityLevel=SNMP_SEC_LEVEL_AUTHNOPRIV;/* set the authentication method to MD5 */session.securityAuthProto=usmHMACMD5AuthProtocol;session.securityAuthProtoLen=sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);session.securityAuthKeyLen=USM_AUTH_KU_LEN;/* set the authentication key to a MD5 hashed version of our
passphrase "The Net-SNMP Demo Password" (which must be at least 8
characters long) */if(generate_Ku(session.securityAuthProto,session.securityAuthProtoLen,(u_char*)our_v3_passphrase,strlen(our_v3_passphrase),session.securityAuthKey,&session.securityAuthKeyLen)!=SNMPERR_SUCCESS){snmp_perror(argv[0]);snmp_log(LOG_ERR,"Error generating Ku from authentication pass phrase. \n");exit(1);}#else /* we'll use the insecure (but simplier) SNMPv1 *//* set the SNMP version number */session.version=SNMP_VERSION_2c;/* set the SNMPv1 community name used for authentication */session.community=community;session.community_len=strlen(session.community);#endif /* SNMPv1 */ss=snmp_open(&session);// establish the session
if(!ss){snmp_sess_perror("ack",&session);memcpy(result,"[ERROR] snmp session open error",strlen("[ERROR] snmp session open error"));LOGE("[ERROR] snmp session open error");return-1;}/*
* Create the PDU for the data for our request.
* 1) We're going to GET the system.sysDescr.0 node.
*/pdu=snmp_pdu_create(SNMP_MSG_GET);anOID_len=MAX_OID_LEN;if(!snmp_parse_oid(id,anOID,&anOID_len)){snmp_perror(id);memcpy(result,"[ERROR] oid parse error",strlen("[ERROR] oid parse error"));DEBUG_WHEREclean_up(ss,response);return-1;}snmp_add_null_var(pdu,anOID,anOID_len);//Send the Request out.
status=snmp_synch_response(ss,pdu,&response);// SUCCESS: Print the result variables
if(status==STAT_SUCCESS&&response->errstat==SNMP_ERR_NOERROR){// TODO: 如果入参oid是一个值,则结果也只会有一个值,暂时保留for循环,以便后续查询多个值
for(vars=response->variables;vars;vars=vars->next_variable){print_variable(vars->name,vars->name_length,vars);if(sprint_realloc_variable(&buf,&buf_len,&out_len,1,anOID,anOID_len,response->variables)){LOGD("sprint_realloc_variable: got response->variables = %s",buf);memcpy(result,buf,out_len);}else{LOGD("[ERROR]sprint_realloc_variable failed");memcpy(result,"[ERROR] parse response failed...",30);DEBUG_WHEREclean_up(ss,response);return-1;}}}// FAILURE: print what went wrong!
else{if(status==STAT_SUCCESS)fprintf(stderr,"Error in packet\nReason: %s\n",snmp_errstring(response->errstat));elseif(status==STAT_TIMEOUT)fprintf(stderr,"Timeout: No response from %s.\n",session.peername);else{snmp_sess_perror("snmpdemoapp",ss);}LOGD("[ERROR]snmp_synch_response failed");memcpy(result,"[ERROR]snmp_synch_response failed",strlen("[ERROR]snmp_synch_response failed"));DEBUG_WHEREclean_up(ss,response);return-1;}DEBUG_WHEREclean_up(ss,response);return(0);}voidclean_up(netsnmp_session*ss,netsnmp_pdu*response){if(response)snmp_free_pdu(response);if(ss)snmp_close(ss);}
cmake_minimum_required(VERSION3.22.1)# Declares the project name
project("snmp")add_library(${CMAKE_PROJECT_NAME}SHARED# List C/C++ source files with relative paths to this CMakeLists.txt.
snmp.c)add_library(netsnmpSHAREDIMPORTED)set_target_properties(netsnmpPROPERTIESIMPORTED_LOCATION${CMAKE_SOURCE_DIR}/net-snmp-libs/${ANDROID_ABI}/libnetsnmp.so)target_include_directories(${CMAKE_PROJECT_NAME}PUBLIC${CMAKE_SOURCE_DIR}/include)set_target_properties(netsnmpPROPERTIESIMPORTED_NO_SONAME1)find_library(# Sets the name of the path variable.
log-lib# Specifies the name of the NDK library that
# you want CMake to locate.
log)# Specifies libraries CMake should link to your target library. You
# can link libraries from various origins, such as libraries defined in this
# build script, prebuilt third-party libraries, or Android system libraries.
target_link_libraries(${CMAKE_PROJECT_NAME}# List libraries link to the target library
android${log-lib}# 第三方so库
netsnmp)