blob: ac5ce6d2f5ec53fc2d5fc140fbbd88a72ecd2ceb [file] [log] [blame]
David K. Bainbridge8bc905c2016-05-31 14:07:10 -07001package main
2
David K. Bainbridge252cc2c2016-06-02 22:28:59 -07003import (
4 "math"
5 "net"
6 "strconv"
7 "strings"
8)
9
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070010type Storage interface {
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070011 Init(networkIn string, skip int) error
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070012 Get(mac string) (string, error)
13 GetAll() map[string]string
14 Put(mac, ip string) error
15 Remove(mac string) (string, error)
16 Dequeue() (string, error)
17 Enqueue(ip string) error
18}
19
20type MemoryStorage struct {
21 allocated map[string]IPv4
22 available []IPv4
23 readIdx, writeIdx, size uint
24}
25
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070026func (s *MemoryStorage) Init(networkIn string, skip int) error {
27 _, network, err := net.ParseCIDR(networkIn)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070028 if err != nil {
29 return err
30 }
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070031 start, _, err := net.ParseCIDR(network.String())
32 if err != nil {
33 return err
34 }
35
36 parts := strings.Split(network.String(), "/")
37 ip, err := ParseIP(start.String())
38 if err != nil {
39 return err
40 }
41 bits, err := strconv.Atoi(parts[1])
42 if err != nil {
43 return err
44 }
45 hostCount := int(math.Pow(2, float64(32-bits))) - skip
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070046 s.readIdx = 0
47 s.writeIdx = 0
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070048 s.size = uint(hostCount)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070049 s.allocated = make(map[string]IPv4)
David K. Bainbridge252cc2c2016-06-02 22:28:59 -070050 s.available = make([]IPv4, hostCount)
51 for i := 0; i < skip; i += 1 {
52 ip, err = ip.Next()
53 if err != nil {
54 return err
55 }
56 }
57 for i := 0; i < hostCount; i += 1 {
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070058 s.available[i] = ip
59 ip, err = ip.Next()
60 if err != nil {
61 return err
62 }
63 }
64 return nil
65}
66
67func (s *MemoryStorage) Get(mac string) (string, error) {
68 ip, ok := s.allocated[mac]
69 if !ok {
70 return "", nil
71 }
72 return ip.String(), nil
73}
74
75func (s *MemoryStorage) GetAll() map[string]string {
76 all := make(map[string]string)
77 for k, v := range s.allocated {
78 all[k] = v.String()
79 }
80 return all
81}
82
83func (s *MemoryStorage) Put(mac, ip string) error {
84 data, err := ParseIP(ip)
85 if err != nil {
86 return err
87 }
88 s.allocated[mac] = data
89 return nil
90}
91
92func (s *MemoryStorage) Remove(mac string) (string, error) {
93 ip, ok := s.allocated[mac]
94 if !ok {
95 return "", nil
96 }
97 delete(s.allocated, mac)
98 return ip.String(), nil
99}
100
101func (s *MemoryStorage) Dequeue() (string, error) {
102 ip := s.available[s.readIdx]
103 s.readIdx = (s.readIdx + 1) % s.size
104 return ip.String(), nil
105}
106
107func (s *MemoryStorage) Enqueue(ip string) error {
108 data, err := ParseIP(ip)
109 if err != nil {
110 return err
111 }
112 s.available[s.writeIdx] = data
113 s.writeIdx = (s.writeIdx + 1) % s.size
114 return nil
115}