#lang racket (require racket/struct) (provide peer 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) (let ([parts (reverse (string-split str "."))]) (for/sum ([i (in-range 4)] [part parts]) (arithmetic-shift (string->number part) (* i 8))))) (define (ip->string ip) (string-join (reverse (for/list ([i (in-range 4)]) (number->string (bitwise-and (arithmetic-shift ip (* i -8)) 255)))) ".")) (define (string->subnet str) (match (string-split str "/") [(list ipstr maskstr) (subnet (string->ip ipstr) (string->number maskstr))])) (define (subnet->string sub) (string-append (ip->string (subnet-ip sub)) "/" (number->string (subnet-mask sub)))) (define (string->peer str) (match (string-split str "-") [(list ip type) (peer (string->ip ip) (string->symbol type))]))