Trap code Development Pit for SNMP

Source: Internet
Author: User

Recently by this SNMP trap to the pit, in fact, in retrospect, mainly on this do not understand. In particular, the study of SNMP protocol is not deep enough,

Really do not want to see these protocol things, just want to know about. The result was a hole in the development of the SNMP trap, with the following columns under its own tread:

1. The Chinese problem of SNMP trap

Originally in their own machine running very good, but the test said found garbled, the heart is not possible to call, the result is really, the original code is as follows:

if (Val_type.equals ("OCTET string")) {    // String type transcoding to prevent Chinese content   new  Else {    new  String (recvb.getvariable (). toString ());}

Charsetcode is the configured message encoding type, which shows that the Java string is Unicode encoded,

Description under:

If you want to get this string byte[] can be obtained by a similar: String.getbytes ("UTF-8").

if such string.getbytes (); is dependent on the JVM's character set encoding, which is generally GBK under Windows.

(To change the JVM default character set encoding, use the option-dfile.encodeing=utf-8 when starting the JVM)

Please do not set the following settings in the program:

System.getproperties (). SetProperty ("file.encoding", "GBK");

This solves the problem of the default encoding is not feasible!!! Not feasible!!! Not feasible!!!

GetBytes ()---->stringcoding.encode () and String CSN = Charset.defaultcharset (). Name ();

/** * Returns thedefaultCharSet of ThisJava virtual machine. * * <p> thedefaultCharSet is determined during virtual-Machine startup and*typically depends upon the locale and charset of the underlying*operating system. *     * @returnA CharSet Object forThedefaultCharSet* * @since 1.5 * * Public StaticCharset Defaultcharset () {if(Defaultcharset = =NULL) {            synchronized(Charset.class) {String CSN=accesscontroller.doprivileged (NewGetpropertyaction ("File.encoding")); Charset CS=lookup (CSN); if(cs! =NULL) Defaultcharset=CS; ElseDefaultcharset= forname ("UTF-8"); }        }        returnDefaultcharset; }

See, this is a static method, as long as the first run Defaultcharset this is not empty, the back is not related to file.encoding, so you basically you can not guarantee

You set before the first call, such as whether the Java other class library has already called GetBytes (), as long as the call code is fixed.

This problem caused me to test the client at the time, the configuration of the encoding and the actual transmission of the encoding is inconsistent, and then I know that can be run through the-DFILE.ENCODEING=UTF-8 option.

There is a simple way to print out the contents of the GetBytes, you can probably know what the Chinese characters are encoded:

System.out.println ("bytes:" +arrays.tostring (Strtmp.getbytes ()));

GBK are 2 bytes, while UTF-8 is generally 2 or three bytes representing a Chinese character.

2, the configuration file inside the project case

Flume configuration file, when reading is case-sensitive, so this do not write wrong, or ignore in the program, oneself unexpectedly be pit to, next to the configuration or ignore the case is good.

3, the V3 version of the Trap will discard the packet problem

Development colleagues in the test, said V3 trap message run will drop packets, strictly speaking, is not to lose packets, is said to run a period of time, V1, V2 version of the message is normally received, SNMP trap V3

Version of the message can not be received, the real pit, looked at the next snmp4j, can not find where to start up the log, ╮(╯▽╰)╭, in the initialization of the place with:

Org.snmp4j.log.LogFactory.setLogFactory (New Consolelogfactory ()); To initialize, the result is printed when the V3 trap packet is not accepted:

1.3.6.1.6.3.15.1.1.2.0=0这条莫名其妙的记录,有记录就好,然后我顺着这条线索查下去,了解的SNMP的时间窗口,这个对应的含义是:

Idnotintimewindow later continue to check the source of snmp4j, found in USM has such a section of related code:

        if(SecurityLevel >= 2) {                if(StatusInfo! =NULL) {                    intAuthparamspos =usmsecurityparameters.getauthparametersposition ()+usmsecurityparameters.getsecurityparametersposition (); BooleanAuthentic = Auth.isauthentic (User.getauthenticationkey (), message, 0, Message.length,NewBytearraywindow (Message, Authparamspos, 12)); if(!(authentic)) {                        if(logger.isdebugenabled ()) {Logger.debug ("rfc3414§3.2.6 wrong Digest, authentication failure:" +usmsecurityparameters.getauthenticationparameters (). tohexstring ()); } counterevent Event=NewCounterevent ( This, snmpconstants.usmstatswrongdigests);                        Fireincrementcounter (event); Statusinfo.setsecuritylevel (NewInteger32 (1)); Statusinfo.seterrorindication (Newvariablebinding (Event.getoid (), Event.getcurrentvalue ())); return1408;                    } usmsecuritystatereference.setauthenticationkey (User.getauthenticationkey ());                    Usmsecuritystatereference.setprivacykey (User.getprivacykey ());                    Usmsecuritystatereference.setauthenticationprotocol (auth);                    Usmsecuritystatereference.setprivacyprotocol (PRIV); intStatus = This. Timetable.checktime (Newusmtimeentry (Securityengineid, Usmsecurityparameters.getauthoritativeengineboots (),                    Usmsecurityparameters.getauthoritativeenginetime ())); Switch(status) { Case1411: Logger.debug ("Rfc3414§3.2.7.a not in time window; Engineid= ' "+Securityengineid+ "', engineboots=" +usmsecurityparameters.getauthoritativeengineboots ()+ ", enginetime=" +usmsecurityparameters.getauthoritativeenginetime ()); Counterevent Event=NewCounterevent ( This, snmpconstants.usmstatsnotintimewindows);                        Fireincrementcounter (event); Statusinfo.setsecuritylevel (NewInteger32 (2)); Statusinfo.seterrorindication (Newvariablebinding (Event.getoid (), Event.getcurrentvalue ())); returnstatus;  Case1410:                        if(logger.isdebugenabled ()) {Logger.debug ("Rfc3414§3.2.7.b-unkown engine ID:" +Securityengineid); } counterevent Event=NewCounterevent ( This, snmpconstants.usmstatsnotintimewindows);                        Fireincrementcounter (event); Statusinfo.setsecuritylevel (NewInteger32 (2)); Statusinfo.seterrorindication (Newvariablebinding (Event.getoid (), Event.getcurrentvalue ())); returnstatus; }                }

The point is: int status = This.timeTable.checkTime (

New Usmtimeentry (Securityengineid, Usmsecurityparameters.getauthoritativeengineboots (),  Usmsecurityparameters.getauthoritativeenginetime ()));

Through this sentence check whether in the time window, if not in the time window directly thrown out.

This sentence calls another method, to let us see: Inside the Usmtimetable.java

 Public synchronized intChecktime (Usmtimeentry entry) {intnow = (int) (System.currenttimemillis ()/1000L); if( This. Localtime.getengineid (). Equals (Entry.getengineid ())) {            if(( This. localtime.getengineboots () = = 2147483647)                    || ( This. localtime.getengineboots ()! =entry.getengineboots ())|| (Math.Abs (now + This. Localtime.gettimediff ()-Entry.getlatestreceivedtime ()) > 150)) {                if(logger.isdebugenabled ()) {Logger.debug ("Checktime:received Message outside time window (authorative):" + (( This. localtime.getengineboots ()! =entry.getengineboots ())? "Engineboots differ"                                            : NewStringBuffer (). Append (""). Append (Math.Abs ( now+ This. Localtime.gettimediff ()-entry.getlatestreceivedtime ())) . Append ("> 150"). toString ())); }                return1411; }            if(logger.isdebugenabled ()) {Logger.debug ("Checktime:time OK (authorative)"); }            return0; }

This function is to check the time window function, note that getengineboots gets the number of engine runs, the first time the message is received, incremented once per second, Getengineid flag engine ID, as if a user an engine.

And then judge the time: Getlastestreceivedtime () Note that this time is the report message of the SNMP when reporting time, if the first message from the beginning to the 150s has not been reported, it is not considered to be discarded in the time window.

Try to pass: SNMPLISTENER.GETUSM (). Gettimetable (). Getentry (New OctetString (Securityname)). Setlatestreceivedtime (((int) ( System.currenttimemillis ()/1000L)); This method is set and the result is the same, there may be a better way.

However, since it is a requirement of the agreement, this mechanism of preventing attack, then keep it for the time being.

Trap code Development Pit for SNMP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.