unpack (Radius::Packet)

    # File radius/packet.rb, line 106
        def unpack(data)
          p_hdr = "CCna16a*"
          rcodes = {
    	1 => 'Access-Request',
    	2  => 'Access-Accept',
    	3  => 'Access-Reject',
    	4  => 'Accounting-Request',
    	5  => 'Accounting-Response',
    	11 => 'Access-Challenge',
    	12 => 'Status-Server',
    	13 => 'Status-Client'
          }

          @code, @identifier, len, @authenticator, attrdat = data.unpack(p_hdr)
          @code = rcodes[@code]

          unset_all

          while (attrdat.length > 0)
    	length = attrdat.unpack("xC")[0].to_i
    	tval, value = attrdat.unpack("Cxa#{length-2}")

    	tval = tval.to_i
    	if (tval == VSA_TYPE)
    	  # handle vendor-specific attributes
    	  vid, vtype, vlength = value.unpack("NCC")
    	  # XXX - How do we calculate the length of the VSA?  It's not
    	  # defined!

    	  # XXX - 3COM seems to do things a bit differently.  The 'if'
    	  # below takes care of that.  This is based on the
    	  # Net::Radius code.
    	  if vid == 429
    	    # 3COM packet
    	    vid, vtype = value.unpack("NN")
    	    vvalue = value.unpack("xxxxxxxxa#{length - 10}")[0]
    	  else
    	    vvalue = value.unpack("xxxxxxa#{vlength - 2}")[0]
    	  end
    	  type = @dict.vsattr_numtype(vid, vtype)
    	  if type == nil
    	    raise "Garbled vendor-specific attribute #{vid}/#{vtype}"
    	  end
    	  val = case type
    		when 'string' then vvalue
    		when 'integer'
    		  (@dict.vsaval_has_name(vid, vtype)) ?
    		  @dict.vsaval_name(vid, vtype, vvalue.unpack("N")[0]) :
    		    vvalue.unpack("N")[0]
    		when 'ipaddr' then inet_ntoa(vvalue)
    		when 'time' then vvalue.unpack("N")[0]
    		when 'date' then vvalue.unpack("N")[0]
    		else
    		  raise "Unknown VSattribute type found: #{vtype}"
    		end
    	  set_vsattr(vid, @dict.vsattr_name(vid, vtype), val)
    	else
    	  type = @dict.attr_numtype(tval)
    	  raise "Garbled attribute #{tval}" if (type == nil)
    	  val = case type
    		when 'string' then value
    		when 'integer'
    		  @dict.val_has_name(tval) ?
    		  @dict.val_name(tval, value.unpack("N")[0]) :
    		    value.unpack("N")[0]
    		when 'ipaddr' then inet_ntoa(value.unpack("N")[0])
    		when 'time' then value.unpack("N")[0]
    		when 'date' then value.unpack("N")[0]
    		else raise "Unknown attribute type found: #{type}"
    		end
    	  set_attr(@dict.attr_name(tval), val)
    	end
    	attrdat[0, length] = ""
          end
        end