CS3700-project2/iputil.rkt

73 lines
2.0 KiB
Racket
Raw Normal View History

2020-01-29 21:23:07 +00:00
#lang racket
2020-01-30 23:09:05 +00:00
(provide (struct-out peer) (struct-out subnet)
2020-01-29 21:23:07 +00:00
string->ip
ip->string
2020-01-31 00:32:01 +00:00
ip-netmask
2020-01-29 21:23:07 +00:00
string->subnet
subnet->string
string->peer)
2020-01-31 00:32:01 +00:00
(require racket/struct)
(module+ test
(require rackunit))
2020-01-29 21:23:07 +00:00
(struct peer [ip type]
2020-01-31 00:47:32 +00:00
#:transparent
2020-01-30 23:09:05 +00:00
#: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)))))])
2020-01-29 21:23:07 +00:00
(struct subnet [ip mask]
2020-01-31 00:47:32 +00:00
#:transparent
2020-01-30 23:09:05 +00:00
#:methods gen:custom-write
[(define write-proc
(make-constructor-style-printer
(lambda (x) 'subnet)
(lambda (x) (list (subnet->string x)))))])
2020-01-29 21:23:07 +00:00
(define (string->ip str)
2020-01-30 23:09:05 +00:00
(define parts (reverse (string-split str ".")))
(for/sum ([part (in-list parts)]
[i (in-naturals)])
(arithmetic-shift (string->number part)
(* i 8))))
2020-01-29 21:23:07 +00:00
(define (ip->string ip)
2020-01-30 23:09:05 +00:00
(define parts
(reverse (for/list ([i (in-range 4)])
(number->string (bitwise-and (arithmetic-shift ip (* i -8))
255)))))
(string-join parts "."))
2020-01-29 21:23:07 +00:00
2020-01-31 00:32:01 +00:00
(define (ip-netmask ip)
(for/sum ([i (in-range 32)])
#:break (positive? (bitwise-and ip (arithmetic-shift 1 i)))
1))
2020-01-29 21:23:07 +00:00
(define (string->subnet str)
2020-01-30 23:09:05 +00:00
(match-define (list ipstr maskstr) (string-split str "/"))
(subnet (string->ip ipstr)
(string->number maskstr)))
2020-01-29 21:23:07 +00:00
(define (subnet->string sub)
2020-01-30 23:09:05 +00:00
(format "~a/~a"
2020-01-31 00:32:01 +00:00
(ip->string (subnet-ip sub))
2020-01-30 23:09:05 +00:00
(subnet-mask sub)))
2020-01-29 21:23:07 +00:00
(define (string->peer str)
2020-01-30 23:09:05 +00:00
(match-define (list ip type) (string-split str "-"))
(peer (string->ip ip) (string->symbol type)))
2020-01-31 00:32:01 +00:00
;; ================================================================================
(module+ test
(check-equal? (ip->string (string->ip "123.84.0.67")) "123.84.0.67")
(check-equal? (ip->string (string->ip "0.0.0.0")) "0.0.0.0")
(check-equal? (ip-netmask (string->ip "255.255.254.0")) 9)
(check-equal? (ip-netmask (string->ip "255.0.0.0")) 24))