47d3ed747e4f32ee4486d5d5ef0f5133aba6f211
[netvirt.git] / dhcpservice / dhcpservice-api / src / main / java / org / opendaylight / vpnservice / dhcpservice / api / DHCPOptions.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.vpnservice.dhcpservice.api;
10
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13 import java.util.LinkedHashMap;
14
15
16
17 import java.util.List;
18
19 import org.apache.commons.lang3.ArrayUtils;
20 import org.opendaylight.controller.liblldp.HexEncode;
21 import org.opendaylight.controller.liblldp.NetUtils;
22 //import org.apache.commons.lang3.ArrayUtils;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import static org.opendaylight.vpnservice.dhcpservice.api.DHCPConstants.*;
27
28 public class DHCPOptions {
29     protected static final Logger logger = LoggerFactory
30             .getLogger(DHCPOptions.class);
31
32     class DhcpOption extends Object {
33         private byte code;
34         private byte length;
35         private byte[] value;
36
37         public DhcpOption(byte code, byte[] value) {
38             if ((code != OPT_PAD) && (code != OPT_END) && (value != null)) {
39                 this.code = code;
40                 this.value = value;
41                 this.length = (byte) value.length;
42             }
43         }
44
45         public byte getCode() {
46             return this.code;
47         }
48
49         public byte[] getValue() {
50             return this.value;
51         }
52
53         public byte[] serialize() {
54             byte[] opt1 = new byte[2];
55             opt1[0] = this.code;
56             opt1[1] = this.length;
57             return ArrayUtils.addAll(opt1, this.value);
58         }
59
60         @Override
61         public String toString() {
62             StringBuilder sb = new StringBuilder();
63             sb.append("{ ")
64             .append("code: ").append(this.code)
65             .append(", len: ").append(this.length)
66             .append(", value: 0x").append(HexEncode.bytesToHexString(this.value))
67             .append(" }");
68             return sb.toString();
69         }
70     }
71
72     private LinkedHashMap<Byte, DhcpOption> options;
73
74     public DHCPOptions() {
75         options = new LinkedHashMap<Byte, DhcpOption>();
76     }
77
78     private void setOption(DhcpOption opt) {
79         this.options.put(opt.getCode(), opt);
80     }
81
82     private DhcpOption getOption(byte code) {
83         return this.options.get(code);
84     }
85
86     public void setOption(byte code, byte[] opt) {
87         this.setOption(new DhcpOption(code, opt));
88     }
89
90     public byte[] getOptionBytes(byte code) {
91         try{
92             return this.getOption(code).getValue();
93         }
94         catch (NullPointerException e)
95         {
96             return null;
97         }
98     }
99
100     public void setOptionByte(byte code, byte opt) {
101         this.setOption(new DhcpOption(code, DHCPUtils.byteToByteArray(opt)));
102     }
103
104     public byte getOptionByte(byte code) {
105         return this.getOption(code).getValue()[0];
106     }
107
108     public void setOptionShort(byte code, short opt) {
109         this.setOption(new DhcpOption(code, DHCPUtils.shortToByteArray(opt)));
110     }
111
112     public short getOptionShort(byte code) {
113         byte[] opt = this.getOptionBytes(code);
114         return DHCPUtils.byteArrayToShort(opt);
115     }
116
117     public void setOptionInt(byte code, int opt) {
118         this.setOption(new DhcpOption(code, DHCPUtils.intToByteArray(opt)));
119     }
120
121     public int getOptionInt(byte code) {
122         byte[] opt = this.getOptionBytes(code);
123         return NetUtils.byteArray4ToInt(opt);
124     }
125
126     public void setOptionInetAddr(byte code, InetAddress opt) {
127         this.setOption(new DhcpOption(code, DHCPUtils.inetAddrToByteArray(opt)));
128     }
129
130     public InetAddress getOptionInetAddr(byte code) {
131         byte[] opt = this.getOptionBytes(code);
132         try {
133             return InetAddress.getByAddress(opt);
134         } catch (UnknownHostException | NullPointerException e) {
135             return null;
136         }
137     }
138
139     public void setOptionStrAddr(byte code, String opt) throws UnknownHostException {
140         this.setOption(new DhcpOption(code, DHCPUtils.strAddrToByteArray(opt)));
141     }
142
143     public String getOptionStrAddr(byte code) {
144         byte[] opt = this.getOptionBytes(code);
145         try {
146             return InetAddress.getByAddress(opt).getHostAddress();
147         } catch (UnknownHostException| NullPointerException e) {
148             return null;
149         }
150     }
151
152     public void setOptionStrAddrs(byte code, List<String> addrs) throws UnknownHostException {
153         if(!addrs.isEmpty()) {
154             this.setOption(new DhcpOption(code, DHCPUtils.strListAddrsToByteArray(addrs)));
155         }
156     }
157
158     public void setOptionString(byte code, String str) {
159         this.setOption(new DhcpOption(code, str.getBytes()));
160     }
161
162     public byte[] serialize() {
163         byte[] options = new byte[0];
164         for(DhcpOption dOpt: this.options.values()) {
165             options = ArrayUtils.addAll(options, dOpt.serialize());
166         }
167         byte[] end = new byte[] {(byte)255};
168         options = ArrayUtils.addAll(options, end);
169         return options;
170     }
171
172     private byte[] getOptionValArray(byte[] opt, int pos, int len) {
173         byte[] val = new byte[len];
174         for(int i = 0; i < len; i++) {
175             val[i] = opt[pos + i];
176         }
177         return val;
178     }
179
180     public void deserialize(byte[] options) {
181         int pos = 0;
182         byte code, len;
183         byte[] value;
184         if (options != null) {
185             while (pos < options.length) {
186                 code = options[pos++];
187                 if (code == OPT_END) {
188                     break;
189                 }
190                 len = options[pos++];
191                 if ((len + pos) > options.length) {
192                     // Throw exception???
193                     break;
194                 }
195                 value = getOptionValArray(options, pos, len);
196                 setOption(code, value);
197                 pos += len;
198             }
199         }
200     }
201
202     @Override
203     public String toString() {
204         StringBuilder sb = new StringBuilder();
205         sb.append("{");
206         int i = 1;
207         for(DhcpOption dOpt: this.options.values()) {
208             //options = ArrayUtils.addAll(options, dOpt.serialize());
209             sb.append("Option").append(i++)
210             .append(dOpt.toString());
211         }
212         sb.append("}");
213         return sb.toString();
214     }
215
216     public boolean containsOption(byte code) {
217         return options.containsKey(code);
218     }
219
220     public DhcpOption unsetOption(byte code) {
221         return options.remove(code);
222     }
223
224 }
225