Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/act365/net/icmp/ICMPReader.java


1   /*
2     * JSocket Wrench
3     * 
4     * Copyright (C) act365.com October 2003
5     * 
6     * Web site: http://www.act365.com/wrench
7     * E-mail: developers@act365.com
8     * 
9     * The JSocket Wrench library adds support for low-level Internet protocols
10    * to the Java programming language.
11    * 
12    * This program is free software; you can redistribute it and/or modify it 
13    * under the terms of the GNU General Public License as published by the Free 
14    * Software Foundation; either version 2 of the License, or (at your option) 
15    * any later version.
16    *  
17    * This program is distributed in the hope that it will be useful, 
18    * but WITHOUT ANY WARRANTY; without even the implied warranty of 
19    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 
20    * Public License for more details.
21    * 
22    * You should have received a copy of the GNU General Public License along with 
23    * this program; if not, write to the Free Software Foundation, Inc., 
24    * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25    */
26  
27  package com.act365.net.icmp ;
28  
29  import com.act365.net.*;
30  
31  import java.io.* ;
32  
33  /**
34   ICMPReader reads ICMPMessage objects from a DatagramPacket.
35  */
36  
37  public class ICMPReader {
38  
39    short identifier ;
40  
41    /**
42     Creates a reader to read from DatagramPacket objects.
43     The reader will only accept ICMP packets with the
44     specified identifier.
45    */
46  
47    public ICMPReader( short identifier ){
48      this.identifier = identifier ;
49    }
50  
51    /**
52     read() constructs an ICMP message from a buffer. An exception will
53     be thrown if the message is not in the ICMP format or if there is a
54     checksum error but the message will simply be ignored should the 
55     identifier does not match.
56     @return The ICMPMessage contained in the packet or null if the
57             identifier did not match.
58    */
59  
60    public ICMPMessage read( byte[] buffer, int length, int offset, boolean testchecksum ) throws IOException {
61  
62       if( length - offset < 8 ) {
63         throw new IOException("ICMP messages must be at least eight bytes long");
64       }
65  
66       short checksum ;
67  
68       if( testchecksum && ( checksum = SocketUtils.checksum( buffer , length , offset ) ) != 0 ){
69         throw new IOException("Checksum error: " + checksum );
70       }
71  
72       ICMPMessage message = new ICMPMessage();
73  
74       message.type = buffer[ offset ];
75       message.code = buffer[ offset + 1 ];
76       message.checksum = SocketUtils.shortFromBytes( buffer , offset + 2 );
77  
78       boolean isquery ;
79  
80       int datastart ;
81  
82       switch( message.type ){
83  
84       case ICMP.ICMP_ECHOREPLY:
85       case ICMP.ICMP_ECHO:
86       case ICMP.ICMP_ROUTERADVERT:
87       case ICMP.ICMP_ROUTERSOLICIT:
88       case ICMP.ICMP_TIMESTAMP:
89       case ICMP.ICMP_TIMESTAMPREPLY:
90       case ICMP.ICMP_INFO_REQUEST:
91       case ICMP.ICMP_INFO_REPLY:
92       case ICMP.ICMP_ADDRESS:
93       case ICMP.ICMP_ADDRESSREPLY:
94  
95         isquery = true ;
96         datastart = 8 ;
97         break;
98  
99       case ICMP.ICMP_DEST_UNREACH:
100      case ICMP.ICMP_SOURCE_QUENCH:
101      case ICMP.ICMP_REDIRECT:
102      case ICMP.ICMP_TIME_EXCEEDED:
103      case ICMP.ICMP_PARAMETERPROB:
104 
105        isquery = false ;
106        datastart = 4 ;
107        break;
108 
109      default:
110 
111        return null ;
112      } 
113 
114      if( isquery ){
115 
116        message.identifier = SocketUtils.shortFromBytes( buffer , offset + 4 );
117 
118        if( identifier != message.identifier ){
119          return null ;
120        }
121 
122        message.sequence_number = SocketUtils.shortFromBytes( buffer , offset + 6 );
123      }
124 
125      byte[] data = new byte[ length - offset - datastart ];
126 
127      int i = offset + datastart ;
128 
129      while( i < length ){
130        data[ i - offset - datastart ] = buffer[i];
131        ++ i ;
132      }
133 
134      message.data = data ;
135 
136      return message ;
137   }
138 }