# File radius/packet.rb, line 191
    def pack
      hdrlen = 1 + 1 + 2 + 16	# size of packet header
      p_hdr = "CCna16a*"	# pack template for header
      p_attr = "CCa*"		# pack template for attribute
      p_vsa = "CCNCCa*"		# pack template for VSA's
      p_vsa_3com = "CCNNa*"	# used by 3COM devices
    
      codes = {
	'Access-Request' => 1,
	'Access-Accept' => 2,
	'Access-Reject' => 3,
	'Accounting-Request' => 4,
	'Accounting-Response' => 5,
	'Access-Challenge' => 11,
	'Status-Server' => 12,
	'Status-Client' => 13 }
      attstr = ""
      each {
	|attr, value|
	anum = @dict.attr_num(attr)
	val = case @dict.attr_type(attr)
	      when "string" then value
	      when "integer"
		[@dict.attr_has_val(anum) ? 
	         @dict.val_num(anum, value) : value].pack("N")
	      when "ipaddr" then [inet_aton(value)].pack("N")
	      when "date" then [value].pack("N")
	      when "time" then [value].pack("N")
	      else
		next
	      end
	attstr += [@dict.attr_num(attr), val.length + 2, val].pack(p_attr)
      }

      # Pack vendor-specific attributes
      each_vsa {
	|vendor, attr, datum|
	code = @dict.vsattr_num(vendor, attr)
	vval = case @dict.vsattr_type(vendor, attr)
	       when "string" then datum
	       when "integer"
		 @dict.vsattr_has_val(vendor.to_i, code) ?
		 [@dict.vsaval_num(vendor, code, datum)].pack("N") :
		   [datum].pack("N")
	       when "ipaddr" then inet_aton(datum)
	       when "time" then [datum].pack("N")
	       when "date" then [datum].pack("N")
	       else next
	       end
	if vendor == 429
	  # For 3COM devices
	  attstr += [VSA_TYPE, vval.length + 10, vendor,
	    @dict.vsattr_num(vendor, attr), vval].pack(p_vsa_3com)
	else
	  attstr += [VSA_TYPE, vval.length + 8, vendor,
	    @dict.vsattr_num(vendor, attr), vval.length + 2,
	    vval].pack(p_vsa)
	end
      }

      return([codes[@code], @identifier, attstr.length + hdrlen,
	       @authenticator, attstr].pack(p_hdr))
    end