This file is indexed.

/usr/share/gauche-0.9/0.9.5/lib/rfc/icmp.scm is in gauche 0.9.5-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
;;;
;;; rfc.icmp - Internet Control Message Protocol
;;;
;;;   Copyright (c) 2007-2016  Shiro Kawai  <shiro@acm.org>
;;;
;;;   Redistribution and use in source and binary forms, with or without
;;;   modification, are permitted provided that the following conditions
;;;   are met:
;;;
;;;   1. Redistributions of source code must retain the above copyright
;;;      notice, this list of conditions and the following disclaimer.
;;;
;;;   2. Redistributions in binary form must reproduce the above copyright
;;;      notice, this list of conditions and the following disclaimer in the
;;;      documentation and/or other materials provided with the distribution.
;;;
;;;   3. Neither the name of the authors nor the names of its contributors
;;;      may be used to endorse or promote products derived from this
;;;      software without specific prior written permission.
;;;
;;;   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
;;;   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
;;;   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
;;;   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
;;;   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
;;;   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
;;;   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
;;;   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
;;;   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
;;;   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;;;   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;;


;; EXPERIMENTAL

;; RFC 792  Internet Control Message Protocol
;; RFC 1256 ICMP Router Discovery Messages
;; RFC 1393 Traceroute Using an IP Option
;; RFC 1788 ICMP Domain Name Messages
;; RFC 1812 Requirements for IP Version 4 Routers
;; RFC 2002 IP Mobility Supprot
;; RFC 2463 ICMPv6
;; RFC 2521 ICMP Security Failures Messages
;; Also useful:
;;  http://www.iana.org/assignments/icmp-parameters

(define-module rfc.icmp
  (use gauche.uvector)
  (use gauche.net)
  (use binary.io)
  (export icmp4-message-type->string
          ICMP4_ECHOREPLY ICMP4_DEST_UNREACH ICMP4_SOURCE_QUENCH
          ICMP4_REDIRECT ICMP4_ECHO ICMP4_ROUTER_ADVERT ICMP4_ROUTER_SOLICIT
          ICMP4_TIME_EXCEEDED ICMP4_PARAMETERPROB ICMP4_TIMESTAMP
          ICMP4_TIMESTAMPREPLY ICMP4_INFO_REQUEST ICMP4_INFO_REPLY
          ICMP4_ADDRESS ICMP4_ADDRESSREPLY ICMP4_TRACEROUTE
          ICMP4_DGRAMCONVERROR ICMP4_DOMAIN_REQUEST ICMP4_DOMAIN_REPLY
          ICMP4_SECURITYFAILURE

          icmp4-unreach-code->string
          ICMP4_NET_UNREACH ICMP4_HOST_UNREACH ICMP4_PROT_UNREACH
          ICMP4_PORT_UNREACH ICMP4_FRAG_NEEDED ICMP4_SR_FAILED
          ICMP4_NET_UNKNOWN ICMP4_HOST_UNKNOWN ICMP4_HOST_ISOLATED
          ICMP4_NET_ANO ICMP4_HOST_ANO ICMP4_NET_UNR_TOS ICMP4_HOST_UNR_TOS
          ICMP4_PKT_FILTERED ICMP4_PREC_VIOLATION ICMP4_PREC_CUTOFF

          icmp4-redirect-code->string
          ICMP4_REDIR_NET ICMP4_REDIR_HOST ICMP4_REDIR_NETTOS
          ICMP4_REDIR_HOSTTOS

          icmp4-router-code->string
          ICMP4_ROUTER_NORMAL ICMP4_ROUTER_NOCOMMON

          icmp4-exceeded-code->string
          ICMP4_EXC_TTL ICMP4_EXC_FRAGTIME

          icmp4-parameter-code->string
          ICMP4_PARAM_PTR ICMP4_PARAM_MISSING ICMP4_PARAM_BADLENGTH

          icmp4-security-code->string
          ICMP4_SEC_BADSPI ICMP4_SEC_AUTHFAILED ICMP4_SEC_DECOMPFAILED
          ICMP4_SEC_DECRYPTFAILED ICMP4_SEC_NEEDAUTHENTICATION
          ICMP4_SEC_NEEDAUTHORIZATION

          icmp6-message-type->string
          ICMP6_DEST_UNREACH ICMP6_PACKET_TOO_BIG ICMP6_TIME_EXCEEDED
          ICMP6_PARAMETERPROB ICMP6_ECHO ICMP6_ECHOREPLY

          icmp6-unreach-code->string
          ICMP6_UNREACH_NOROUTE ICMP6_UNREACH_ADMIN ICMP6_UNREACH_BEYONDSCOPE
          ICMP6_UNREACH_ADDR ICMP6_UNREACH_NOPORT

          icmp6-exceeded-code->string
          ICMP6_EXC_TRANSIT ICMP6_EXC_REASSEMBLY

          icmp6-parameter-code->string
          ICMP6_PARAM_HEADER ICMP6_PARAM_NEXTHEADER ICMP6_PARAM_OPTION

          icmp-fill-header!
          icmp4-fill-checksum! icmp4-fill-echo!
          icmp6-fill-echo!

          icmp-packet-type icmp-packet-code
          icmp-echo-ident icmp-echo-sequence
          icmp4-describe-packet icmp6-describe-packet
          ))
(select-module rfc.icmp)

;;============================================================
;; Constants
;;
;;  NB: it seems that these symbols in C slightly differ among the
;;  underlying ICMP library, e.g. between GNU/Linux and BSD.
;;  I follow the GNU convention, for it is a bit more descriptive.

(define-syntax define-named-code
  (syntax-rules ()
    ((_ name ->string (sym val expl) ...)
     (begin
       (define-constant sym val) ...
       (define (->string c)
         (case c
           ((val) expl) ...
           (else (format "Unknown code ~s for ~a" c name))))))))

;;-------------------------------------------------------------
;; ICMPv4
;;

;; ICMP message types.
(define-named-code "ICMP message types"
  icmp4-message-type->string
  (ICMP4_ECHOREPLY          0   "Echo Reply")
  (ICMP4_DEST_UNREACH       3   "Destination Unreachable")
  (ICMP4_SOURCE_QUENCH      4   "Source Quench      ")
  (ICMP4_REDIRECT           5   "Redirect (change route)")
  (ICMP4_ECHO               8   "Echo Request")
  (ICMP4_ROUTER_ADVERT      9   "Router Advertisement")
  (ICMP4_ROUTER_SOLICIT     10  "Router solicitation")
  (ICMP4_TIME_EXCEEDED      11  "Time Exceeded")
  (ICMP4_PARAMETERPROB      12  "Parameter Problem")
  (ICMP4_TIMESTAMP          13  "Timestamp Request")
  (ICMP4_TIMESTAMPREPLY     14  "Timestamp Reply")
  (ICMP4_INFO_REQUEST       15  "Information Request")
  (ICMP4_INFO_REPLY         16  "Information Reply")
  (ICMP4_ADDRESS            17  "Address Mask Request")
  (ICMP4_ADDRESSREPLY       18  "Address Mask Reply")
  (ICMP4_TRACEROUTE         30  "Traceroute")
  (ICMP4_DGRAMCONVERROR     31  "Datagram Conversion Error")
  (ICMP4_DOMAIN_REQUEST     37  "Domain Name Request")
  (ICMP4_DOMAIN_REPLY       38  "Domain Name Reply")
  (ICMP4_SECURITYFAILURE    40  "Security Failures")
  )

;; Codes
(define-named-code "ICMP UNREACH codes"
  icmp4-unreach-code->string
  (ICMP4_NET_UNREACH        0   "Network Unreachable")
  (ICMP4_HOST_UNREACH       1   "Host Unreachable")
  (ICMP4_PROT_UNREACH       2   "Protocol Unreachable")
  (ICMP4_PORT_UNREACH       3   "Port Unreachable")
  (ICMP4_FRAG_NEEDED        4   "Fragmentation Needed/DF set")
  (ICMP4_SR_FAILED          5   "Source Route failed")
  (ICMP4_NET_UNKNOWN        6   "Unknown Net")
  (ICMP4_HOST_UNKNOWN       7   "Unknown Host")
  (ICMP4_HOST_ISOLATED      8   "Source Host Isolated")
  (ICMP4_NET_ANO            9   "Dest Network Prohibited")
  (ICMP4_HOST_ANO           10  "Dest Host Prohibited")
  (ICMP4_NET_UNR_TOS        11  "Dest Netowork Unreachable for TOS")
  (ICMP4_HOST_UNR_TOS       12  "Dest Host Unreachable for TOS")
  (ICMP4_PKT_FILTERED       13  "Packet Filtered")
  (ICMP4_PREC_VIOLATION     14  "Precedence Violation")
  (ICMP4_PREC_CUTOFF        15  "Precedence Cut Off")
  )

(define-named-code "ICMP REDIRECT codes"
  icmp4-redirect-code->string
  (ICMP4_REDIR_NET          0   "Redirect Net")
  (ICMP4_REDIR_HOST         1   "Redirect Host")
  (ICMP4_REDIR_NETTOS       2   "Redirect Net for TOS")
  (ICMP4_REDIR_HOSTTOS      3   "Redirect Host for TOS")
  )

(define-named-code "ICMP ROUTER ADVERTISE codes"
  icmp4-router-code->string
  (ICMP4_ROUTER_NORMAL      0   "Normal Router Advertisement")
  (ICMP4_ROUTER_NOCOMMON    16  "Does not route common traffic")
  )

(define-named-code "ICMP TIME EXCEEDED codes"
  icmp4-exceeded-code->string
  (ICMP4_EXC_TTL            0   "TTL count exceeded")
  (ICMP4_EXC_FRAGTIME       1   "Fragment Reass time exceeded")
  )

(define-named-code "ICMP PARAMETER PROBLEM codes"
  icmp4-parameter-code->string
  (ICMP4_PARAM_PTR          0   "Pointer indicates the error")
  (ICMP4_PARAM_MISSING      1   "Missing Required Option")
  (ICMP4_PARAM_BADLENGTH    2   "Bad Length")
  )

(define-named-code "ICMP SECURITY FAILURE codes"
  icmp4-security-code->string
  (ICMP4_SEC_BADSPI         0   "Bad SPI")
  (ICMP4_SEC_AUTHFAILED     1   "Authentication Failed")
  (ICMP4_SEC_DECOMPFAILED   2   "Decompression Failed")
  (ICMP4_SEC_DECRYPTFAILED  3   "Decryption Failed")
  (ICMP4_SEC_NEEDAUTHENTICATION 4 "Need Authentication")
  (ICMP4_SEC_NEEDAUTHORIZATION  5 "Need Authorization")
  )

;;-------------------------------------------------------------
;; ICMPv6
;;
(define-named-code "ICMP6 message types"
  icmp6-message-type->string
  (ICMP6_DEST_UNREACH      1   "Destination unreachable")
  (ICMP6_PACKET_TOO_BIG    2   "Packet Too Big")
  (ICMP6_TIME_EXCEEDED     3   "Time Exceeded")
  (ICMP6_PARAMETERPROB     4   "Parameter problem")

  (ICMP6_ECHO            128   "Echo request")
  (ICMP6_ECHOREPLY       129   "Echo reply")
  )

(define-named-code "ICMP6 UNREACH codes"
  icmp6-unreach-code->string
  (ICMP6_UNREACH_NOROUTE      0 "No route to destination")
  (ICMP6_UNREACH_ADMIN        1 "Communication administratively prohibited")
  (ICMP6_UNREACH_BEYONDSCOPE  2 "Beyond scope of source address")
  (ICMP6_UNREACH_ADDR         3 "Address unreachable")
  (ICMP6_UNREACH_NOPORT       4 "Bad port")
  )

(define-named-code "ICMP6 TIME EXCEEDED codes"
  icmp6-exceeded-code->string
  (ICMP6_EXC_TRANSIT          0 "Hop limit == 0 in transit")
  (ICMP6_EXC_REASSEMBLY       1 "Reassembly time out")
  )

(define-named-code "ICMP6 PARAMETER PROBLEM codes"
  icmp6-parameter-code->string
  (ICMP6_PARAM_HEADER         0 "Erroneous header field")
  (ICMP6_PARAM_NEXTHEADER     1 "Unrecognized next header")
  (ICMP6_PARAM_OPTION         2 "Unrecognized IPv6 option")
  )

;;============================================================
;; Packet construction
;;

;; The low-level 'fill' routines operates on pre-allocated u8vector
;; as buffer.  They don't allocate, so that they can be used
;; in inner loops.

;; Fill ICMP/ICMP6 packet header (except checksum)
(define-inline (icmp-fill-header! buf type code)
  (put-u8! buf 0 type)
  (put-u8! buf 1 code)
  (put-u16be! buf 2 0))

(define (icmp4-fill-checksum! buf size)
  (put-u16be! buf 2 (inet-checksum buf size)))

(define (icmp4-fill-echo! buf ident seq data)
  (icmp-fill-header! buf ICMP4_ECHO 0)
  (put-u16be! buf 4 ident)
  (put-u16be! buf 6 seq)
  (u8vector-copy! buf 8 data)
  (icmp4-fill-checksum! buf (+ (u8vector-length data) 8)))

;; We don't need to fill out checksum fields, for the kernel calculates it.
(define (icmp6-fill-echo! buf ident seq data)
  (icmp-fill-header! buf ICMP6_ECHO 0)
  (put-u16be! buf 4 ident)
  (put-u16be! buf 6 seq)
  (u8vector-copy! buf 8 data))

;;============================================================
;; Packet decomposition
;;

;; common to v4/v6
(define (icmp-packet-type buf offset)
  (get-u8 buf (+ 0 offset)))

;; common to v4/v6
(define (icmp-packet-code buf offset)
  (get-u8 buf (+ 1 offset)))

;; common to v4/v6
(define (icmp-echo-ident buf offset)
  (get-u16be buf (+ 4 offset)))

;; common to v4/v6
(define (icmp-echo-sequence buf offset)
  (get-u16be buf (+ 6 offset)))

(define (icmp4-describe-packet buf offset)
  (let ((type (icmp-packet-type buf offset))
        (code (icmp-packet-code buf offset)))
    (format #t "ICMP packet type=~a(~a)\n"
            type (icmp4-message-type->string type))
    (cond
     ((memv type `(,ICMP4_ECHOREPLY ,ICMP4_ECHO))
      (format #t "  ident=~2,'0x seq=~2,'0x\n"
              (icmp-echo-ident buf offset) (icmp-echo-sequence buf offset)))
     ((assv type `((,ICMP4_DEST_UNREACH . ,icmp4-unreach-code->string)
                   (,ICMP4_REDIRECT     . ,icmp4-redirect-code->string)
                   (,ICMP4_ROUTER_ADVERT . ,icmp4-router-code->string)
                   (,ICMP4_TIME_EXCEEDED . ,icmp4-exceeded-code->string)
                   (,ICMP4_PARAMETERPROB . ,icmp4-parameter-code->string)
                   (,ICMP4_SECURITYFAILURE . ,icmp4-security-code->string)))
      => (lambda (p)
           (format #t "  code=~a(~a)\n" code ((cdr p) code))))
     )))

(define (icmp6-describe-packet buf offset)
  (let ((type (icmp-packet-type buf offset))
        (code (icmp-packet-code buf offset)))
    (format #t "ICMPv6 packet type=~a(~a)\n"
            type (icmp6-message-type->string type))
    (cond
     ((= type ICMP6_ECHOREPLY)
      (format #t "  ident=~2,'0x seq=~2,'0x\n"
              (icmp-echo-ident buf offset) (icmp-echo-sequence buf offset)))
     ((assv type `((,ICMP6_DEST_UNREACH . ,icmp6-unreach-code->string)
                   (,ICMP6_TIME_EXCEEDED . ,icmp6-exceeded-code->string)
                   (,ICMP6_PARAMETERPROB . ,icmp6-parameter-code->string)))
      => (lambda (p)
           (format #t "  code=~a(~a)\n" code ((cdr p) code))))
     )))