mt_racket 1.0.12a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/README +76 -0
  3. data/examples/arp-send +24 -0
  4. data/examples/arp-send2 +30 -0
  5. data/examples/cdp +39 -0
  6. data/examples/cdp-spew +52 -0
  7. data/examples/dhcp +42 -0
  8. data/examples/dhcp-spew +48 -0
  9. data/examples/dns +38 -0
  10. data/examples/egp +30 -0
  11. data/examples/hsrp +43 -0
  12. data/examples/hsrp_takeover +69 -0
  13. data/examples/icmp-recv +34 -0
  14. data/examples/icmp-spew +50 -0
  15. data/examples/icmpv6 +84 -0
  16. data/examples/icmpv6-spew +50 -0
  17. data/examples/igmpv1 +27 -0
  18. data/examples/igmpv2 +27 -0
  19. data/examples/igrp-send +25 -0
  20. data/examples/ipv6 +35 -0
  21. data/examples/nat-pimp +32 -0
  22. data/examples/ntp +38 -0
  23. data/examples/ntp2 +42 -0
  24. data/examples/sctp +32 -0
  25. data/examples/stp-send +21 -0
  26. data/examples/synflood +147 -0
  27. data/examples/tcp +43 -0
  28. data/examples/tcp2udp +65 -0
  29. data/examples/udp +46 -0
  30. data/examples/vrrp +34 -0
  31. data/examples/vtp +28 -0
  32. data/lib/racket/l2/eightotwodotthree.rb +48 -0
  33. data/lib/racket/l2/ethernet.rb +62 -0
  34. data/lib/racket/l2/llc.rb +50 -0
  35. data/lib/racket/l2/misc.rb +67 -0
  36. data/lib/racket/l2/snap.rb +40 -0
  37. data/lib/racket/l2/vlan.rb +61 -0
  38. data/lib/racket/l2/vtp.rb +124 -0
  39. data/lib/racket/l2.rb +30 -0
  40. data/lib/racket/l3/arp.rb +63 -0
  41. data/lib/racket/l3/cdp.rb +85 -0
  42. data/lib/racket/l3/egp.rb +53 -0
  43. data/lib/racket/l3/ipv4.rb +132 -0
  44. data/lib/racket/l3/ipv6.rb +66 -0
  45. data/lib/racket/l3/misc.rb +159 -0
  46. data/lib/racket/l3/stp.rb +81 -0
  47. data/lib/racket/l3.rb +30 -0
  48. data/lib/racket/l4/gre.rb +65 -0
  49. data/lib/racket/l4/icmp.rb +295 -0
  50. data/lib/racket/l4/icmpv6.rb +446 -0
  51. data/lib/racket/l4/igmpv1.rb +79 -0
  52. data/lib/racket/l4/igmpv2.rb +76 -0
  53. data/lib/racket/l4/igrp.rb +138 -0
  54. data/lib/racket/l4/misc.rb +35 -0
  55. data/lib/racket/l4/sctp.rb +163 -0
  56. data/lib/racket/l4/tcp.rb +152 -0
  57. data/lib/racket/l4/udp.rb +81 -0
  58. data/lib/racket/l4/vrrp.rb +95 -0
  59. data/lib/racket/l4.rb +30 -0
  60. data/lib/racket/l5/bootp.rb +106 -0
  61. data/lib/racket/l5/dns.rb +110 -0
  62. data/lib/racket/l5/hsrp.rb +73 -0
  63. data/lib/racket/l5/misc.rb +35 -0
  64. data/lib/racket/l5/nat-pmp.rb +41 -0
  65. data/lib/racket/l5/ntp.rb +59 -0
  66. data/lib/racket/l5.rb +30 -0
  67. data/lib/racket/misc/lv.rb +108 -0
  68. data/lib/racket/misc/misc.rb +62 -0
  69. data/lib/racket/misc/orderedhash.rb +63 -0
  70. data/lib/racket/misc/raw.rb +35 -0
  71. data/lib/racket/misc/tlv.rb +103 -0
  72. data/lib/racket/misc/vt.rb +114 -0
  73. data/lib/racket/misc.rb +30 -0
  74. data/lib/racket/racket.rb +166 -0
  75. data/lib/racket/racketpart.rb +66 -0
  76. data/lib/racket.rb +4 -0
  77. data/test/l2/ts_ethernet.rb +22 -0
  78. data/test/l2/ts_misc.rb +23 -0
  79. data/test/l2/ts_vlan.rb +15 -0
  80. data/test/l3/ts_ipv4.rb +44 -0
  81. data/test/l3/ts_ipv6.rb +26 -0
  82. data/test/l3/ts_misc.rb +31 -0
  83. data/test/l4/ts_icmp.rb +38 -0
  84. data/test/l4/ts_tcp.rb +55 -0
  85. data/test/l4/ts_udp.rb +40 -0
  86. data/test/misc/ts_lv.rb +59 -0
  87. data/test/misc/ts_orderedhash.rb +33 -0
  88. data/test/misc/ts_tlv.rb +47 -0
  89. data/test/misc/ts_vt.rb +56 -0
  90. data/test/ts_all.rb +14 -0
  91. metadata +153 -0
@@ -0,0 +1,446 @@
1
+ # $Id$
2
+ #
3
+ # Copyright (c) 2008, Jon Hart
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright
11
+ # notice, this list of conditions and the following disclaimer in the
12
+ # documentation and/or other materials provided with the distribution.
13
+ # * Neither the name of the <organization> nor the
14
+ # names of its contributors may be used to endorse or promote products
15
+ # derived from this software without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
18
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
21
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #
28
+ module Racket
29
+ module L4
30
+ # Internet Control Message Protcol, v6
31
+ #
32
+ # http://en.wikipedia.org/wiki/ICMPv6
33
+ #
34
+ # Generic ICMP class from which all ICMP variants spawn. This should never be used directly.
35
+ class ICMPv6Generic < RacketPart
36
+ ICMPv6_TYPE_ECHO_REPLY = 129
37
+ ICMPv6_TYPE_DESTINATION_UNREACHABLE = 1
38
+ ICMPv6_TYPE_PACKET_TOO_BIG = 2
39
+ ICMPv6_TYPE_ECHO_REQUEST = 128
40
+ ICMPv6_TYPE_TIME_EXCEEDED = 3
41
+ ICMPv6_TYPE_PARAMETER_PROBLEM = 4
42
+ ICMPv6_TYPE_MLD_QUERY = 130
43
+ ICMPv6_TYPE_MLD_REPORT = 131
44
+ ICMPv6_TYPE_MLD_DONE = 132
45
+ ICMPv6_TYPE_ROUTER_SOLICITATION = 133
46
+ ICMPv6_TYPE_ROUTER_ADVERTISEMENT = 134
47
+ ICMPv6_TYPE_NEIGHBOR_SOLICITATION = 135
48
+ ICMPv6_TYPE_NEIGHBOR_ADVERTISEMENT = 136
49
+ ICMPv6_TYPE_REDIRECT = 137
50
+ ICMPv6_TYPE_INFORMATION_REQUEST = 139
51
+ ICMPv6_TYPE_INFORMATION_REPLY = 140
52
+
53
+ # Type
54
+ unsigned :type, 8
55
+ # Code
56
+ unsigned :code, 8
57
+ # Checksum
58
+ unsigned :checksum, 16
59
+ rest :message
60
+
61
+ # check the checksum for this ICMP packet
62
+ def checksum?
63
+ self.checksum == compute_checksum
64
+ end
65
+
66
+ def initialize(*args)
67
+ super(*args)
68
+ @autofix = false
69
+ end
70
+
71
+ # Add an ICMPv6 option. RFC claims that the value should be padded (with what?)
72
+ # to land on a 64-bit boundary, however that doesn't always appear to be the case. so, yeah,
73
+ # try to pad on your own or pick strings that are multiples of 8 characters
74
+ def add_option(type, value)
75
+ t = Racket::Misc::TLV.new(1,1)
76
+ t.type = type
77
+ t.length = (value.length + 2) / 8
78
+ just = value.length + 2 + (8 - ((value.length + 2) % 8))
79
+ t.value = (value.length + 2) % 8 == 0 ? value : value.ljust(just, "\x00")
80
+ self.payload = t.encode + self.payload
81
+ end
82
+
83
+ # ignorantly assume the first parts of the payload contain ICMPv6 options
84
+ # and find a return an array of Racket::Misc::TLV representing the options
85
+ def get_options
86
+ p = self.payload
87
+ options = []
88
+ until ((o = Racket::Misc::TLV.new(1,1,8,true).decode(p)).nil?)
89
+ options << o[0..2]
90
+ p = o[3]
91
+ end
92
+ options
93
+ end
94
+
95
+ # compute and set the checksum for this ICMP packet
96
+ def checksum!(src_ip, dst_ip)
97
+ self.checksum = compute_checksum(src_ip, dst_ip)
98
+ end
99
+
100
+ # 'fix' this ICMP packet up for sending.
101
+ # (really, just set the checksum)
102
+ def fix!(src_ip, dst_ip)
103
+ self.checksum!(src_ip, dst_ip)
104
+ end
105
+
106
+ # get the source link layer address of this message, if found
107
+ def slla
108
+ addr = nil
109
+ self.get_options.each do |o|
110
+ type, length, value, rest = o.flatten
111
+ if (type == 1)
112
+ addr = L2::Misc.string2mac(value)
113
+ end
114
+ end
115
+ addr
116
+ end
117
+
118
+ # set the source link layer address of this message.
119
+ # expects +addr+ in de:ad:ba:dc:af:e0 form
120
+ def slla=(addr)
121
+ self.add_option(1, L2::Misc.mac2string(addr))
122
+ end
123
+
124
+ # get the target link layer address of this message, if found
125
+ def tlla
126
+ addr = nil
127
+ self.get_options.each do |o|
128
+ type, length, value, rest = o.flatten
129
+ if (type == 2)
130
+ addr = L2::Misc.string2mac(value)
131
+ end
132
+ end
133
+ addr
134
+ end
135
+
136
+ # set the target link layer address of this message
137
+ # expects +addr+ in de:ad:ba:dc:af:e0 form
138
+ def tlla=(addr)
139
+ self.add_option(2, L2::Misc.mac2string(addr))
140
+ end
141
+
142
+ private
143
+ def compute_checksum(src_ip, dst_ip)
144
+ s1 = src_ip >> 96
145
+ s2 = (src_ip >> 64) & 0xFFFFFFFF
146
+ s3 = (src_ip >> 32) & 0xFFFFFFFF
147
+ s4 = src_ip & 0xFFFFFFFF
148
+
149
+ d1 = dst_ip >> 96
150
+ d2 = (dst_ip >> 64) & 0xFFFFFFFF
151
+ d3 = (dst_ip >> 32) & 0xFFFFFFFF
152
+ d4 = dst_ip & 0xFFFFFFFF
153
+
154
+ # pseudo header used for checksum calculation as per RFC 768
155
+ pseudo = [ s1, s2, s3, s4, d1, d2, d3, d4, self.length, 58, self.type, self.code, 0, self.message ]
156
+ L3::Misc.checksum(pseudo.pack("NNNNNNNNNNCCna*"))
157
+ end
158
+ end
159
+ # Send raw ICMP packets of your own design
160
+ class ICMPv6 < ICMPv6Generic
161
+ rest :payload
162
+ end
163
+
164
+ # Generic ICMPv6 echo, used by ICMPv6EchoRequest and ICMPv6EchoReply
165
+ class ICMPv6Echo < ICMPv6Generic
166
+ # identifier to aid in matching echo requests/replies
167
+ unsigned :id, 16
168
+ # sequence number to aid in matching requests/replies
169
+ unsigned :sequence, 16
170
+ rest :payload
171
+
172
+ def initialize(*args)
173
+ super(*args)
174
+ end
175
+
176
+ end
177
+
178
+ # ICMPv6Echo Request
179
+ class ICMPv6EchoRequest < ICMPv6Echo
180
+ rest :payload
181
+
182
+ def initialize(*args)
183
+ super(*args)
184
+ self.type = ICMPv6_TYPE_ECHO_REQUEST
185
+ self.code = 0
186
+ end
187
+
188
+ end
189
+
190
+ # ICMPv6Echo Reply
191
+ class ICMPv6EchoReply < ICMPv6Echo
192
+ rest :payload
193
+
194
+ def initialize(*args)
195
+ super(*args)
196
+ self.type = ICMPv6_TYPE_ECHO_REPLY
197
+ self.code = 0
198
+ end
199
+ end
200
+
201
+ # ICMP Destination Unreachable Message
202
+ class ICMPv6DestinationUnreachable < ICMPv6Generic
203
+ ICMPv6_CODE_NO_ROUTE = 0
204
+ ICMPv6_CODE_ADMIN_PROHIBITED = 1
205
+ ICMPv6_CODE_BEYOND_SCOPE = 2
206
+ ICMPv6_CODE_ADDRESS_UNREACHABLE = 3
207
+ ICMPv6_CODE_PORT_UNREACHABLE = 4
208
+ ICMPv6_CODE_FAILED_POLICY = 4
209
+ ICMPv6_CODE_REJECT_ROUTE = 5
210
+ # This is never used according to the RFC
211
+ unsigned :unused, 32
212
+ # Internet header + 64 bits of original datagram
213
+ rest :payload
214
+
215
+ def initialize(*args)
216
+ super(*args)
217
+ self.type = ICMPv6_TYPE_DESTINATION_UNREACHABLE
218
+ end
219
+ end
220
+
221
+ class ICMPv6PacketTooBig < ICMPv6Generic
222
+ # The Maximum Transmission Unit of the next-hop link
223
+ unsigned :mtu, 32
224
+ rest :payload
225
+
226
+ def initialize(*args)
227
+ super(*args)
228
+ self.type = ICMPv6_TYPE_PACKET_TOO_BIG
229
+ end
230
+
231
+ end
232
+
233
+ # ICMP Time Exceeded Message
234
+ class ICMPv6TimeExceeded < ICMPv6Generic
235
+ ICMPv6_CODE_TTL_EXCEEDED_IN_TRANSIT = 0
236
+ ICMPv6_CODE_FRAG_REASSEMBLY_TIME_EXCEEDED = 1
237
+ # This is never used according to the RFC
238
+ unsigned :unused, 32
239
+ # As much of the original ICMPv6 packet without busting MTU
240
+ rest :payload
241
+
242
+ def initialize(*args)
243
+ super(*args)
244
+ self.type = ICMPv6_TYPE_TIME_EXCEEDED
245
+ end
246
+ end
247
+
248
+ # ICMPv6 Parameter Problem Message
249
+ class ICMPv6ParameterProblem < ICMPv6Generic
250
+ ICMPv6_CODE_ERRONEOUS_HEADER = 0
251
+ ICMPv6_CODE_UNRECOGNIZED_NEXT_HEADER = 1
252
+ ICMPv6_CODE_UNRECOGNIZED_OPTION = 2
253
+ # pointer to the octet where the error was detected
254
+ unsigned :pointer, 32
255
+ # As much of the original ICMPv6 packet without busting MTU
256
+ rest :payload
257
+
258
+ def initialize(*args)
259
+ super(*args)
260
+ self.type = ICMPv6_TYPE_PARAMETER_PROBLEM
261
+ end
262
+ end
263
+
264
+ # ICMPv6 Multicast Listener Discovery (MLD)
265
+ # http://www.faqs.org/rfcs/rfc2710.html
266
+ class ICMPv6MulticastListener < ICMPv6Generic
267
+ # maximum response delay
268
+ unsigned :delay, 16
269
+ # should be zero. never used.
270
+ unsigned :reserved, 16
271
+ # multicast address
272
+ unsigned :address, 128
273
+ rest :payload
274
+
275
+ def initialize(*args)
276
+ super(*args)
277
+ end
278
+ end
279
+
280
+ class ICMPv6MulticastListenerQuery < ICMPv6MulticastListener
281
+ rest :payload
282
+
283
+ def initialize(*args)
284
+ super(*args)
285
+ self.type = ICMPv6_TYPE_MLD_QUERY
286
+ end
287
+ end
288
+
289
+ class ICMPv6MulticastListenerReport < ICMPv6MulticastListener
290
+ rest :payload
291
+
292
+ def initialize(*args)
293
+ super(*args)
294
+ self.type = ICMPv6_TYPE_MLD_REPORT
295
+ end
296
+ end
297
+
298
+ class ICMPv6MulticastListenerDone < ICMPv6MulticastListener
299
+ rest :payload
300
+
301
+ def initialize(*args)
302
+ super(*args)
303
+ self.type = ICMPv6_TYPE_MLD_DONE
304
+ end
305
+ end
306
+
307
+ # http://tools.ietf.org/html/rfc4861
308
+ class ICMPv6RouterSolicitation < ICMPv6Generic
309
+ # should be 0, never used.
310
+ unsigned :reserved, 32
311
+ rest :payload
312
+
313
+ def initialize(*args)
314
+ super(*args)
315
+ self.type = ICMPv6_TYPE_ROUTER_SOLICITATION
316
+ end
317
+ end
318
+
319
+ # http://tools.ietf.org/html/rfc4861
320
+ class ICMPv6RouterAdvertisement < ICMPv6Generic
321
+ # default value that should be placed in the hop count field of the IP header
322
+ # for outgoing IP packets
323
+ unsigned :hop_limit, 8
324
+ # boolean, managed address configuration?
325
+ unsigned :managed_config, 1
326
+ # boolean, other configuration?
327
+ unsigned :other_config, 1
328
+ # set to 0, never used.
329
+ unsigned :reserved, 6
330
+ # lifetime associated with the default router in seconds
331
+ unsigned :lifetime, 16
332
+ # time in milliseconds that a node assumes a neighbor is reachable after having received a reachability confirmation
333
+ unsigned :reachable_time, 32
334
+ # time in milliseconds between retransmitted neighbor solicitation messages
335
+ unsigned :retrans_time, 32
336
+ rest :payload
337
+
338
+ def initialize(*args)
339
+ super(*args)
340
+ self.type = ICMPv6_TYPE_ROUTER_ADVERTISEMENT
341
+ end
342
+ end
343
+
344
+ # http://tools.ietf.org/html/rfc4861
345
+ class ICMPv6NeighborSolicitation < ICMPv6Generic
346
+ # set to 0, never used.
347
+ unsigned :reserved, 32
348
+ # target address of the solicitation
349
+ unsigned :address, 128
350
+ rest :payload
351
+
352
+ def initialize(*args)
353
+ super(*args)
354
+ self.type = ICMPv6_TYPE_NEIGHBOR_SOLICITATION
355
+ end
356
+ end
357
+
358
+ # http://tools.ietf.org/html/rfc4861
359
+ class ICMPv6NeighborAdvertisement < ICMPv6Generic
360
+ # normally this would be router (1), solicited (1), override(1) and reserved (2), however
361
+ # a bit-struct byte boundary bug bites us here
362
+ unsigned :bigbustedfield, 32
363
+ # for solicited adverts, the target address field in the solicitation that prompted this.
364
+ # for unsolicited adverts, the address whose link-layer address has changed
365
+ unsigned :address, 128
366
+ rest :payload
367
+
368
+ # set solicited flag
369
+ def solicited=(f)
370
+ self.bigbustedfield = (f << 30) ^ self.bigbustedfield
371
+ end
372
+
373
+ # set router flag
374
+ def router=(f)
375
+ self.bigbustedfield = (f << 31) ^ self.bigbustedfield
376
+ end
377
+
378
+ # set override flag
379
+ def override=(f)
380
+ self.bigbustedfield = (f << 29) ^ self.bigbustedfield
381
+ end
382
+
383
+ def initialize(*args)
384
+ super(*args)
385
+ self.type = ICMPv6_TYPE_NEIGHBOR_ADVERTISEMENT
386
+ end
387
+ end
388
+
389
+ # http://tools.ietf.org/html/rfc4861
390
+ class ICMPv6Redirect < ICMPv6Generic
391
+ # unused, should be 0
392
+ unsigned :reserved, 32
393
+ # the IP address that is a better first hop to use for the ICMP destination address
394
+ unsigned :src_ip, 128
395
+ # the IP address of the destination that is redirected to the target
396
+ unsigned :dst_ip, 128
397
+ rest :payload
398
+
399
+ def initialize(*args)
400
+ super(*args)
401
+ self.type = ICMPv6_TYPE_REDIRECT
402
+ end
403
+ end
404
+
405
+ # Generic class that IPv6NodeInformationRequest and Reply inherit from
406
+ # http://tools.ietf.org/html/rfc4620
407
+ class ICMPv6NodeInformation < ICMPv6Generic
408
+ # type of information requested in a query or supplied in a reply
409
+ unsigned :qtype, 16
410
+ # qtype-specific flags that may be defined for certain qtypes and their replies
411
+ unsigned :flags, 16
412
+ # opaque field to help avoid spoofing and/or to aid in matching replies with queries
413
+ text :nonce, 64
414
+ rest :payload
415
+
416
+ def initialize(*args)
417
+ super(*args)
418
+ end
419
+ end
420
+
421
+ # http://tools.ietf.org/html/rfc4620
422
+ class ICMPv6NodeInformationRequest < ICMPv6NodeInformation
423
+ ICMPv6_CODE_INFORMATION_REQUEST_IPv6 = 0
424
+ ICMPv6_CODE_INFORMATION_REQUEST_NAME = 1
425
+ ICMPv6_CODE_INFORMATION_REQUEST_IPv4 = 2
426
+
427
+ def initialize(*args)
428
+ super(*args)
429
+ self.type = ICMPv6_TYPE_INFORMATION_REQUEST
430
+ end
431
+ end
432
+
433
+ # http://tools.ietf.org/html/rfc4620
434
+ class ICMPv6NodeInformationReply < ICMPv6NodeInformation
435
+ ICMPv6_CODE_INFORMATION_REPLY_SUCCESS = 0
436
+ ICMPv6_CODE_INFORMATION_REPLY_REFUSE = 1
437
+ ICMPv6_CODE_INFORMATION_REPLY_UNKNOWN = 2
438
+
439
+ def initialize(*args)
440
+ super(*args)
441
+ self.type = ICMPv6_TYPE_INFORMATION_REPLY
442
+ end
443
+ end
444
+ end
445
+ end
446
+ # vim: set ts=2 et sw=2:
@@ -0,0 +1,79 @@
1
+ # $Id: igmpv1.rb 14 2008-03-02 05:42:30Z warchild $
2
+ #
3
+ # Copyright (c) 2008, Jon Hart
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright
11
+ # notice, this list of conditions and the following disclaimer in the
12
+ # documentation and/or other materials provided with the distribution.
13
+ # * Neither the name of the <organization> nor the
14
+ # names of its contributors may be used to endorse or promote products
15
+ # derived from this software without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
18
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
21
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #
28
+ module Racket
29
+ module L4
30
+ # Internet Group Management Protocol, Version 1
31
+ #
32
+ # RFC1112 (http://www.faqs.org/rfcs/rfc1112.html)
33
+ #
34
+ class IGMPv1 < RacketPart
35
+ # Version (defaults to 1)
36
+ unsigned :version, 4, { :default => 1 }
37
+ # Type
38
+ unsigned :type, 4
39
+ # Unused
40
+ unsigned :unused, 8
41
+ # Checksum
42
+ unsigned :checksum, 16
43
+ # Group Address
44
+ octets :gaddr, 32
45
+ # Payload
46
+ rest :payload
47
+
48
+ # Check the checksum for this IGMP message
49
+ def checksum?
50
+ self.checksum == 0 || (self.checksum == compute_checksum)
51
+ end
52
+
53
+ # Compute and set the checkum for this IGMP message
54
+ def checksum!
55
+ self.checksum = compute_checksum
56
+ end
57
+
58
+ # Do whatever 'fixing' is neccessary in preparation
59
+ # for being sent
60
+ def fix!
61
+ self.checksum!
62
+ end
63
+
64
+ private
65
+ def compute_checksum
66
+ # The checksum is the 16-bit one's complement of the one's complement sum
67
+ # of the 8-octet IGMP message. For computing the checksum, the checksum
68
+ # field is zeroed.
69
+ tmp = []
70
+ tmp << ((((self.version << 4) | self.type) << 8) | self.unused)
71
+ tmp << 0
72
+ tmp << L3::Misc.ipv42long(self.gaddr)
73
+ tmp << self.payload
74
+ L3::Misc.checksum(tmp.pack("nnNa*"))
75
+ end
76
+ end
77
+ end
78
+ end
79
+ # vim: set ts=2 et sw=2:
@@ -0,0 +1,76 @@
1
+ # $Id: igmpv2.rb 14 2008-03-02 05:42:30Z warchild $
2
+ #
3
+ # Copyright (c) 2008, Jon Hart
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright
11
+ # notice, this list of conditions and the following disclaimer in the
12
+ # documentation and/or other materials provided with the distribution.
13
+ # * Neither the name of the <organization> nor the
14
+ # names of its contributors may be used to endorse or promote products
15
+ # derived from this software without specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
18
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
21
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #
28
+ module Racket
29
+ module L4
30
+ # Internet Group Management Protocol, Version 2: IGMPv2
31
+ #
32
+ # RFC2236 (http://www.faqs.org/rfcs/rfc2236.html)
33
+ class IGMPv2 < RacketPart
34
+ # Type
35
+ unsigned :type, 8
36
+ # Max Response Time
37
+ unsigned :time, 8
38
+ # Checksum
39
+ unsigned :checksum, 16
40
+ # Group Address
41
+ octets :gaddr, 32
42
+ # Payload
43
+ rest :payload
44
+
45
+ # Is the checksum of this IGMPv2 message correct
46
+ def checksum?
47
+ self.checksum == 0 || (self.checksum == compute_checksum)
48
+ end
49
+
50
+ # Set the checksum of this IGMPv2 message
51
+ def checksum!
52
+ self.checksum = compute_checksum
53
+ end
54
+
55
+ # Do whatever 'fixing' is neccessary in preparation
56
+ # for being sent
57
+ def fix!
58
+ checksum!
59
+ end
60
+
61
+ private
62
+ def compute_checksum
63
+ # The checksum is the 16-bit one's complement of the one's complement sum
64
+ # of the 8-octet IGMP message. For computing the checksum, the checksum
65
+ # field is zeroed.
66
+ tmp = []
67
+ tmp << ((self.type << 8) | self.time)
68
+ tmp << 0
69
+ tmp << L3::Misc.ipv42long(self.gaddr)
70
+ tmp << self.payload
71
+ L3::Misc.checksum(tmp.pack("nnNa*"))
72
+ end
73
+ end
74
+ end
75
+ end
76
+ # vim: set ts=2 et sw=2: