inet-address

0.1.0


A Clojure wrapper for the family of Java InetAddress classes

dependencies

org.clojure/clojure
1.8.0
potemkin
0.4.3



(this space intentionally left almost blank)
 
(ns inet.address
  (:require
    [inet.address.core :as address-core]
    [inet.address.six :as address-six]
    [potemkin :refer [import-vars]]))
(import-vars
  [address-core
   ;; static
   all-by-name
   by-address
   by-name
   localhost
   loopback
   ;; behaviour
   address
   canonical-hostname
   host-address
   hostname
   any-local-address?
   link-local-address?
   loopback-address?
   mc-global?
   mc-link-local?
   mc-node-local?
   mc-org-local?
   mc-site-local?
   multicast-address?
   reachable?
   site-local-address?
   ;; constructor
   create])
(import-vars
  [address-six
   ;; behaviour
   scoped-interface
   scope-id
   ipv4-compatible-address?])
 
(ns inet.address.four
  (:require
    [inet.address.core :as ipnet-core]
    [potemkin :refer [import-vars]])
  (:import
    (java.net Inet4Address)))

Static Methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Given the name of a host, returns an Clojure vector of its IP address objects, based on the configured name service on the system.

(defn all-by-name
  [host]
  (->> host
       (Inet4Address/getAllByName)
       (into [])))

Returns an InetAddress.

In the arity-1 case, an object is given a vector of octets representing a 'raw' IP address. In the arity-2 case, an object is given based on the provided host name and a 'raw' IP address.

Note: expected type of addr is a byte array, e.g.: ```clj (by-address [127 0 0 1]) ``` or ```clj (by-address "localhost" [127 0 0 1]) ```

(defn by-address
  ([addr]
    (Inet4Address/getByAddress (byte-array addr)))
  ([host addr]
    (Inet4Address/getByAddress host (byte-array addr))))

Determines the IP address of a host, given the host's name.

(defn by-name
  [host]
  (Inet4Address/getByName host))

Returns the address of the local host.

(defn localhost
  []
  (Inet4Address/getLocalHost))

Returns the loopback address.

(defn loopback
  []
  (Inet4Address/getLoopbackAddress))

Implementation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(extend Inet4Address ipnet-core/Address ipnet-core/behaviour)

Aliases ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(import-vars
  [ipnet-core
   ;; behaviour
   address
   canonical-hostname
   host-address
   hostname
   any-local-address?
   link-local-address?
   loopback-address?
   mc-global?
   mc-link-local?
   mc-node-local?
   mc-org-local?
   mc-site-local?
   multicast-address?
   reachable?
   site-local-address?])
 
(ns inet.address.core
  (:import
    (java.net InetAddress)))

Static Methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Given the name of a host, returns an Clojure vector of its IP address objects, based on the configured name service on the system.

(defn all-by-name
  [host]
  (->> host
       (InetAddress/getAllByName)
       (into [])))

Returns an InetAddress.

In the arity-1 case, an object is given a vector of octets representing a 'raw' IP address. In the arity-2 case, an object is given based on the provided host name and a 'raw' IP address.

Note: expected type of addr is a byte array, e.g.: ```clj (by-address [127 0 0 1]) ``` or ```clj (by-address "localhost" [127 0 0 1]) ```

(defn by-address
  ([addr]
    (InetAddress/getByAddress (byte-array addr)))
  ([host addr]
    (InetAddress/getByAddress host (byte-array addr))))

Determines the IP address of a host, given the host's name.

(defn by-name
  [host]
  (InetAddress/getByName host))

Returns the address of the local host.

(defn localhost
  []
  (InetAddress/getLocalHost))

Returns the loopback address.

(defn loopback
  []
  (InetAddress/getLoopbackAddress))

Protocol ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprotocol Address
  (address [this]
    "Returns the raw IP address of this InetAddress object as a Clojure
    vector.")
  (canonical-hostname [this]
    "Gets the fully qualified domain name for this IP address.")
  (host-address [this]
    "Returns the IP address string in textual presentation.")
  (hostname [this]
    "Gets the host name for this IP address.")
  (any-local-address? [this]
    "Utility routine to check if the InetAddress in a wildcard address.")
  (link-local-address? [this]
    "Utility routine to check if the InetAddress is an link local address.")
  (loopback-address? [this]
    "Utility routine to check if the InetAddress is a loopback address.")
  (mc-global? [this]
    "Utility routine to check if the multicast address has global scope.")
  (mc-link-local? [this]
    "Utility routine to check if the multicast address has link scope.")
  (mc-node-local? [this]
    "Utility routine to check if the multicast address has node scope.")
  (mc-org-local? [this]
    "Utility routine to check if the multicast address has organization
    scope.")
  (mc-site-local? [this]
    "Utility routine to check if the multicast address has site scope.")
  (multicast-address? [this]
    "Utility routine to check if the InetAddress is an IP multicast address.")
  (reachable? [this timeout] [this net-iface ttl timeout]
    "Test whether that address is reachable. The units of `timeout` is
    milliseconds.")
  (site-local-address? [this]
    "Utility routine to check if the InetAddress is a site local address."))

Implementation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def behaviour
  {:address (fn [this] (into [] (.getAddress this)))
   :canonical-hostname (fn [this] (.getCanonicalHostName this))
   :host-address (fn [this] (.getHostAddress this))
   :hostname (fn [this] (.getHostName this))
   :any-local-address? (fn [this] (.isAnyLocalAddress this))
   :link-local-address? (fn [this] (.isLinkLocalAddress this))
   :loopback-address? (fn [this] (.isLoopbackAddress this))
   :mc-global? (fn [this] (.isMCGlobal this))
   :mc-link-local? (fn [this] (.isMCLinkLocal this))
   :mc-node-local? (fn [this] (.isMCNodeLocal this))
   :mc-org-local? (fn [this] (.isMCOrgLocal this))
   :mc-site-local? (fn [this] (.isMCSiteLocal this))
   :multicast-address? (fn [this] (.isMulticastAddress this))
   :reachable? (fn ([this timeout]
                    (.isReachable this timeout))
                   ([this net-iface ttl timeout]
                    (.isReachable this net-iface ttl timeout)))
   :site-local-address? (fn [this] (.isSiteLocalAddress this))})
(extend InetAddress Address behaviour)

Constructors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def create #'by-address)
 
(ns inet.address.six
  (:require
    [inet.address.core :as ipnet-core]
    [potemkin :refer [import-vars]])
  (:import
    (java.net Inet6Address)))

Static Methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Given the name of a host, returns an Clojure vector of its IP address objects, based on the configured name service on the system.

(defn all-by-name
  [host]
  (->> host
       (Inet6Address/getAllByName)
       (into [])))

Returns an Inet6Address.

This creates an Inet6Address in a similar manner as with the 2-arity ipnet-core/by-address except that a third argument is provided:

  • either the IPv6 scope id is set by passing an integer represenging the scope id, or
  • the IPv6 scope_id is set to the value corresponding to the given interface for the address type specified with addr.

    Note: as with InetAddress, and Inet4Address, the expected type of addr is a vector of integers, e.g.: ```clj (by-address "localhost" [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1] 0) ```

(defn by-address
  [host addr scope-or-nif]
  (Inet6Address/getByAddress host (byte-array addr) scope-or-nif))

Determines the IP address of a host, given the host's name.

(defn by-name
  [host]
  (Inet6Address/getByName host))

Returns the address of the local host.

(defn localhost
  []
  (Inet6Address/getLocalHost))

Returns the loopback address.

(defn loopback
  []
  (Inet6Address/getLoopbackAddress))

Protocol ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprotocol IPV6Address
  (scoped-interface [this]
    "Returns the scoped interface, if this instance was created with with a
    scoped interface.")
  (scope-id [this]
    "Returns the numeric scopeId, if this instance is associated with an
    interface.")
  (ipv4-compatible-address? [this]
    "Utility routine to check if the InetAddress is an IPv4 compatible IPv6
    address."))

Implementation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def behaviour
  (merge
    ipnet-core/behaviour
    {:scoped-interface (fn [this] (.getScopedInterface this))
     :scope-id (fn [this] (.getScopeId this))
     :ipv4-compatible-address? (fn [this] (.isIPv4CompatibleAddress this))}))
(extend Inet6Address IPV6Address behaviour)
(extend Inet6Address ipnet-core/Address behaviour)

Constructors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def create #'by-address)

Aliases ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(import-vars
  [ipnet-core
   ;; behaviour
   address
   canonical-hostname
   host-address
   hostname
   any-local-address?
   link-local-address?
   loopback-address?
   mc-global?
   mc-link-local?
   mc-node-local?
   mc-org-local?
   mc-site-local?
   multicast-address?
   reachable?
   site-local-address?])
 
(ns inet.interface
  (:refer-clojure :exclude [index name])
  (:import
    (java.net NetworkInterface)))

Static Methods ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Get a network interface given its index.

(defn by-index
  [idx]
  (NetworkInterface/getByIndex idx))

Convenience method to search for a network interface that has the specified Internet Protocol (IP) address bound to it.

(defn by-inet-address
  [addr]
  (NetworkInterface/getByInetAddress addr))

Searches for the network interface with the specified name.

(defn by-name
  [iface-name]
  (NetworkInterface/getByName iface-name))

Returns all the interfaces on this machine.

(defn network-interfaces
  []
  (-> (NetworkInterface/getNetworkInterfaces)
      (enumeration-seq)
      (vec)))

Protocol ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprotocol NetInterface
  (display-name [this]
    "Get the display name of this network interface.")
  (hardware-address [this]
    "Returns the hardware address (usually MAC) of the interface if it has
    one and if it can be accessed given the current privileges.")
  (index [this]
    "Returns the index of this network interface.")
  (inet-addresses [this]
    "Convenience method to return an Enumeration with all or a subset of the
    InetAddresses bound to this network interface.")
  (interface-addresses [this]
    "Get a List of all or a subset of the InterfaceAddresses of this network
    interface.")
  (mtu [this]
    "Returns the Maximum Transmission Unit (MTU) of this interface.")
  (name [this]
    "Get the name of this network interface.")
  (parent [this]
    "Returns the parent NetworkInterface of this interface if this is a
    subinterface, or null if it is a physical (non virtual) interface or has
    no parent.")
  (sub-interfaces [this]
    "Get an Enumeration with all the subinterfaces (also known as virtual
    interfaces) attached to this network interface.")
  (loopback? [this]
    "Returns whether a network interface is a loopback interface.")
  (point-to-point? [this]
    "Returns whether a network interface is a point to point interface.")
  (up? [this]
    "Returns whether a network interface is up and running.")
  (virtual? [this]
    "Returns whether this interface is a virtual interface (also called
    subinterface).")
  (supports-multicast? [this]
    "Returns whether a network interface supports multicasting or not."))

Implementation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def behaviour
  {:display-name (fn [this] (.getDisplayName this))
   :hardware-address (fn [this] (->> (.getHardwareAddress this)
                                     (map #(format "%02x" %))
                                     (vec)))
   :index (fn [this] (.getIndex this))
   :inet-addresses (fn [this] (-> (.getInetAddresses this)
                                  (enumeration-seq)
                                  (vec)))
   :interface-addresses (fn [this] (.getInterfaceAddresses this))
   :mtu (fn [this] (.getMTU this))
   :name (fn [this] (.getName this))
   :parent (fn [this] (.getParent this))
   :sub-interfaces (fn [this] (-> (.getSubInterfaces this)
                                  (enumeration-seq)
                                  (vec)))
   :loopback? (fn [this] (.isLoopback this))
   :point-to-point? (fn [this] (.isPointToPoint this))
   :up? (fn [this] (.isUp this))
   :virtual? (fn [this] (.isVirtual this))
   :supports-multicast? (fn [this] (.supportsMulticast this))})
(extend NetworkInterface NetInterface behaviour)

Constructors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;