egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Need help with IPinfo Script

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help
View previous topic :: View next topic  
Author Message
sysusr
Voice


Joined: 13 Dec 2016
Posts: 6

PostPosted: Sun Sep 16, 2018 11:13 am    Post subject: Need help with IPinfo Script Reply with quote

So far I have the following code to read data from ipinfo.io

Example of the site: https://ipinfo.io/8.8.8.8/json

Code:
proc geo {n u h c t} {
        catch {set http [::http::geturl http://ipinfo.io/[lindex $t 0]/json -timeout 6000]} error
        if {[string match "*error*" $error]} { putserv "PRIVMSG $c :connect error!" ; return 0 }
        if {[string match "*timeout*" $error]} { putserv "PRVMSG $c :timeout!"; return 0 }
        set html [::http::data $http]
        if {[string match "*Not Found*" $html]} { putserv "PRIVMSG $c :GeoIP: No data found." ; return }
        regexp -line -- {<"ip":>(.*)</ip>} $html -> ipz
        regexp -line -- {<"hostname":>(.*)</hostname>} $html -> hostname
        regexp -line -- {<"city":>(.*)</city>} $html -> city
        regexp -line -- {<"region">(.*)</region>} $html -> region
        regexp -line -- {<"country":>(.*)</country>} $html -> country
        regexp -line -- {<"loc":>(.*)</loc>} $html -> loc
        regexp -line -- {<"org":>(.*)</org>} $html -> org
        putserv "PRIVMSG $c :IP: $ipz - Hostname: $hostname - City: $city - Region: $region - Country: $country - Location: $loc - Organization: $org"
        http::cleanup $http
}


But I am getting the following error....

Quote:
[11:09:20] Tcl error [geo]: can't read "ipz": no such variable


Does anyone have any suggestion or help why I am getting this error? Thanks
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3583
Location: Mint Factory

PostPosted: Sun Sep 16, 2018 1:34 pm    Post subject: Reply with quote

If the output is in json format why do you complicate things and not parse it as a dictionary with ::json::json2dict instead?

Here's a proof of concept.
Code:

package require http
package require json

proc geo {nick uhost hand chan text} {
   set lookup [lindex [split $text] 0]
   catch {set http [::http::geturl http://ipinfo.io/$lookup/json -timeout 6000]} error
   set data [::http::data $http]
   set json [::json::json2dict $data]
   ::http::cleanup $http
   foreach ele [dict keys $json] { set $ele [dict get $json $ele] }
   putserv "PRIVMSG $chan :IP: $ip - Hostname: $hostname - City: $city - Region: $region - Country: $country - Location: $loc - Organization: $org"
}

You can either grab json.tcl file and load it before your geo script or install tcllib package.
_________________
I tawt I taw a puddy tat!
Back to top
View user's profile Send private message
sysusr
Voice


Joined: 13 Dec 2016
Posts: 6

PostPosted: Sun Sep 16, 2018 1:54 pm    Post subject: Reply with quote

Not sure what you mean. But I tried to load json and it broke. I already have tcllib package installed on my box. Just looking for the simplest way to parse the data
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3583
Location: Mint Factory

PostPosted: Mon Sep 17, 2018 12:39 am    Post subject: Reply with quote

If you have tcllib then you don't need that separate json.tcl file, it should work without it.
_________________
I tawt I taw a puddy tat!
Back to top
View user's profile Send private message
sysusr
Voice


Joined: 13 Dec 2016
Posts: 6

PostPosted: Mon Sep 17, 2018 10:06 am    Post subject: Reply with quote

caesar wrote:
If you have tcllib then you don't need that separate json.tcl file, it should work without it.


Unfortunately it still does not work. Any other suggestion?
Back to top
View user's profile Send private message
willyw
Revered One


Joined: 15 Jan 2009
Posts: 1042

PostPosted: Mon Sep 17, 2018 10:29 am    Post subject: Reply with quote

You might like to be SURE that you have json, etc.

In the partyline, do:
.tcl package names

and it will return a list of everything. Check to be sure that it is finding what you want/need.

( You will need to have the use of .tcl for owner's use, enabled in eggdrop.conf for this to work. )
_________________
For a fun (and popular) Trivia game, visit us at: irc.librairc.net #science-fiction . Over 300K Q & A to play in BogusTrivia !
Back to top
View user's profile Send private message
sysusr
Voice


Joined: 13 Dec 2016
Posts: 6

PostPosted: Mon Sep 17, 2018 10:43 am    Post subject: Reply with quote

willyw wrote:
You might like to be SURE that you have json, etc.

In the partyline, do:
.tcl package names

and it will return a list of everything. Check to be sure that it is finding what you want/need.

( You will need to have the use of .tcl for owner's use, enabled in eggdrop.conf for this to work. )


OK i got the script working but when the field is blank it has another error.

Quote:
[10:51:01] Tcl error [who]: can't read "hostname": no such variable
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3583
Location: Mint Factory

PostPosted: Tue Sep 18, 2018 2:33 am    Post subject: Reply with quote

Here's a sneaky method. Replace:
Code:

foreach ele [dict keys $json] { set $ele [dict get $json $ele] }

with:
Code:

set keys [dict keys $json]
set expecting {ip hostname city region country loc postal phone org}
foreach ele $expecting {
   if {[lsearch $keys $ele] != -1} {
      set $ele [dict get $json $ele]
   } else {
      set $ele "n/a"
   }
}

_________________
I tawt I taw a puddy tat!
Back to top
View user's profile Send private message
sysusr
Voice


Joined: 13 Dec 2016
Posts: 6

PostPosted: Fri Oct 12, 2018 2:09 pm    Post subject: Reply with quote

Forgot to reply back. Script works flawless now. Thank you
Back to top
View user's profile Send private message
Sadie05
Voice


Joined: 27 Jan 2019
Posts: 1

PostPosted: Sun Jan 27, 2019 4:46 pm    Post subject: Re: Need help with IPinfo Script Reply with quote

I tried but It's a little complicated Mad
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3583
Location: Mint Factory

PostPosted: Mon Jan 28, 2019 3:45 am    Post subject: Reply with quote

Care to elaborate on what you tried and is complicated? Here is an updated code that validates user input and if the ip is in correct format (for example 1.1.1.1).
Code:

package require http
package require json

bind pub * !geo fetch:geo

proc fetch:geo {nick uhost hand chan text} {
   if {[scan $text {%s} lookup] != 1} {
      puthelp "PRIVMSG $chan :Error, syntax is: !geo <ip>"
      return
   }
   if {![regexp {([0-9]+\.)([0-9]+\.)([0-9]+\.)([0-9]+)} $lookup]} {
      puthelp "PRIVMSG $chan :Error, the IP you mentioned is not valid."
      return
   }
   catch {set http [::http::geturl http://ipinfo.io/$lookup/json -timeout 6000]} error
   set data [::http::data $http]
   set json [::json::json2dict $data]
   ::http::cleanup $http
   set keys [dict keys $json]
   foreach ele {ip hostname city region country loc postal phone org} {
      set $ele [expr {[lsearch $keys $ele] > -1 ? [dict get $json $ele] : "n/a"}]
   }
   puthelp "PRIVMSG $chan :IP: $ip - Hostname: $hostname - City: $city - Region: $region - Country: $country - Location: $loc - Organization: $org"
}

_________________
I tawt I taw a puddy tat!
Back to top
View user's profile Send private message
Stefano1990
Voice


Joined: 04 Jun 2018
Posts: 20

PostPosted: Mon Jan 28, 2019 12:17 pm    Post subject: Script help Reply with quote

Can u make this script and to show on connect client Nick IP Country Code and msg connect client on channel #opers

and to make save blacklist list countrycode on #opers !add blcountry AA | !del blcountry AA | !blcountry list

if the country code is on blacklist to show only this msg one #oper during client Global connect

INFO:Client Global Connecting : [G-ZLine] : Jimmy 46.34.57.23 Germany De [BlackCountry]

to take gzline *@IP 2h: Your Country Is Not Allowed In This Network

and to make save exemp list on channel #opers !add exemp 46.34.* US | !del exemp 46.34.* US |
!exemp list

if the Ip + country code is on exemp list to show only this msg one #oper during client Global connect

INFO: Client Global Connecting : Jimmy 46.34.57.23 Germany De

if the Ip dont have his Country Code on exemp to be gzline
same and for the Country Code when dont have his Ip on exemp
example: this to be add for Client Global Connect wrote:


Code:

bind raw - NOTICE server:notices

proc server:notices {from keyword text} {
  global outputchan
      if {[string match -nocase "*client connecting*" $text]} {
        set hostmask [lindex [split $text] 6]
     puthelp "PRIVMSG #Opers :$nick -  $IP - $country"
        return 0
      }
}


_________________
Use your common sense and try not to make me look too much like I know what I'm doing.
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3583
Location: Mint Factory

PostPosted: Mon Jan 28, 2019 2:36 pm    Post subject: Reply with quote

Keep this in mind about ipinfo.io website:
Quote:

If you need to make under 1,000 requests a day to our API and it's for non-commercial use, or you just want to test things out, signup for our free plan.

meaning that they offer a paid lookup service, so if you do a few of them then I guess that they won't mind, but if you plan to whois every IP that is connecting (meaning a lot of traffic) should consider either getting a paid account or another service, maybe an addon for the IRC server itself.

Anyway, if whatever you get from:
Code:

set hostmask [lindex [split $text] 6]

isn't a valid IP in the format x.x.x.x this won't work, you would have to reverse DNS to get the actual IP.

Give this untested code a try:
Code:

bind raw - NOTICE server:notices

proc server:notices {from keyword text} {
   if {[string match -nocase "*client connecting*" $text]} {
      set hostmask [lindex [split $text] 6]
      if {![regexp {([0-9]+\.)([0-9]+\.)([0-9]+\.)([0-9]+)} $lookup]} return
      catch {set http [::http::geturl http://ipinfo.io/$lookup/json -timeout 6000]} error
      set data [::http::data $http]
      set json [::json::json2dict $data]
      ::http::cleanup $http
      set keys [dict keys $json]
      foreach ele {ip hostname city region country loc postal phone org} {
         set $ele [expr {[lsearch $keys $ele] > -1 ? [dict get $json $ele] : "n/a"}]
      }
      puthelp "PRIVMSG #Opers :$nick -  $ip - $country"
   }
}

Duno from what position in that raw notice you get the $nick from cos you didn't give me an example so left it as is and it's up to you to fix it.

Edit: There are multiple paid and free options you should consider if plan to filter every connection. Just do a ip to country database lookup on Google.
_________________
I tawt I taw a puddy tat!


Last edited by caesar on Mon Jan 28, 2019 3:52 pm; edited 1 time in total
Back to top
View user's profile Send private message
sysusr
Voice


Joined: 13 Dec 2016
Posts: 6

PostPosted: Wed Apr 03, 2019 10:22 pm    Post subject: Reply with quote

i have a slight inquiry since your last update, you can no longer look up IPv6 addresses

so i decided to remove the regex that requires numerical digits and it worked just fine
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3583
Location: Mint Factory

PostPosted: Thu Apr 04, 2019 2:29 am    Post subject: Reply with quote

I just noticed that I copy/paste the code you gave me and didn't double check the variables, so instead of:
Code:

set hostmask [lindex [split $text] 6]

should have been:
Code:

set lookup [lindex [split $text] 6]


Anyway, back to what you asked. We can just use TCLib's IP to validate a Ipv4 or IPv6 that will return -1 if the IP isn't valid, 4 for IPv4 and 6 for IPv6. Simple, no?

Basically we change these two lines:
Code:

      set hostmask [lindex [split $text] 6]
      if {![regexp {([0-9]+\.)([0-9]+\.)([0-9]+\.)([0-9]+)} $lookup]} return

with:
Code:

      set lookup [lindex [split $text] 6]
      if {[::ip::version $lookup] < 4} return

and above:
Code:

bind raw - NOTICE server:notices

simply add:
Code:

package require ip

_________________
I tawt I taw a puddy tat!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber