code: func NewPacket(op Operation, srcHW net.HardwareAddr, srcIP net.IP, dstHW net.HardwareAddr, dstIP net.IP) (*Packet, error) {
  	// Validate hardware addresses for minimum length, and matching length
  	if len(srcHW) < 6 {
  		return nil, ErrInvalidHardwareAddr
  	}
  	if len(dstHW) < 6 {
  		return nil, ErrInvalidHardwareAddr
  	}
  	if len(srcHW) != len(dstHW) {
  		return nil, ErrInvalidHardwareAddr
  	}
  
  	// Validate IP addresses to ensure they are IPv4 addresses, and
  	// correct length
  	srcIP = srcIP.To4()
  	if srcIP == nil {
  		return nil, ErrInvalidIP
  	}
  	dstIP = dstIP.To4()
  	if dstIP == nil {
  		return nil, ErrInvalidIP
  	}
  
  	return &Packet{
  		// There is no Go-native way to detect hardware type of a network
  		// interface, so default to 1 (ethernet 10Mb) for now
  		HardwareType: 1,
  
  		// Default to EtherType for IPv4
  		ProtocolType: uint16(ethernet.EtherTypeIPv4),
  
  		// Populate other fields using input data
  		HardwareAddrLength: uint8(len(srcHW)),
  		IPLength:           uint8(len(srcIP)),
  		Operation:          op,
  		SenderHardwareAddr: srcHW,
  		SenderIP:           srcIP,
  		TargetHardwareAddr: dstHW,
  		TargetIP:           dstIP,
  	}, nil
  }
docs: // NewPacket creates a new Packet from an input Operation and hardware/IPv4
  // address values for both a sender and target.
  //
  // If either hardware address is less than 6 bytes in length, or there is a
  // length mismatch between the two, ErrInvalidHardwareAddr is returned.
  //
  // If either IP address is not an IPv4 address, or there is a length mismatch
  // between the two, ErrInvalidIP is returned.