API ipset-ng execute user JavaScript scenario

For the development of the script ipset-ng used MuJS framework, author Artifex Software Inc. MuJS is a lightweight Javascript interpreter designed for embedding in other software to extend them with scripting capabilities. IPSET-NG script engine uses JavaScript (ECMA-262) as scripting language for scenario.
JavaScript/Lua scenarios can use the following programs from the package: IPSETD-NG, SENSOR-NG, MILTER-NG, JSTEST-NG.


Defined variable user JavaScript scenario:

answer - structure contains predefined parameters from the client's request, part of the parameters it contains a read-only:

  • answer.ok - predefined return answer is succes, value: 200.
  • answer.nok - predefined return answer is block, value: 404.
  • answer.utype - predefined request check type, see command numeric details.
  • answer.ip - predefined request prepare IP address.
  • answer.ustr - predefined request user string, see send example details. In parse LOG mode, full logging string.

the other part of the structure answer - be used to enter the processing results IP address script:

  • answer.uret - client return value: answer.ok or answer.nok.
  • answer.uip - old or new defined return IP address.
  • answer.utbl - ipset table name to operate from return IP address.
  • answer.ucmd - cmd to return IP address, valid: add | del.
  • answer.utm - live time added IP addresses in the table, see timeout - add address details.

For testing and debugging JavaScript's can use a utility included in the package IPSET-NG - JSTEST-NG.


JavaScript command support:

  • all basic command is standart ECMA-262

Extended features command:

System command:

  • require - required script file library, stated without extension .js
  • load - load runtime script file
  • rfile - get any plain text file content to variable
  • print print all types variable, similarly team console.log
  • write - alias is print, for compatibility many library scripts
  • alert - alias is print, for compatibility many library scripts
  • console.log - alias is print, for compatibility many library scripts
  • document.write - alias is print, for compatibility many library scripts
  • quit - return from script, similarly team abort
  • gc - show status memory garbage collection in JavaScript stack
  • syslog - send message to syslog
  • ungzip - deflate gzip .gz files
  • unbzip - deflate bzip .bz2 files

Prototype command:

  • new File - open constructor to read/write in file source, required two parameters:
    * file name - system file name include path
    * flags - opener mode, read/write/append, valid flag: r|r+|a|a+|w|w+
  • .readChar - read 'character' from file stream
  • .readLine - read 'line' from file stream, before the first newline or end of file
  • .writeLine - write 'line' to file stream, in r+ mode - write begin of file, in a+ mode - write to end of file
  • .pos - get current position in file stream
  • .startPos - set start position in file stream
  • .endPos - set end position in file stream
  • .close - close file stream
  • xxx.File example

Network command:

  • ip.dns - get hostname to IP address
  • ip.family - get IP address family, IPV4 = 2, IPV6 = 10, not IP address = 0
  • ip.prefix - get network prefix, required parameter: netmask
  • ip.whois - get Whois information from IP address or domain name
  • ip.range - return IP address array is requested network address include prefix
  • ip.calc - IPV4 IP address calculator, return object structure:
    * .ipaddr - IP address
    * .netmask - network mask
    * .network - network address, netmask requie
    * .broadcast - broadcast network address, netmask requie
    * .startip - the first IP address in the network, netmask requie
    * .endip - the last network ip, netmask requie
    * .prefix - network prefix, netmask requie
    * .dns - hostname to IP address
  • ip.xxx example

GeoLocation command:

  • geo.asn - GeoIP, get ASNumber to IP address
  • geo.isp - GeoIP, get ISProvider to IP address
  • geo.country2 - GeoIP, get Country as two characters to IP address
  • geo.country3 - GeoIP, get Country as three characters to IP address
  • geo.city - GeoIP, get City to IP address
  • geo.region - GeoIP, get Region to IP address
  • geo.area - GeoIP, get Area to IP address
  • geo.weather - GeoIP, get Weather to IP address
  • geo.domain - GeoIP, get Domain to IP address
  • geo.zipc - GeoIP, get zipc to IP address
  • geo.timez - GeoIP, get timez to IP address
  • geo.latlng - GeoIP, get Latitude & Longitude to IP address
  • geo.netspeed - GeoIP, get network speed object
  • geo.utype - GeoIP, get usaly type object
  • geo.xxx example

HTTP command:

  • http.get - get method HTTP request, support basic Authorization
  • http.post - post method HTTP request, support basic Authorization
  • http.head - head method HTTP request, support basic Authorization
  • http.options - get HTTP options method request
  • http.update - get latest version JBL black list from network, see example
  • http.xxx return object structure:
    * .body - this contains the response BODY (usually HTML)
    * .code - this returns contains the HTTP Status code returned by the server as an integer
    * .status - this returns the text associated with the status code
    * .headers - contains the HTTP headers returned by the server
  • http.xxx example

Iptables/firewall IPV4 & IPV6 command:

  • all syntax for this command group: iptables.xxx(ip,chain,target)
  • iptables.insert - insert IP address rule
  • iptables.add - add IP address rule
  • iptables.del - delete IP address rule
  • iptables example

Iptables/firewall IPV4 command:

  • all syntax for IPV4 command group: ip4tables.xxx(chain)
  • ip4tables.create - create new chain
  • ip4tables.destroy - destroy chain
  • ip4tables.flush - flush chain
  • ip4tables.list - list IP adresses in chain
  • ip4tables.ccheck - check chain exist
  • ip4tables example

Iptables/firewall IPV6 command:

  • all syntax for IPV6 command group: ip6tables.xxx(chain)
  • ip6tables.create - create new chain
  • ip6tables.destroy - destroy chain
  • ip6tables.flush - flush chain
  • ip6tables.list - list IP adresses in chain
  • ip6tables.ccheck - check chain exist
  • ip6tables example

Function iptables.xxx automatic check type from IP address, IPV4 or IPV6, and depending on the outcome of a rule is inserted in the corresponding table.
Automatic adding rules from creation chain in INPUT chain: 0 0 TESTCHAIN all -- * * 0.0.0.0/0 0.0.0.0/0 to iptables.
When deleting a chain, also removed the iptables rules for this chain.
Internet protocol version 4 and 6 for iptables operation compatible.


Example JavaScript iptables.xxx function:

example-iptable.js


    var ipa = "1.2.3.4",
        chain = "TESTCHAIN",
        target = "DROP";

    var status = iptables.add(ipa,chain,target);
    if (status) {
                print("--iptables add: OK ", status);
    } else {
                print("--iptables add: ERROR ", status);
    }

    // Result 'iptables -L -n -v':
    //   Chain TESTCHAIN (1 references)
    //   pkts bytes target prot opt in  out  source   destination
    //     0     0  DROP    all  --  *   *   1.2.3.4   0.0.0.0/0
    //   ....
    //   or use in script:  ip4tables.list(chain);

        status = iptables.del(ipa,chain,target);
    if (status) {
                print("--iptables del: OK ", status);
    } else {
                print("--iptables del: ERROR ", status);
    }




Example JavaScript ip(4|6)tables.xxx function:

example-iptable.js


    var chain = "TESTCHAIN";

    // clear "TESTCHAIN" in table IPV4 'filter' 
    var status = ip4tables.flush(chain);
    if (status) {
                print("--ip4tables flush: OK ", status);
    } else {
                print("--ip4tables flush: ERROR ", status);
    }

    // clear "TESTCHAIN" in table IPV6 'filter' 
        status = ip6tables.flush(chain);
    if (status) {
                print("--ip6tables flush: OK ", status);
    } else {
                print("--ip6tables flush: ERROR ", status);
    }



Example update iptables access rule on startup script:

startup-ipt-update.js


    // Update iptables access rule on startup script
    // answer.view - is current runing daemon print status

    var dlurl = [
            "http://xxxxxx.xxx/blacktbl.json",
            "http://xxxxxx.xxx/blacklog.json",
            "http://xxxxxx.xxx/blackhack.json"
    ];

    iptupdate = function(url) {

        var aaa = http.get(url, "X-Origin:IPSET-NG update script");
        if( aaa.code === 200 ) {

        var dlb = JSON.parse(aaa.body); delete(aaa);
        var ret = ip4tables.create(dlb.table);
        if(answer.view) { print("Create chain return: ", ret); }

        dlb.ipa.forEach(function(ipentry) {
            iptables.add(ipentry, dlb.table, "DROP");
            if(answer.view) { print("Add ip: ", ipentry, " to: ", dlb.table); }
        });
        if(answer.view) { print(dlb.table, " -> Done.."); }
        delete(dlb);
        delete(aaa);

        } else {
        print("Update iptables access: error connect to server: ", aaa.code, aaa.status);
        delete(aaa);
        }
    }

        for(var iurl in dlurl) {
        if(answer.view) { print("Going to URL: ", iurl); }
        iptupdate(iurl);
        }




Example JavaScript HHTP client functions:

example-http-client.js


    // ALL http functions does handle redirects automaticly.
    //
    // * The first <URL> parameter specifies request URL.
    // * The second <custom header fields> parameter you can specify extra headers.
    // * The third <post data> parameter the post data can be specified, for 'http.post' method only.
    // * Support 'Basic Authorization', place in <post data> 'username=Lea&password=suxx123'
    // * Support 'Accept Encoding' gzip

    // Return object structure:
    //  .body - this contains the response BODY (usually HTML).
    //  .code - this returns contains the HTTP Status code returned by the server as an integer.
    //  .status - this returns the text associated with the status code.
    //  .headers - contains the HTTP headers returned by the server.

    // Makes an HTTP GET request to "http://www.google.com" <URL>
    // syntax for this command:
    // http.get(<URL>, <custom header fields>);

    var httpr = http.get("http://www.google.com", "X-Origin:IPSET-NG update script");

    print("--http .status:", httpr.status);
    print("--http .code:", httpr.code);
    print("--http .headers:", httpr.headers);
    print("--http .body:", httpr.body);

    // Makes an HTTP POST method request to "http://www.mysite.com/refresh.php" <URL>
    // syntax for this command:
    // http.post(<URL>, <custom header fields>, <post data>);

        httpr = http.post("http://www.mysite.com/refresh.php", "X-Origin:IPSET-NG update script","q=test&lm=76&ds=secret");

    print("--http .status:", httpr.status);
    print("--http .code:", httpr.code);
    print("--http .headers:", httpr.headers);
    print("--http .body:", httpr.body);

    // HEAD method example:
    // syntax for this command:
    // http.head(<URL>, <custom header fields>);

        httpr = http.head("http://www.mysite.com/geturl.php", "X-Origin:IPSET-NG update script");

    if(code == 200) {
        print("--http .status:", httpr.status);
        print("--http .code:", httpr.code);
        print("--http .headers:", httpr.headers);
    }

    // HEAD method not get 'body', this is empty..
    // print("--http .body:", httpr.body);

    // UPDATE: get latest version JBL black list from network
    // valid values:
    //
    // * 'blackip4' - latest IP black list v4
    // * 'blackip6' - latest IP black list v6
    // * 'blacklog' - latest IP black list hacker attack
    // * 'blacknet' - latest NETWORK black list
    // * 'blackproxy' - latest black list open proxy
    //
    var newBlackList = http.update("blackip4");
    if( newBlackList.code === 200 ) {

        var dlbl = JSON.parse(newBlackList.body);
        delete(newBlackList);
        // * JSON process:
        //   -  dlbl.table - table name
        //   -  dlbl.type - ip = 1, net = 3, set = 4,
        //    0 = table type error, skip this table
        //   -  dlbl.ipv - ipv4 = 2, ipv6 = 10
        //   -  dlbl.ipa - IP address array
        //
        // more detail in:
        // http://ipset-ng.pick-nik.ru/en/api/ipsetng-JSON-proto#protocol_json_export
        //
        dlbl.ipa.forEach(function(ipentry) {
            ... // you rules.. see iptables example
        });

    } else {
        print("Update black list: HTTP - error connect to server: ", newBlackList.code, newBlackList.status);
        delete(newBlackList);
    }



The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.

The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.

The semantics of the GET method change to a "partial GET" if the request message includes a Range header field. A partial GET requests that only part of the entity be transferred. The partial GET method is intended to reduce unnecessary network usage by allowing partially-retrieved entities to be completed without transferring data already held by the client.
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions:
  • Annotation of existing resources
  • Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles
  • Providing a block of data, such as the result of submitting a form, to a data-handling process
  • Extending a database through an append operation
The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.

The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.

If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

The response to a HEAD request MAY be cacheable in the sense that the information contained in the response MAY be used to update a previously cached entity from that resource. If the new field values indicate that the cached entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache entry as stale.
The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval. Responses to this method are not cacheable.

If the OPTIONS request includes an entity-body (as indicated by the presence of Content-Length or Transfer-Encoding), then the media type MUST be indicated by a Content-Type field. Although this specification does not define any use for such a body, future extensions to HTTP might use the OPTIONS body to make more detailed queries on the server. A server that does not support such an extension MAY discard the request body.

If the Request-URI is an asterisk ("*"), the OPTIONS request is intended to apply to the server in general rather than to a specific resource. Since a server's communication options typically depend on the resource, the "*" request is only useful as a "ping" or "no-op" type of method; it does nothing beyond allowing the client to test the capabilities of the server. For example, this can be used to test a proxy for HTTP/1.1 compliance (or lack thereof).

If the Request-URI is not an asterisk, the OPTIONS request applies only to the options that are available when communicating with that resource.

A 200 response SHOULD include any header fields that indicate optional features implemented by the server and applicable to that resource (e.g., Allow), possibly including extensions not defined by this specification. The response body, if any, SHOULD also include information about the communication options. The format for such a body is not defined by this specification, but might be defined by future extensions to HTTP. Content negotiation MAY be used to select the appropriate response format. If no response body is included, the response MUST include a Content-Length field with a field-value of "0".

The Max-Forwards request-header field MAY be used to target a specific proxy in the request chain. When a proxy receives an OPTIONS request on an absoluteURI for which request forwarding is permitted, the proxy MUST check for a Max-Forwards field. If the Max-Forwards field-value is zero ("0"), the proxy MUST NOT forward the message; instead, the proxy SHOULD respond with its own communication options. If the Max-Forwards field-value is an integer greater than zero, the proxy MUST decrement the field-value when it forwards the request. If no Max-Forwards field is present in the request, then the forwarded request MUST NOT include a Max-Forwards field.


Example JavaScript use prototype 'File' function:

example-File-prototype.js


        var bbb, num =  0;

        // open file in read+append mode
        var aaa = new File("test.txt","a+");

        // read file
        while( (bbb  = aaa.readLine()) != null ) {
        var pos = aaa.pos();
            print("Line :", num, pos, bbb);
            num++;
        }

        // write string to file
        aaa.writeLine("I'm write to open file stream.\nThis next line..");

        // go to the beginning of the file
        aaa.startPos();

        num = 0;

        // re-read edited file
        while( (bbb  = aaa.readLine()) != null ) {
            print("Line :", num, bbb);
            num++;
        }

        // close file
        aaa.close();


The argument mode points to a string beginning with one of the following sequences (possibly followed by additional characters, as described below):

open flag description
r Open text file for reading. The stream is positioned at the beginning of the file.
r+ Open for reading and writing. The stream is positioned at the beginning of the file.
w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.
w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.
a Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.
a+ Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.


Example JavaScript use network utilites:

example-iputils.js


    // Demo JavaScript framework code for ipset-ng
    // use network utilites:

    var ip_address = "93.158.134.3";
    var aaa;

    // get hostname to IP address:
    aaa = ip.dns(ip_address);
    print("DNS: ", aaa);

    // IPV4 IP address calculator:
    var netcalc = ip.calc("93.158.134.3/24");

    // return object structure:
    print("IP: ",netcalc.ipaddr);
    print("NETMASK: ",netcalc.netmask);
    print("BROADCAST: ",netcalc.network);
    print("NETWORK: ",netcalc.broadcast);
    print("START HOST: ",netcalc.startip);
    print("END HOST: ",netcalc.endip);
    print("PREFIX: ",netcalc.prefix);
    print("HOSTNAME: ",netcalc.dns);

    delete netcalc;

    // or another method network defined

    var netcalc1 = ip.calc("93.158.134.3/255.255.255.0");
    ...
    var netcalc2 = ip.calc("93.158.134.3 255.255.255.0");
    ...
    var netcalc3 = ip.calc("93.158.134.3 24");
    ...

    // get IP address family:
    // IPV4 = 2,
    // IPV6 = 10,
    // not IP address = 0
    var ipvType = ip.family("93.158.134.3");
    if( ipvType === 2 ) {
            print("IP address is IPV4 family");
    } else
    if( ipvType === 10 ) {
            print("IP address is IPV6 family");
    } else {
            print("this is NOT IP address!");
    }

    var ipvType1 = ip.family("2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d");
    ... == 10

    // get network prefix:
    // required parameter: 'netmask'
    var netPrefix = ip.prefix("255.255.255.240");
    print("Network prefix is: /", netPrefix);

    // get IP address range:
    // required parameters: 'network' + 'prefix'
    var num = 1;
    var iprange = ip.range("10.1.2.0/24");
    for(var i in iprange) {
        print("ip range IP: ", num, iprange[i]);
        num++;
    }
    delete(iprange);

    // get Whois information from IP address or domain name:
    // required parameters: 'IP address', 'mode',
    // parameter 'mode': 
    // 1 - minimal information: inetnum, route, origin
    // 2 - complete information: inetnum, route, origin, address, phone, fax-no, abuse-mailbox
    // 3 - full mode information: no any field filter

    var whoiString = ip.whois("213.180.204.3", 2);
    print(whoiString);
    delete(whoiString);

    // Example whois output in 'mode' = 2:
    //     inetnum:        213.180.204.0 - 213.180.204.255
    //     address:        Yandex LLC
    //     address:        16, Leo Tolstoy St.
    //     address:        119021
    //     address:        Moscow
    //     address:        Russian Federation
    //     phone:          +7 495 739 xxxx
    //     fax-no:         +7 495 739 xxxx
    //     abuse-mailbox:  abuse@yandex.ru
    //     route:          213.180.204.0/24
    //     origin:         AS13238
    


Example JavaScript use GeoLocations tools:

example-geoip.js


    // Demo JavaScript framework code for ipset-ng
    // use GeoLocations functions:

    var ip_address = "93.158.134.3";
    var aaa;

    aaa = ip.dns(ip_address);
    print("DNS: ", aaa);

    aaa = geo.asn(ip_address);
    print("AS: ",aaa);

    aaa = geo.isp(ip_address);
    print("ISP: ",aaa);

    aaa = geo.country2(ip_address);
    print("Country [2]: ",aaa);

    aaa = geo.country3(ip_address);
    print("Country [3]: ",aaa);

    aaa = geo.city(ip_address);
    print("City: ",aaa)

    aaa = geo.latlng(ipa);
    print("LatLong:",aaa);

    aaa = geo.timez(ipa);
    print("Time Zone:",aaa);

    aaa = geo.zipc(ipa);
    print("ZIP code:",aaa);

    aaa = geo.domain(ipa);
    print("Domain:",aaa);

    aaa = geo.weather(ipa);
    print("Weather station:",aaa);

    aaa = geo.area(ipa);
    print("Area:",aaa);

    aaa = geo.region(ipa);
    print("Region:",aaa);

    aaa = geo.netspeed(ipa);
    print("Net Speed:",aaa);

    aaa = geo.utype(ipa);
    print("Used type:",aaa,"\n");



Example user JavaScript Input/Output scenario:

example-input-output-system.js


    // Demo JavaScript framework code for ipset-ng

    // Show server defined data 
    // from client request:
    print("aaa",answer.nok,answer.ok,answer.utype,answer.ip,answer.ustr);

    var ipa = answer.ip;

    print( "Input read-only parametrs for parsing:\n\n");
    print( "- ip:", answer.ip );
    print( "- type operation/list:", answer.utype );
    print( "- extended param:", answer.ustr );

    print("redefined read/write ip variable: ",ipa);

    // Output read-write parametrs from parsing:

    answer.uret = answer.nok;
    answer.uip = "1.2.3.4";
    answer.utbl = "badloglist";
    answer.ucmd = "add";
    answer.utm = 3800;

    print("Output test:",answer.uret,answer.utbl,answer.uip,answer.ucmd,answer.utm);

    // print stdout
    document.write("test document.write : OK ",ipa);
    alert("test alert : ", "OK ", ipa);
    console.log("test console.log :", "OK", ipa);

    // write to syslog
    syslog("test syslog : OK",ipa);

    // deflate gzip '.gz' (text) files, no binary content support
    var unZip = ungzip("/var/archive/test.gz");
    print(unZip);
    delete(unZip);

    // deflate bzip '.bz2' (text) files, no binary content support
    var unbZip = unbzip("/var/archive/test.bz2");
    print(unbZip);
    delete(unbZip);



Example JavaScript ASN filter scenario:

example-geo_asn_crawler_filter.js:


    //
    // example compare for GeoIP AS nuber for matching
    // search system: Yandex,Google,Bing ... etc
    // and if rule == black : bloking search system
    // or rule == white : access granted to search system
    //

     // for real data input see: example-input-output-system.js
     //     var ipa = "93.158.134.11"; // yandex.ru ip
     //     var rule = "black";

     var ipa = answer.ip;
     var rule = answer.utype;

     check_asn = function(ipa,rule) {
        var asn = geo.asn(ipa);
        if( asn !== '') {
            var str = rfile("example-asn_crawler_filter.txt");
            var res = str.split("\n");
            delete str;

            for(var i in res) {
                if( res[i].trim() === asn ) {
                    // print( "- match:",res[i].trim(), asn );
                    // access granted if rule black
                    // and access granted if rule white
                    return( (rule === 'black') ? answer.nok : answer.ok );
                }
            }
    
            delete i;
            delete res;
        }
        return( (rule === 'black') ? answer.ok : answer.nok );
     }

    answer.uret = check_asn(ipa,rule);




example-asn_crawler_filter.txt:


        AS10003
        AS10010
        AS10030
        AS10091
        AS10094
        AS10139
        AS10143
        AS10199
        AS10219
        AS10297
        AS10316
    ... etc
    



Example JavaScript GeoCity filter scenario:

example-geo_city_filter.js:

    
    //
    // example compare for GeoIP city name for matching
    // for IP address.
    // and if rule == black : bloking search system
    // or rule == white : access granted to search system
    //

     // for real data input see: example-input-output-system.js
     //     var ipa = "81.19.70.3"; // rambler.ru ip
     //     var rule = "black";

     var ipa = answer.ip;
     var rule = answer.utype;
     var city = ['Saint Petersburg','Moscow'];

     check_city = function(ipa,rule) {
        var geocty = geo.city(ipa);
        if( geocty !== '') {

            for(var i in city) {
                if( city[i] === geocty ) {
                    // print( "- match:",city[i], geocty );
                    // access granted if rule black
                    // and access granted if rule white
                    return( (rule === 'black') ? answer.nok : answer.ok );
                }
            }
    
            delete i;
            delete geocty;
        }
        return( (rule === 'black') ? answer.ok : answer.nok );
     }

    answer.uret = check_city(ipa,rule);



Example JavaScript Browser Detect filter scenario:

example-BrowserDetect.js



    require("jslibBrowserDetect");

    answer.uret = answer.nok;
    answer.utbl = "blacklistng";
    answer.ucmd = "add";
    answer.utm = 3800;

    var ua = Array();
        ua[0] = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36";
        ua[1] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.2 (KHTML, like Gecko) Ubuntu/11.10 Chromium/15.0.874.106 Chrome/";
        ua[2] = "Mozilla/5.0 (compatible; Konqueror/4.1; OpenBSD) KHTML/4.1.4 (like Gecko)";
        ua[3] = "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.11 (KHTML, like Gecko) Version/7.1.0.7 Saf";
        ua[4] = "Mozilla/5.0 (Linux; U; Android 3.0.1; en-us; Xoom Build/HWI69) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.";
    
        for(var i in ua) {
            var parser = BrowserDetect.check(ua[i]);
            print(parser.os,parser.device,parser.browser);
        // if(answer.ustr == .. you choice .. ) {
        //  answer.uret = answer.ok;
        //  answer.ucmd = "";
        //  answer.utbl = "";
        //  break;
        //}
        }

    


Example JavaScript Access time filter scenario:

example-timeaccess.js


    //
    // Example access for my subnet (see example-mynet.jst)
    // for time
    // use external parser jslibIPv4.js
    //

     var ipa = answer.ip;

    checkIp = function(ipa) {

      require("jslibIPv4");

      if( load("example-mynet.jst") === true ) {
        var date = new Date();
        if(typeof timeaccess === "object") {
            for ( var x in timeaccess.subnet ) {
                // print("--parse debug: ",timeaccess.subnet[x]);
                if( new IPv4.Subnet(
                            timeaccess.subnet[x][0],
                            timeaccess.subnet[x][1])
                            .isValidAddress(ipa)) {
                    for ( var t in timeaccess.timeacc ) {
                        // print("--matched debug: ",ipa,timeaccess.timeacc[t]);
                        if((date.getHours() >= timeaccess.timeacc[t][0]) &&
                           (date.getHours() <= timeaccess.timeacc[t][1])) {
                            return( answer.ok );
                        }
                    }
                    delete t;
                }
            }
            delete x;
        }
        delete date;
      }
    return( answer.nok );
    }

    answer.uret = checkIp(ipa);


    

example-mynet.jst


    var mynet = [
        ["192.168.0.0",24],
        ["192.168.1.0",24],
        ["192.168.220.0",24],
        ["11.0.0.15",32]
    ];

    var timeaccess = {
        subnet: mynet,
        timeacc: [[9,13],[14,17]]
    };

    

Full source can be found in the directory <ipset-ng-src-dir>/userscript


  Meta Tags: API user JavaScript framework