1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.directory.server.dhcp.protocol;
22
23
24 import java.net.InetAddress;
25 import java.net.InetSocketAddress;
26
27 import org.apache.directory.server.dhcp.messages.DhcpMessage;
28 import org.apache.directory.server.dhcp.messages.MessageType;
29 import org.apache.directory.server.dhcp.service.DhcpService;
30 import org.apache.mina.core.service.IoHandlerAdapter;
31 import org.apache.mina.core.session.IdleStatus;
32 import org.apache.mina.core.session.IoSession;
33 import org.apache.mina.filter.codec.ProtocolCodecFilter;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37
38
39
40
41
42
43
44
45 public class DhcpProtocolHandler extends IoHandlerAdapter
46 {
47 private static final Logger LOG = LoggerFactory.getLogger( DhcpProtocolHandler.class );
48
49
50
51
52 public static final int CLIENT_PORT = 68;
53
54
55
56
57 public static final int SERVER_PORT = 67;
58
59
60
61
62
63 private final DhcpService dhcpService;
64
65
66
67
68
69 public DhcpProtocolHandler( DhcpService service )
70 {
71 this.dhcpService = service;
72 }
73
74
75 @Override
76 public void sessionCreated( IoSession session ) throws Exception
77 {
78 LOG.debug( "{} CREATED", session.getLocalAddress() );
79 session.getFilterChain().addFirst( "codec",
80 new ProtocolCodecFilter( new DhcpProtocolCodecFactory() ) );
81 }
82
83
84 @Override
85 public void sessionOpened( IoSession session )
86 {
87 LOG.debug( "{} -> {} OPENED", session.getRemoteAddress(), session
88 .getLocalAddress() );
89 }
90
91
92 @Override
93 public void sessionClosed( IoSession session )
94 {
95 LOG.debug( "{} -> {} CLOSED", session.getRemoteAddress(), session
96 .getLocalAddress() );
97 }
98
99
100 @Override
101 public void sessionIdle( IoSession session, IdleStatus status )
102 {
103
104 }
105
106
107 @Override
108 public void exceptionCaught( IoSession session, Throwable cause )
109 {
110 LOG.error( "EXCEPTION CAUGHT ", cause );
111 cause.printStackTrace( System.out );
112
113 session.closeNow();
114 }
115
116
117 @Override
118 public void messageReceived( IoSession session, Object message )
119 throws Exception
120 {
121 if ( LOG.isDebugEnabled() )
122 {
123 LOG.debug( "{} -> {} RCVD: {} ", message, session.getRemoteAddress(),
124 session.getLocalAddress() );
125 }
126
127 final DhcpMessage./../../../org/apache/directory/server/dhcp/messages/DhcpMessage.html#DhcpMessage">DhcpMessage request = ( DhcpMessage ) message;
128
129 final DhcpMessage reply = dhcpService.getReplyFor(
130 ( InetSocketAddress ) session.getServiceAddress(),
131 ( InetSocketAddress ) session.getRemoteAddress(), request );
132
133 if ( null != reply )
134 {
135 final InetSocketAddress isa = determineMessageDestination( request, reply );
136 session.write( reply, isa );
137 }
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
161 private InetSocketAddress determineMessageDestination( DhcpMessage request,
162 DhcpMessage reply )
163 {
164
165 final MessageType mt = reply.getMessageType();
166
167 if ( !isNullAddress( request.getRelayAgentAddress() ) )
168 {
169
170 return new InetSocketAddress( request.getRelayAgentAddress(), SERVER_PORT );
171 }
172 else if ( null != mt && mt == MessageType.DHCPNAK )
173 {
174
175 return new InetSocketAddress( "255.255.255.255", 68 );
176 }
177 else
178 {
179
180 if ( !isNullAddress( request.getCurrentClientAddress() ) )
181 {
182
183 return new InetSocketAddress( request.getCurrentClientAddress(),
184 CLIENT_PORT );
185 }
186 else
187 {
188 return new InetSocketAddress( "255.255.255.255", 68 );
189 }
190 }
191 }
192
193
194
195
196
197
198
199
200
201 private boolean isNullAddress( InetAddress addr )
202 {
203 final byte[] a = addr.getAddress();
204
205 for ( int i = 0; i < a.length; i++ )
206 {
207 if ( a[i] != 0 )
208 {
209 return false;
210 }
211 }
212
213 return true;
214 }
215
216
217 @Override
218 public void messageSent( IoSession session, Object message )
219 {
220 if ( LOG.isDebugEnabled() )
221 {
222 LOG.debug( "{} -> {} SENT: ", message, session.getRemoteAddress(),
223 session.getLocalAddress() );
224 }
225 }
226
227
228 @Override
229 public void inputClosed( IoSession session )
230 {
231 }
232 }