d5e5ab05463eac633e627cdd506909749a0708ca
[controller.git] / third-party / openflowj / src / main / java / org / openflow / protocol / action / ActionVendorOutputNextHop.java
1 package org.openflow.protocol.action;
2
3         import java.net.Inet4Address;
4         import java.net.InetAddress;
5         import java.net.UnknownHostException;
6 import java.nio.ByteBuffer;
7
8 import org.openflow.util.HexString;
9
10
11         public class ActionVendorOutputNextHop extends OFActionVendor {
12                 private static final long serialVersionUID = 1L;
13                 private static int VENDOR_CISCO = 0xC;
14                 private enum ONHLength {
15                         ONH_LEN_MIN(16),
16                         ONH_LEN_P2P(16),
17                         ONH_LEN_IPV4(24),
18                         ONH_LEN_MAC(32),
19                         ONH_LEN_IPV6(40);
20                 private int value;
21                 private ONHLength(int value) {
22                         this.value = value;
23                 }
24                 public int getValue() {
25                         return this.value;
26                 }
27                 }       
28                 private enum ONHActionType {
29                         ONH_ACTION_NONE(0),
30                         ONH_ACTION_OUTPUT_NH(1),
31                         ONH_ACTION_NETFLOW(2);
32                 private int value;
33                 private ONHActionType(int value) {
34                         this.value = value;
35                 }
36                 public int getValue() {
37                         return this.value;
38                 }
39                 }
40                 private enum ONHAddressType {
41                 ONH_ADDRTYPE_NONE(0),
42                 ONH_ADDRTYPE_P2P(1),
43                 ONH_ADDRTYPE_IPV4(2),
44                 ONH_ADDRTYPE_IPV6(3),
45                 ONH_ADDRTYPE_MAC48(4);
46                 private int value;
47                 private ONHAddressType(int value) {
48                         this.value = value;
49                 }
50                 public int getValue() {
51                         return this.value;
52                 }
53             }
54             private enum ONHXAddressType {
55                 ONH_XADDRTYPE_NONE(0),
56                 ONH_XADDRTYPE_PORT(1),
57                 ONH_XADDRTYPE_VPNID(2);
58                 private int value;
59                 private ONHXAddressType(int value) {
60                         this.value = value;
61                 }
62                 public int getValue() {
63                         return this.value;
64                 }
65            }
66                 protected InetAddress address; 
67                         
68                 public ActionVendorOutputNextHop() {
69                 super();
70                 super.setLength((short)ONHLength.ONH_LEN_MIN.getValue());
71                         super.setVendor(VENDOR_CISCO);
72                         this.address = null;
73                 }
74                 
75                 public void setNextHop(InetAddress address) {
76                         short actionLen;
77                         if (address instanceof Inet4Address) 
78                                 actionLen = (short)ONHLength.ONH_LEN_IPV4.getValue();
79                         else
80                                 actionLen = (short)ONHLength.ONH_LEN_IPV6.getValue();
81                         super.setLength(actionLen);
82                         this.address = address;
83                 }
84                 public InetAddress getNextHop() {
85                         return this.address;
86                 }
87             @Override
88             public void readFrom(ByteBuffer data) {
89                 /*
90                  * For now, only contains the next hop address
91                  */
92                 //super.readFrom(data); don't need this
93                 
94                 if (data.remaining() < super.getLength()-8) {
95                         /*
96                          * malformed element, skip over 
97                          */
98                         data.position(data.remaining());
99                         return;
100                 }
101                 if ((super.getLength() !=  (short)ONHLength.ONH_LEN_IPV4.getValue()) &&
102                         (super.getLength() !=  (short)ONHLength.ONH_LEN_IPV6.getValue())) {
103                         /*
104                          * mal-formed element, skip over 
105                          */
106                         data.position(super.getLength());
107                         return;
108                 }
109                 data.getShort();  // skip the ONH_ACTION_OUTPUT_NH
110                 data.getShort(); // skip address and xtraaddress types
111                 data.getInt();     // skip the extra address (8 bytes)
112                 data.getInt();
113                 byte[] a;
114                 if (super.getLength() == (short)ONHLength.ONH_LEN_IPV4.getValue()) {
115                         a = new byte[4];
116                         data.get(a);
117                 } else {
118                         a = new byte[16];
119                         data.get(a);
120                         data.getInt(); //4 bytes pad
121                 }
122                 try {
123                         this.address = InetAddress.getByAddress(a);
124                 } catch (UnknownHostException e) {
125                         e.printStackTrace();
126                 }
127             }
128
129             @Override
130             public void writeTo(ByteBuffer data) {
131                 byte atype = (byte)(ONHAddressType.ONH_ADDRTYPE_NONE.getValue());
132                 byte xatype = (byte)(ONHXAddressType.ONH_XADDRTYPE_NONE.getValue());
133                 if (address instanceof Inet4Address) 
134                         atype =  (byte)(ONHAddressType.ONH_ADDRTYPE_IPV4.getValue());
135                 else
136                         atype = (byte)(ONHAddressType.ONH_ADDRTYPE_IPV6.getValue());
137                 super.writeTo(data); // this writes the standard  8byte ofp_action_vendor_header
138                 data.putShort((short)(ONHActionType.ONH_ACTION_OUTPUT_NH.getValue()));
139                 data.put(atype);
140                 data.put(xatype);
141                 /*
142                  * write the xtra address. For now it is all 0
143                  */
144                 data.putInt(0); // 8-byte pad
145                 data.putInt(0);
146                 /* 
147                  * write the address only when address type is not P2P
148                  */
149                 if (atype == (byte)(ONHAddressType.ONH_ADDRTYPE_IPV4.getValue())) {
150                         data.put(address.getAddress()); // no need to pad
151                         //avnh.put(address.getAddress()); 
152                 } else if (atype == (byte)(ONHAddressType.ONH_ADDRTYPE_IPV6.getValue())) {
153                         data.put(address.getAddress());
154                         //avnh.put(address.getAddress());
155                         data.putInt(0); // 4-byte pad
156                         //avnh.putInt(0);
157                 }
158                 ActionVendorOutputNextHop a = new ActionVendorOutputNextHop();
159                 a.setLength((short)24);
160             }
161
162             @Override
163             public int hashCode() {
164                 final int prime = 347;
165                 int result = super.hashCode();
166                 result = prime * result + address.hashCode();
167                 return result;
168             }
169
170             @Override
171             public boolean equals(Object obj) {
172                 if (this == obj) {
173                     return true;
174                 }
175                 if (!super.equals(obj)) {
176                     return false;
177                 }
178                 if (!(obj instanceof ActionVendorOutputNextHop)) {
179                     return false;
180                 }
181                 ActionVendorOutputNextHop other = (ActionVendorOutputNextHop) obj;
182                 if (!other.address.equals(this.address))
183                         return false;
184                 return true;
185             }
186
187                 public String toString() {
188                         return ("OutputNextHop: " + address.getHostAddress());
189                 }
190
191         }
192