Wednesday, January 19, 2011

Detect your host IP with Clojure

Recently I was faced with trivial task of detecting a host's IP address where the host could have multiple network interfaces. Based on how the local network was configured, you might have a luck with just a one liner in Clojure:

(import (java.net InetAddress))
(println (InetAddress/getLocalHost))

This will produce following:
;;user=> (import (java.net InetAddress))
;;(println (InetAddress/getLocalHost))
;;user=>
;;inet4address kpad/127.0.0.1
;;nil

Obviosly, that is not what you might be looking for since it is just a loopback address.
To find the your host LAN IP address, you need to find the not loopback interface and obtain the IP that is bound to it. It turns out it is pretty easy in Clojure. Here is whole thing:
===================================================================
import (java.net NetworkInterface))
(def ip
     (let [ifc (NetworkInterface/getNetworkInterfaces)
    ifsq (enumeration-seq ifc)
    ifmp (map #(bean %) ifsq)
    ipsq (filter #(false? (% :loopback)) ifmp)
    ipa (map :interfaceAddresses ipsq)
    ipaf (nth ipa 0)
    ipafs (.split (str ipaf) " " )
    ips (first (nnext ipafs))]
       (str (second (.split ips "/")))))
 

========================================================================

This will produce following:
;;user=> (println ip)
;;192.168.1.70
;;nil

Note: I am still learning Clojure and surely there will be better way of doing this. If you happen to know, please share. Thanks for reading.