#lang racket (require racket/struct) (provide (struct-out peer) (struct-out subnet) string->ip ip->string string->subnet subnet->string string->peer) (struct peer [ip type] #:methods gen:custom-write [(define write-proc (make-constructor-style-printer (lambda (x) 'peer) (lambda (x) (list (ip->string (peer-ip x)) (peer-type x)))))]) (struct subnet [ip mask] #:methods gen:custom-write [(define write-proc (make-constructor-style-printer (lambda (x) 'subnet) (lambda (x) (list (subnet->string x)))))]) (define (string->ip str) (define parts (reverse (string-split str "."))) (for/sum ([part (in-list parts)] [i (in-naturals)]) (arithmetic-shift (string->number part) (* i 8)))) (define (ip->string ip) (define parts (reverse (for/list ([i (in-range 4)]) (number->string (bitwise-and (arithmetic-shift ip (* i -8)) 255))))) (string-join parts ".")) (define (string->subnet str) (match-define (list ipstr maskstr) (string-split str "/")) (subnet (string->ip ipstr) (string->number maskstr))) (define (subnet->string sub) (format "~a/~a" (subnet-ip sub) (subnet-mask sub))) (define (string->peer str) (match-define (list ip type) (string-split str "-")) (peer (string->ip ip) (string->symbol type)))