Skip to content

Commit bb5d614

Browse files
committed
function to anonymize IP addresses
1 parent 1008469 commit bb5d614

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

helpers.lisp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,39 @@
4949
(defun hash! (field)
5050
(declare (ignore field)))
5151

52-
;; copy permutation algo from python code
53-
(defun anonip! (ip)
54-
(declare (ignore ip)))
52+
(let* ((v6-permutors (loop repeat 16 collect (ax:shuffle (coerce (loop for x upto 255 collect x) 'vector))))
53+
(v4-permutors (nthcdr 12 v6-permutors))
54+
(v4-string-permutors (loop for p in v4-permutors collect (map 'vector #'write-to-string p))))
55+
;; TODO: IP-ADDRESS operation is destructive but STRING one is not. Hmm.
56+
(defgeneric anonip (ip)
57+
(:documentation "Anonymize an IP address by permuting each byte with a fixed set of permutations for each byte.")
58+
(:method ((ip string))
59+
(if (na::ipv4-str? ip)
60+
(let ((quads (split-sequence #\. ip)))
61+
(setf (first quads) (aref (first v4-string-permutors) (parse-integer (first quads)))
62+
(second quads) (aref (second v4-string-permutors) (parse-integer (second quads)))
63+
(third quads) (aref (third v4-string-permutors) (parse-integer (third quads)))
64+
(fourth quads) (aref (fourth v4-string-permutors) (parse-integer (fourth quads))))
65+
(str:join "." quads))
66+
(na:str (anonip (na:make-ip-address ip)))))
67+
(:method ((ip na::ip-address))
68+
(let ((version (na:version ip)))
69+
(loop for offset from (if (= version 4) 24 120) downto 0 by 8
70+
for permutor in (if (= version 4) v4-permutors v6-permutors)
71+
do (setf (ldb (byte 8 offset) (slot-value ip 'netaddr::int))
72+
(aref permutor (ldb (byte 8 offset) (slot-value ip 'netaddr::int)))))
73+
(setf (slot-value ip 'netaddr:str) (na::ip-int-to-str (na:int ip) version))
74+
ip)))
75+
76+
;; TODO: lazy way: anonymize the whole IP, but still apply the mask which will just 0 out the bytes that don't matter
77+
;; smarter way: only anonymize the bytes that aren't masked.
78+
(defgeneric anoncidr (cidr)
79+
(:method ((cidr string))
80+
(error "not implemented!"))
81+
(:method ((cidr na::ip-network))
82+
(error "not implemented!"))))
83+
84+
;; is there a reasonable way to anonymize domains?
5585

5686
;; probably need to replace the symbol with a call to (PRODUCTIVE? LOG) in main.
5787
(defun productive? (zeek-log)

main.lisp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@
157157

158158
;; SETF is a macro that needs to be expanded _after_ we update the columns, otherwise it won't use the SETF function for
159159
;; GET-VALUE.
160+
;; TODO: allow suffixing normal functions with ! to automatically expand to a SETF form, i.e.,
161+
;; (anonip! @o_h) -> (setf @o_h (anonip @o_h)) -> (setf (get-value log @id.orig_h) (anonip (get-value log @id.orig_h)))
162+
;; probably need to use MACROEXPAND instead of MACROEXPAND-1?
160163
(defun compile-runtime-mutators (s)
161164
(when s
162165
(let* ((raw-mutators (with-input-from-string (in s)

0 commit comments

Comments
 (0)