ruby-radius 1.1

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.
data/README ADDED
@@ -0,0 +1,37 @@
1
+ = Ruby-Radius - RADIUS interface for Ruby
2
+
3
+ This Ruby module provides an interface to the RADIUS protocol. It
4
+ provides these two classes:
5
+
6
+ +Radius::Packet+:: Deals with Radius Packets
7
+ +Radius::Dictionary+:: - Deals with RADIUS dictionaries
8
+
9
+ This module's API is based heavily on the Net::Radius Perl module
10
+ created by Christopher Masto, Luis Munoz, and Ian Smith.
11
+
12
+ == Installation
13
+
14
+ Since the module is pure Ruby, to install this all that needs to be
15
+ done is to run the 'install.rb' script.
16
+
17
+ This package supports the use of vendor-specific attributes. This
18
+ type of attribute is defined in RFC 2138 and is used to support
19
+ 'proprietary' extensions on top of the base RADIUS specification.
20
+
21
+ The whole API is documented in rdoc-style comments within the source
22
+ itself. If you have extracted this from a distribution tarball, the
23
+ documentation should be included ready for you to read within the
24
+ 'doc' subdirectory. If you've gotten this from CVS, you need rdoc to
25
+ extract the HTML documentation. Visit the rdoc website at
26
+ http://rdoc.sourceforge.net/ for more information.
27
+
28
+ = Other stuff
29
+ Author:: Rafael 'Dido' Sevilla <dido@imperium.ph>
30
+ Requires:: Ruby 1.6.7 or later (may work with older versions)
31
+ License:: Copyright (c) 2002 Rafael R. Sevilla
32
+ GNU Lesser General Public License, see the file COPYING.LIB
33
+ for more details.
34
+
35
+ All of the test and example programs are placed in the public domain.
36
+
37
+ $Id: README 2 2006-12-17 06:16:21Z dido $
@@ -0,0 +1,289 @@
1
+ #
2
+ # This file contains dictionary translations for parsing
3
+ # requests and generating responses. All transactions are
4
+ # composed of Attribute/Value Pairs. The value of each attribute
5
+ # is specified as one of 4 data types. Valid data types are:
6
+ #
7
+ # string - 0-253 octets
8
+ # ipaddr - 4 octets in network byte order
9
+ # integer - 32 bit value in big endian order (high byte first)
10
+ # date - 32 bit value in big endian order - seconds since
11
+ # 00:00:00 GMT, Jan. 1, 1970
12
+ #
13
+ # Enumerated values are stored in the user file with dictionary
14
+ # VALUE translations for easy administration.
15
+ #
16
+ # Example:
17
+ #
18
+ # ATTRIBUTE VALUE
19
+ # --------------- -----
20
+ # Framed-Protocol = PPP
21
+ # 7 = 1 (integer encoding)
22
+ #
23
+
24
+
25
+
26
+ #
27
+ # Proper names for everything - use this instead of the above
28
+ #
29
+ ATTRIBUTE User-Name 1 string
30
+ ATTRIBUTE User-Password 2 string
31
+ ATTRIBUTE CHAP-Password 3 string
32
+ ATTRIBUTE NAS-IP-Address 4 ipaddr
33
+ ATTRIBUTE NAS-Port 5 integer
34
+ ATTRIBUTE Service-Type 6 integer
35
+ ATTRIBUTE Framed-Protocol 7 integer
36
+ ATTRIBUTE Framed-IP-Address 8 ipaddr
37
+ ATTRIBUTE Framed-IP-Netmask 9 ipaddr
38
+ ATTRIBUTE Framed-Routing 10 integer
39
+ ATTRIBUTE Filter-Id 11 string
40
+ ATTRIBUTE Framed-MTU 12 integer
41
+ ATTRIBUTE Framed-Compression 13 integer
42
+ ATTRIBUTE Login-IP-Host 14 ipaddr
43
+ ATTRIBUTE Login-Service 15 integer
44
+ ATTRIBUTE Login-TCP-Port 16 integer
45
+ ATTRIBUTE Reply-Message 18 string
46
+ ATTRIBUTE Callback-Number 19 string
47
+ ATTRIBUTE Callback-Id 20 string
48
+ ATTRIBUTE Expiration 21 date
49
+ ATTRIBUTE Framed-Route 22 string
50
+ ATTRIBUTE Framed-IPX-Network 23 ipaddr
51
+ ATTRIBUTE State 24 string
52
+ ATTRIBUTE Class 25 octets
53
+ ATTRIBUTE Vendor-Specific 26 octets
54
+ ATTRIBUTE Session-Timeout 27 integer
55
+ ATTRIBUTE Idle-Timeout 28 integer
56
+ ATTRIBUTE Termination-Action 29 integer
57
+ ATTRIBUTE Called-Station-Id 30 string
58
+ ATTRIBUTE Calling-Station-Id 31 string
59
+ ATTRIBUTE NAS-Identifier 32 string
60
+ ATTRIBUTE Proxy-State 33 octets
61
+ ATTRIBUTE Login-LAT-Service 34 string
62
+ ATTRIBUTE Login-LAT-Node 35 string
63
+ ATTRIBUTE Login-LAT-Group 36 octets
64
+ ATTRIBUTE Framed-AppleTalk-Link 37 integer
65
+ ATTRIBUTE Framed-AppleTalk-Network 38 integer
66
+ ATTRIBUTE Framed-AppleTalk-Zone 39 string
67
+ ATTRIBUTE Acct-Status-Type 40 integer
68
+ ATTRIBUTE Acct-Delay-Time 41 integer
69
+ ATTRIBUTE Acct-Input-Octets 42 integer
70
+ ATTRIBUTE Acct-Output-Octets 43 integer
71
+ ATTRIBUTE Acct-Session-Id 44 string
72
+ ATTRIBUTE Acct-Authentic 45 integer
73
+ ATTRIBUTE Acct-Session-Time 46 integer
74
+ ATTRIBUTE Acct-Input-Packets 47 integer
75
+ ATTRIBUTE Acct-Ouput-Packets 48 integer
76
+ ATTRIBUTE Acct-Terminate-Cause 49 integer
77
+ ATTRIBUTE Event-Timestamp 55 date
78
+ ATTRIBUTE NAS-Port-Type 61 integer
79
+ ATTRIBUTE Port-Limit 62 integer
80
+
81
+ ATTRIBUTE CHAP-Challenge 60 octets
82
+ ATTRIBUTE Login-LAT-Port 63 string
83
+
84
+
85
+ ATTRIBUTE ARAP-Password 70 octets # 16 octets of data
86
+ ATTRIBUTE ARAP-Features 71 octets # 14 octets of data
87
+ ATTRIBUTE ARAP-Zone-Access 72 integer
88
+ ATTRIBUTE ARAP-Security 73 integer
89
+ ATTRIBUTE ARAP-Security-Data 74 string
90
+ ATTRIBUTE Password-Retry 75 integer
91
+ ATTRIBUTE Prompt 76 integer
92
+ ATTRIBUTE Connect-Info 77 string
93
+ ATTRIBUTE Configuration-Token 78 string
94
+ ATTRIBUTE EAP-Message 79 octets
95
+ ATTRIBUTE Message-Authenticator 80 octets
96
+
97
+ ATTRIBUTE ARAP-Challenge-Response 84 octets # 8 octets of data
98
+ ATTRIBUTE Acct-Interim-Interval 85 integer
99
+ # 86: RFC 2867
100
+ ATTRIBUTE NAS-Port-Id 87 string
101
+ ATTRIBUTE Framed-Pool 88 string
102
+
103
+
104
+ #
105
+ # Integer Translations
106
+ #
107
+
108
+ # Service types
109
+ VALUE Service-Type Login-User 1
110
+ VALUE Service-Type Framed-User 2
111
+ VALUE Service-Type Callback-Login-User 3
112
+ VALUE Service-Type Callback-Framed-User 4
113
+ VALUE Service-Type Outbound-User 5
114
+ VALUE Service-Type Administrative-User 6
115
+ VALUE Service-Type NAS-Prompt-User 7
116
+ VALUE Service-Type Authenticate-Only 8
117
+ VALUE Service-Type Callback-NAS-Prompt 9
118
+ VALUE Service-Type Call-Check 10
119
+ VALUE Service-Type Callback-Administrative 11
120
+
121
+ # Framed Protocols
122
+
123
+ VALUE Framed-Protocol PPP 1
124
+ VALUE Framed-Protocol SLIP 2
125
+
126
+ # Framed Routing Values
127
+
128
+ VALUE Framed-Routing None 0
129
+ VALUE Framed-Routing Broadcast 1
130
+ VALUE Framed-Routing Listen 2
131
+ VALUE Framed-Routing Broadcast-Listen 3
132
+
133
+ # Framed Compression Types
134
+
135
+ VALUE Framed-Compression None 0
136
+ VALUE Framed-Compression Van-Jacobson-TCP-IP 1
137
+
138
+ # Login Services
139
+
140
+ VALUE Login-Service Telnet 0
141
+ VALUE Login-Service Rlogin 1
142
+ VALUE Login-Service TCP-Clear 2
143
+ VALUE Login-Service PortMaster 3
144
+
145
+ # Status Types
146
+
147
+ VALUE Acct-Status-Type Start 1
148
+ VALUE Acct-Status-Type Stop 2
149
+ VALUE Acct-Status-Type Interim-Update 3
150
+
151
+ # Authentication Types
152
+
153
+ VALUE Acct-Authentic RADIUS 1
154
+ VALUE Acct-Authentic Local 2
155
+ VALUE Acct-Authentic PowerLink128 100
156
+
157
+ # Termination Options
158
+
159
+ VALUE Termination-Action Default 0
160
+ VALUE Termination-Action RADIUS-Request 1
161
+
162
+ # NAS Port Types, available in ComOS 3.3.1 and later
163
+
164
+ VALUE NAS-Port-Type Async 0
165
+ VALUE NAS-Port-Type Sync 1
166
+ VALUE NAS-Port-Type ISDN 2
167
+ VALUE NAS-Port-Type ISDN-V120 3
168
+ VALUE NAS-Port-Type ISDN-V110 4
169
+
170
+ # Acct Terminate Causes, available in ComOS 3.3.2 and later
171
+
172
+ VALUE Acct-Terminate-Cause User-Request 1
173
+ VALUE Acct-Terminate-Cause Lost-Carrier 2
174
+ VALUE Acct-Terminate-Cause Lost-Service 3
175
+ VALUE Acct-Terminate-Cause Idle-Timeout 4
176
+ VALUE Acct-Terminate-Cause Session-Timeout 5
177
+ VALUE Acct-Terminate-Cause Admin-Reset 6
178
+ VALUE Acct-Terminate-Cause Admin-Reboot 7
179
+ VALUE Acct-Terminate-Cause Port-Error 8
180
+ VALUE Acct-Terminate-Cause NAS-Error 9
181
+ VALUE Acct-Terminate-Cause NAS-Request 10
182
+ VALUE Acct-Terminate-Cause NAS-Reboot 11
183
+ VALUE Acct-Terminate-Cause Port-Unneeded 12
184
+ VALUE Acct-Terminate-Cause Port-Preempted 13
185
+ VALUE Acct-Terminate-Cause Port-Suspended 14
186
+ VALUE Acct-Terminate-Cause Service-Unavailable 15
187
+ VALUE Acct-Terminate-Cause Callback 16
188
+ VALUE Acct-Terminate-Cause User-Error 17
189
+ VALUE Acct-Terminate-Cause Host-Request 18
190
+
191
+
192
+ #
193
+ # Obsolete names for backwards compatibility with older users files
194
+ # If you want RADIUS accounting logs to use the new names instead of
195
+ # these, move this section to the beginning of the dictionary file
196
+ # and kill and restart radiusd
197
+ # If you don't have a RADIUS 1.16 users file that you're still using,
198
+ # you can delete or ignore this section.
199
+ #
200
+ ATTRIBUTE Client-Id 4 ipaddr
201
+ ATTRIBUTE Client-Port-Id 5 integer
202
+ ATTRIBUTE User-Service-Type 6 integer
203
+ ATTRIBUTE Framed-Address 8 ipaddr
204
+ ATTRIBUTE Framed-Netmask 9 ipaddr
205
+ ATTRIBUTE Framed-Filter-Id 11 string
206
+ ATTRIBUTE Login-Host 14 ipaddr
207
+ ATTRIBUTE Login-Port 16 integer
208
+ ATTRIBUTE Old-Password 17 string
209
+ ATTRIBUTE Port-Message 18 string
210
+ ATTRIBUTE Dialback-No 19 string
211
+ ATTRIBUTE Dialback-Name 20 string
212
+ ATTRIBUTE Challenge-State 24 string
213
+ VALUE Service-Type Dialback-Login-User 3
214
+ VALUE Service-Type Dialback-Framed-User 4
215
+ VALUE Service-Type Shell-User 6
216
+ VALUE Framed-Compression Van-Jacobsen-TCP-IP 1
217
+ #VALUE Auth-Type Unix 1
218
+ #
219
+ # END of obsolete names for backwards compatibility
220
+ #
221
+
222
+ #
223
+ # Configuration Values
224
+ # uncomment out these two lines to turn account expiration on
225
+ #
226
+
227
+ #VALUE Server-Config Password-Expiration 30
228
+ #VALUE Server-Config Password-Warning 5
229
+
230
+ ##
231
+ ## VENDOR SPECIFIC ATTRIBUTES
232
+ ##
233
+ ## The following entries demonstrate the use of VSAs
234
+ ##
235
+
236
+ # cisco-avpair is used for various functions by cisco IOS. Most
237
+ # notably, it's used to create VPDN tunnels.
238
+ #
239
+ VENDORATTR 9 cisco-avpair 1 string
240
+
241
+ # Symbol attributes
242
+
243
+ # Access request attribute's
244
+ VENDORATTR 388 Symbol-Service-Type 1 integer
245
+ # SSID in the access request
246
+ VENDORATTR 388 Symbol-Wlan-Index 2 string
247
+ # Wlan index in the Access Request, deprecated in WING 5.0, this check item is replaced by VSA - Symbol-Allowed-ESSID
248
+ VENDORATTR 388 Symbol-Attr-4 4 string
249
+ VENDORATTR 388 Symbol-Allowed-ESSID 3 string
250
+ # Reply Attribute which sends the expiry date & time for the guest users
251
+ VENDORATTR 388 Guest-User-Expiry-Date-Time 7 string
252
+ # Reply Attribute which sends the start date & time for the guest users
253
+ VENDORATTR 388 Guest-User-Start-Date-Time 8 string
254
+ # Rate Limit Parameters
255
+ VENDORATTR 388 Symbol-Downlink-Limit-Kbps 10 integer
256
+ VENDORATTR 388 Symbol-Uplink-Limit-Kbps 11 integer
257
+ # User group name
258
+ VENDORATTR 388 Symbol-User-Group 12 string
259
+ VENDORATTR 388 Symbol-User-Device-Type 13 string
260
+ VENDORATTR 388 Symbol-User-OS 14 string
261
+ VENDORATTR 388 Symbol-User-Browser 15 string
262
+ VENDORATTR 388 Symbol-Login-Service 100 integer
263
+
264
+ # Aruba attributes
265
+
266
+ VENDORATTR 14823 Aruba-User-Role 1 string
267
+ VENDORATTR 14823 Aruba-User-Vlan 2 integer
268
+ VENDORATTR 14823 Aruba-Priv-Admin-User 3 integer
269
+ VENDORATTR 14823 Aruba-Admin-Role 4 string
270
+ VENDORATTR 14823 Aruba-Essid-Name 5 string
271
+ VENDORATTR 14823 Aruba-Location-Id 6 string
272
+ VENDORATTR 14823 Aruba-Port-Id 7 string
273
+ VENDORATTR 14823 Aruba-Template-User 8 string
274
+ VENDORATTR 14823 Aruba-Named-User-Vlan 9 string
275
+ VENDORATTR 14823 Aruba-AP-Group 10 string
276
+ VENDORATTR 14823 Aruba-Framed-IPv6-Address 11 string
277
+
278
+ # Airespace attributes
279
+ VENDORATTR 14179 Airespace-Wlan-Id 1 integer
280
+ VENDORATTR 14179 Airespace-QOS-Level 2 integer
281
+ VENDORATTR 14179 Airespace-DSCP 3 integer
282
+ VENDORATTR 14179 Airespace-8021p-Tag 4 integer
283
+ VENDORATTR 14179 Airespace-Interface-Name 5 string
284
+ VENDORATTR 14179 Airespace-ACL-Name 6 string
285
+
286
+ VENDORVALUE 14179 Airespace-QOS-Level Bronze 3
287
+ VENDORVALUE 14179 Airespace-QOS-Level Silver 0
288
+ VENDORVALUE 14179 Airespace-QOS-Level Gold 1
289
+ VENDORVALUE 14179 Airespace-QOS-Level Platinum 2
@@ -0,0 +1,51 @@
1
+ #!/usr/local/bin/ruby
2
+ #
3
+ # Sample RADIUS client
4
+ #
5
+ # This code is provided for illustrative purposes only and is placed
6
+ # in the public domain.
7
+ #
8
+ # $Id: radiusclient.rb 2 2006-12-17 06:16:21Z dido $
9
+ #
10
+ require 'radius/dictionary'
11
+ require 'radius/packet'
12
+ require 'socket'
13
+
14
+ user = 'test'
15
+ pass = 'test'
16
+ authhost = '127.0.0.1';
17
+ authport = '1812';
18
+ secret = 'h1dd3n';
19
+ dictfile = "../dictionary"
20
+
21
+ dict = Radius::Dict.new
22
+ File.open(dictfile) {
23
+ |fn|
24
+ dict.read(fn)
25
+ }
26
+
27
+ def bigrand()
28
+ return([rand(65536), rand(65536), rand(65536), rand(65536),
29
+ rand(65536), rand(65536), rand(65536), rand(65536)].pack("n8"))
30
+ end
31
+
32
+ ident = 170;
33
+ req = Radius::Packet.new(dict)
34
+ req.code = 'Access-Request'
35
+ req.identifier = ident
36
+ req.authenticator = bigrand()
37
+ req.set_attr('NAS-IP-Address', '127.0.0.1')
38
+ req.set_attr('User-Name', user)
39
+ req.set_password(pass, secret)
40
+ print req.to_s(nil) + "\n"
41
+ p = req.pack
42
+ print p.unpack("H*"), "\n"
43
+ print "Socket connecting\n"
44
+ sock = UDPSocket.open
45
+ sock.connect(authhost, authport)
46
+ print "Socket sending\n"
47
+ sock.send(p, 0)
48
+ rec = sock.recvfrom(65536)
49
+ resp = Radius::Packet.new(dict)
50
+ resp.unpack(rec[0])
51
+ print resp.to_s(nil)
@@ -0,0 +1,24 @@
1
+ #!/usr/local/bin/ruby
2
+ #
3
+ # Sample RADIUS client using the new Radius::Auth class
4
+ #
5
+ # This code is provided for illustrative purposes only and is placed
6
+ # in the public domain.
7
+ #
8
+ # $Id: rclient.rb 2 2006-12-17 06:16:21Z dido $
9
+ #
10
+ require 'radius/auth'
11
+
12
+ auth = Radius::Auth.new('../dictionary', '127.0.0.1', 5)
13
+ secret = 'h1dd3n'
14
+ print "login: "
15
+ user = $stdin.readline
16
+ user.chomp!
17
+ print "Password: "
18
+ pass = $stdin.readline
19
+ pass.chomp!
20
+ if (auth.check_passwd(user, pass, secret, '127.0.0.1'))
21
+ print "Authentication successful.\n"
22
+ else
23
+ print "Authentication failed.\n"
24
+ end
@@ -0,0 +1,131 @@
1
+ # RADIUS authenticator
2
+ # Copyright (C) 2002 Rafael R. Sevilla <dido@imperium.ph>
3
+ # This file is part of the Radius Authentication Module for Ruby
4
+ #
5
+ # The Radius Authentication Module for Ruby is free software; you can
6
+ # redistribute it and/or modify it under the terms of the GNU Lesser
7
+ # General Public License as published by the Free Software
8
+ # Foundation; either version 2.1 of the License, or (at your option)
9
+ # any later version.
10
+ #
11
+ # The Radius Authentication Module is distributed in the hope that it
12
+ # will be useful, but WITHOUT ANY WARRANTY; without even the implied
13
+ # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+ # See the GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with the GNU C Library; if not, write to the Free
18
+ # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
+ # 02111-1307 USA.
20
+ #
21
+ # Author:: Rafael R. Sevilla (mailto:dido@imperium.ph)
22
+ # Copyright:: Copyright (c) 2002 Rafael R. Sevilla
23
+ # License:: GNU Lesser General Public License
24
+ # $Id: auth.rb 2 2006-12-17 06:16:21Z dido $
25
+ #
26
+
27
+ module Radius
28
+ require 'radius/packet'
29
+ require 'radius/dictionary'
30
+ require 'socket'
31
+
32
+ class Auth
33
+ # We can inspect and alter the contents of the internal RADIUS
34
+ # packet here (although this is probably not required for simple
35
+ # work)
36
+ attr_reader :packet
37
+
38
+ # This method initializes the Auth object, given a dictionary
39
+ # filename to read, the RADIUS host[:port] to connect to, and a
40
+ # timeout value in seconds for the connection.
41
+ # =====Parameters
42
+ # +dictfilename+:: Dictionary filename to read
43
+ # +radhost+:: name of RADIUS server optionally followed by port number
44
+ # +myip+:: the client's own IP address (NAS IP address)
45
+ # +timeout+:: Timeout time
46
+ def initialize(radhost, myip, timeout, dictfilename = File.dirname(__FILE__) + "/../../dictionary")
47
+ @dict = Radius::Dictionary.new
48
+ if dictfilename != nil
49
+ File.open(dictfilename) do |fn|
50
+ @dict.read(fn)
51
+ end
52
+ end
53
+ @packet = Radius::Packet.new(@dict)
54
+
55
+ # this is probably better than starting identifiers at 0
56
+ @packet.identifier = Kernel.rand(65535)
57
+ @myip = myip
58
+ @host, @port = radhost.split(":")
59
+ @port = Socket.getservbyname("radius", "udp") unless @port
60
+ @port = 1812 unless @port
61
+ @port = @port.to_i # just in case
62
+ @timeout = timeout
63
+ @sock = UDPSocket.open
64
+ @sock.connect(@host, @port)
65
+ end
66
+
67
+ # Verifies a username/password pair against the RADIUS server
68
+ # associated with the Auth object.
69
+ #
70
+ # =====Parameters
71
+ # +name+:: The user name to verify
72
+ # +pwd+:: The password associated with this name
73
+ # +secret+:: The RADIUS secret of the system
74
+ # =====Return value
75
+ # returns true or false depending on whether or not the attempt succeeded or failed.
76
+ def check_passwd(name, pwd, secret)
77
+ send_check_passwd(name, pwd, secret)
78
+ recv_check_passwd
79
+ end
80
+
81
+ def send_check_passwd(name, pwd, secret)
82
+ @packet.code = 'Access-Request'
83
+ gen_authenticator
84
+ @packet.set_attr('User-Name', name)
85
+ @packet.set_attr('NAS-IP-Address', @myip)
86
+ @packet.set_password(pwd, secret)
87
+ send_packet
88
+ end
89
+
90
+ def recv_check_passwd
91
+ recv_packet
92
+ return(@packet.code == 'Access-Accept')
93
+ end
94
+
95
+ # Generate an authenticator, placing it in the @packet object's
96
+ # authenticator attribute. It will try to use /dev/urandom if
97
+ # possible, or the system rand call if that's not available.
98
+ def gen_authenticator
99
+ # get authenticator data from /dev/urandom if possible
100
+ if (File.exist?("/dev/urandom"))
101
+ File.open("/dev/urandom") do |urandom|
102
+ @packet.authenticator = urandom.read(16)
103
+ end
104
+ else
105
+ # use the Kernel:rand method. This is quite probably not
106
+ # as secure as using /dev/urandom, be wary...
107
+ @packet.authenticator = [rand(65536), rand(65536), rand(65536),
108
+ rand(65536), rand(65536), rand(65536), rand(65536),
109
+ rand(65536)].pack("n8")
110
+ end
111
+ return(@packet.authenticator)
112
+ end
113
+
114
+ # Sends a packet to the server via UDP.
115
+ def send_packet
116
+ data = @packet.pack
117
+ @packet.identifier = (@packet.identifier + 1) & 0xff
118
+ @sock.send(data, 0)
119
+ end
120
+
121
+ # Receive a packet from the server via UDP.
122
+ def recv_packet
123
+ if select([@sock], nil, nil, @timeout) == nil
124
+ raise "Timed out waiting for response packet from server"
125
+ end
126
+ data = @sock.recvfrom(65536)
127
+ @packet.unpack(data[0])
128
+ return(@packet)
129
+ end
130
+ end
131
+ end