about summary refs log tree commit diff
path: root/tools/ipconverter
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ipconverter')
-rw-r--r--tools/ipconverter/default.nix39
-rw-r--r--tools/ipconverter/go.mod3
-rwxr-xr-xtools/ipconverter/ipconverter.py29
-rw-r--r--tools/ipconverter/main.go63
-rw-r--r--tools/ipconverter/main_test.go43
5 files changed, 55 insertions, 122 deletions
diff --git a/tools/ipconverter/default.nix b/tools/ipconverter/default.nix
index c4d2f3a..ae08d0f 100644
--- a/tools/ipconverter/default.nix
+++ b/tools/ipconverter/default.nix
@@ -1,15 +1,28 @@
-{ pkgs, buildGoModule, ... }:
-
-buildGoModule rec {
-  name = "ipconverter";
-  src = ./.;
-  vendorSha256 = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo=";
-  nativeBuildInputs = with pkgs; [ go ];
-
-  meta = with pkgs.lib; {
-    description = "CLI to convert IP addresses to integer and vice versa";
-    license = licenses.mit;
-    platforms = platforms.linux;
-    maintainers = [ ];
+{ lib, python3, stdenvNoCC, pkgs }:
+
+stdenvNoCC.mkDerivation rec {
+  pname = "ipconverter";
+  version = "0.1.0";
+
+  src = ./ipconverter.py;
+
+  buildInputs = [ python3 ];
+
+  dontUnpack = true;
+  dontBuild = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp $src $out/bin/${pname}
+    chmod a+x $out/bin/${pname}
+    ln -s $out/bin/${pname} $out/bin/ip2int
+    ln -s $out/bin/${pname} $out/bin/int2ip
+  '';
+
+  meta = with lib; {
+    description = "Helper script to convert an IP address to an integer.";
+    license = with licenses; [ mit ];
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ fcuny ];
   };
 }
diff --git a/tools/ipconverter/go.mod b/tools/ipconverter/go.mod
deleted file mode 100644
index 49b8653..0000000
--- a/tools/ipconverter/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module golang.fcuny.net/ipconverter
-
-go 1.17
diff --git a/tools/ipconverter/ipconverter.py b/tools/ipconverter/ipconverter.py
new file mode 100755
index 0000000..fffc6fa
--- /dev/null
+++ b/tools/ipconverter/ipconverter.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+
+import argparse
+import ipaddress
+import sys
+import fileinput
+
+
+argp = argparse.ArgumentParser()
+argp.add_argument("infile", nargs="?", type=argparse.FileType("r"), default=sys.stdin)
+args = argp.parse_args()
+
+# read the input, filter out commented lines and remove new line characters
+string_ips = [
+    ip for l in args.infile.readlines() if (ip := l.strip()) and not ip.startswith("#")
+]
+
+# convert entries to int if the string is a numeric value
+ips = list(map(lambda n: int(n) if n.isnumeric() else n, string_ips))
+
+# helper function to convert based on the name of the program
+conv = lambda n: int(n) if argp.prog == "ip2int" else str(n)
+
+for ip in ips:
+    try:
+        r = conv(ipaddress.ip_address(ip))
+        print(f"{ip:15} → {r:15}")
+    except Exception as e:
+        print(f"error: {e}", file=sys.stderr)
diff --git a/tools/ipconverter/main.go b/tools/ipconverter/main.go
deleted file mode 100644
index 42baf7c..0000000
--- a/tools/ipconverter/main.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package main
-
-import (
-	"encoding/binary"
-	"fmt"
-	"math/big"
-	"net"
-	"os"
-	"path"
-	"strconv"
-)
-
-func main() {
-	if len(os.Args) < 2 {
-		fmt.Fprintf(os.Stderr, "usage: %s <ip2int|int2ip> <values>\n", os.Args[0])
-		os.Exit(1)
-	}
-
-	cmd := path.Base(os.Args[1])
-
-	switch cmd {
-	case "ip2int":
-		for _, ip := range os.Args[2:] {
-			r, err := IPtoInt(ip)
-			if err != nil {
-				fmt.Fprintf(os.Stderr, "failed to parse %s to an int: %s\n", ip, err)
-				continue
-			}
-			fmt.Printf("%s\t%d\n", ip, r)
-		}
-	case "int2ip":
-		for _, ip := range os.Args[2:] {
-			r, err := IPtoN(ip)
-			if err != nil {
-				fmt.Fprintf(os.Stderr, "failed to parse %s to an addresse IP: %s\n", ip, err)
-				continue
-			}
-			fmt.Printf("%s\t%s\n", ip, r)
-		}
-	default:
-		fmt.Fprintf(os.Stderr, "`%s' is not a supported command\n", cmd)
-		os.Exit(1)
-	}
-}
-
-func IPtoInt(ip string) (*big.Int, error) {
-	i := net.ParseIP(ip)
-	if len(i.To4()) == 4 {
-		return big.NewInt(0).SetBytes(i.To4()), nil
-	} else {
-		return nil, fmt.Errorf("%s is not an IPv4 address", ip)
-	}
-}
-
-func IPtoN(ip string) (string, error) {
-	r, err := strconv.Atoi(ip)
-	if err != nil {
-		return "", fmt.Errorf("failed to parse %s to an int: %s", ip, err)
-	}
-	newIP := make(net.IP, 4)
-	binary.BigEndian.PutUint32(newIP, uint32(r))
-	return newIP.To4().String(), nil
-}
diff --git a/tools/ipconverter/main_test.go b/tools/ipconverter/main_test.go
deleted file mode 100644
index 10d09ab..0000000
--- a/tools/ipconverter/main_test.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package main
-
-import (
-	"math/big"
-	"testing"
-)
-
-func TestIPtoInt(t *testing.T) {
-
-	tests := map[string]*big.Int{
-		"192.168.0.1": big.NewInt(3232235521),
-		"10.0.0.1":    big.NewInt(167772161),
-	}
-	for test := range tests {
-		r, err := IPtoInt(test)
-		if err != nil {
-			t.Errorf("failed to convert %s to an int: %s", test, err)
-		}
-		if r.Cmp(tests[test]) != 0 {
-			t.Errorf("convert %s to int, got %d expected %d", test, r, tests[test])
-		}
-	}
-
-	if _, err := IPtoInt("10"); err == nil {
-		t.Error("calling IPtoInt with invalid IP did not result in error")
-	}
-}
-
-func TestIPtoN(t *testing.T) {
-	tests := map[string]string{
-		"3232235521": "192.168.0.1",
-		"167772161":  "10.0.0.1",
-	}
-	for test := range tests {
-		r, err := IPtoN(test)
-		if err != nil {
-			t.Errorf("failed to convert %s to an address: %s", test, err)
-		}
-		if r != tests[test] {
-			t.Errorf("convert %s to address, got %s expected %s", test, r, tests[test])
-		}
-	}
-}