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.ntp.io;
22
23
24 import java.nio.ByteBuffer;
25
26 import org.apache.directory.server.ntp.messages.LeapIndicatorType;
27 import org.apache.directory.server.ntp.messages.ModeType;
28 import org.apache.directory.server.ntp.messages.NtpMessage;
29 import org.apache.directory.server.ntp.messages.NtpMessageModifier;
30 import org.apache.directory.server.ntp.messages.NtpTimeStamp;
31 import org.apache.directory.server.ntp.messages.ReferenceIdentifier;
32 import org.apache.directory.server.ntp.messages.StratumType;
33
34
35
36
37
38
39 public class NtpMessageDecoder
40 {
41
42
43
44
45
46
47 public NtpMessage decode( ByteBuffer request )
48 {
49 NtpMessageModifier modifier = new NtpMessageModifier();
50
51 byte header = request.get();
52 modifier.setLeapIndicator( parseLeapIndicator( header ) );
53 modifier.setVersionNumber( parseVersionNumber( header ) );
54 modifier.setMode( parseMode( header ) );
55 modifier.setStratum( parseStratum( request ) );
56 modifier.setPollInterval( parsePollInterval( request ) );
57 modifier.setPrecision( parsePrecision( request ) );
58 modifier.setRootDelay( parseRootDelay( request ) );
59 modifier.setRootDispersion( parseRootDispersion( request ) );
60 modifier.setReferenceIdentifier( parseReferenceIdentifier( request ) );
61 modifier.setReferenceTimestamp( new NtpTimeStamp( request ) );
62 modifier.setOriginateTimestamp( new NtpTimeStamp( request ) );
63
64 byte[] unneededBytes = new byte[8];
65 request.get( unneededBytes );
66
67 modifier.setReceiveTimestamp( new NtpTimeStamp() );
68 modifier.setTransmitTimestamp( new NtpTimeStamp( request ) );
69
70 return modifier.getNtpMessage();
71 }
72
73
74 private LeapIndicatorType parseLeapIndicator( byte header )
75 {
76 return LeapIndicatorType.getTypeByOrdinal( ( header & 0xc0 ) >>> 6 );
77 }
78
79
80 private int parseVersionNumber( byte header )
81 {
82 return ( header & 0x38 ) >>> 3;
83 }
84
85
86 private ModeType parseMode( byte header )
87 {
88 return ModeType.getTypeByOrdinal( header & 0x07 );
89 }
90
91
92 private StratumType parseStratum( ByteBuffer request )
93 {
94 return StratumType.getTypeByOrdinal( request.get() );
95 }
96
97
98 private byte parsePollInterval( ByteBuffer bytes )
99 {
100 return ( byte ) Math.round( Math.pow( 2, bytes.get() ) );
101 }
102
103
104 private byte parsePrecision( ByteBuffer bytes )
105 {
106 return ( byte ) ( 1000 * Math.pow( 2, bytes.get() ) );
107 }
108
109
110 private ReferenceIdentifier parseReferenceIdentifier( ByteBuffer request )
111 {
112 byte[] nextFourBytes = new byte[4];
113 request.get( nextFourBytes );
114 return ReferenceIdentifier.getTypeByName( new String( nextFourBytes ) );
115 }
116
117
118 private int parseRootDelay( ByteBuffer bytes )
119 {
120 int temp = 256 * ( 256 * ( 256 * bytes.get() + bytes.get() ) + bytes.get() ) + bytes.get();
121 return 1000 * ( temp / 0x10000 );
122 }
123
124
125 private int parseRootDispersion( ByteBuffer bytes )
126 {
127 int temp = 256 * ( 256 * ( 256 * bytes.get() + bytes.get() ) + bytes.get() ) + bytes.get();
128 return 1000 * ( temp / 0x10000 );
129 }
130 }