text: /**
      Kernel-mode virtual adapter interface.
   
      File: virtual_adapter.h
   
      @copyright
      Copyright (c) 2002 - 2009 SafeNet Inc, all rights reserved. 
  
      @author Markku Rossi (mtr@ssh.fi)
   
   */
  
  #ifndef VIRTUAL_ADAPTER_H
  #define VIRTUAL_ADAPTER_H
  
  #include "interceptor.h"
  
  /* ***************************** Data Types **********************************/
  
  /** Error codes for virtual adapter operations. */
  typedef enum {
    /** Success */
    SSH_VIRTUAL_ADAPTER_ERROR_OK              = 0,
    /** Success, status callback will be called again */
    SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE         = 1,
    /** Nonexistent adapter */
    SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT     = 2,
    /** Address configuration error */
    SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE = 3,
    /** Route configuration error */
    SSH_VIRTUAL_ADAPTER_ERROR_ROUTE_FAILURE   = 4,
    /** Parameter configuration error */
    SSH_VIRTUAL_ADAPTER_ERROR_PARAM_FAILURE   = 5,
    /** Memory allocation error */
    SSH_VIRTUAL_ADAPTER_ERROR_OUT_OF_MEMORY   = 6,
    /** Undefined internal error */
    SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR   = 255
  } SshVirtualAdapterError;
  
  /** Virtual adapter state. */
  typedef enum {
    /** Invalid value */
    SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED        = 0,
    /** Up */
    SSH_VIRTUAL_ADAPTER_STATE_UP               = 1,
    /** Down */
    SSH_VIRTUAL_ADAPTER_STATE_DOWN             = 2,
    /** Keep existing state */
    SSH_VIRTUAL_ADAPTER_STATE_KEEP_OLD         = 3,
  } SshVirtualAdapterState;
  
  /** Optional parameters for a virtual adapter. */
  struct SshVirtualAdapterParamsRec
  {
    /** Virtual adapter mtu. */
    SshUInt32 mtu;
  
    /** DNS server IP addresses. */
    SshUInt32 dns_ip_count;
    SshIpAddr dns_ip;
  
    /** WINS server IP addresses. */
    SshUInt32 wins_ip_count;
    SshIpAddr wins_ip;
  
    /** Windows domain name. */
    char *win_domain;
  
    /** Netbios node type. */
    SshUInt8 netbios_node_type;
  };
  
  typedef struct SshVirtualAdapterParamsRec SshVirtualAdapterParamsStruct;
  typedef struct SshVirtualAdapterParamsRec *SshVirtualAdapterParams;
  
  /* ******************* Sending and Receiving Packets *************************/
  
  /** Send packet `pp' to the IP stack like it was received by the
      virtual adapter indexed by `pp->ifnum_in'. The packet `pp' must be a 
      plain IP packet (IPv4 or IPv6) or it must be of the same media type 
      as the virtual adapter (most probably ethernet). This will free the
      packet `pp'.
  
      NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_receive()!
  */
  void ssh_virtual_adapter_send(SshInterceptor interceptor,
  			      SshInterceptorPacket pp);
  
  /** Callback function of this type is called whenever a packet is
      sent out via a virtual adapter. This function must eventually free the
      packet by calling ssh_interceptor_packet_free.  
     
      This function is used for handling only those ARP, neighbor discovery, 
      and DHCP packets that are not handled by the generic engine packet 
      callback. This function must not be used for passing normal
      IP packets.
  
      Note that this function may be called asynchronously. */
  typedef void (*SshVirtualAdapterPacketCB)(SshInterceptor interceptor,
                                            SshInterceptorPacket pp,
                                            void *adapter_context);
  
  /* **************************** Generic Callbacks ****************************/
  
  /** A callback function of this type is called to notify about the
     success of a virtual adapter operation.  
     
     - The argument `error' describes whether the operation was successful or 
       not. If `error' indicates success, the arguments `adapter_ifnum', 
       `adapter_name', and `state' contain information about the virtual adapter.
     
     - The argument `adapter_ifnum' is an unique interface identifier for the 
       virtual adapter.  You can use it configuring additional routes for 
       the adapter, and for configuring and destroying the adapter.  
     
     - The argument `adapter_name' contains the name of the created adapter. 
       The returned name is the same that identifies the interface in the 
       interceptor's interface callback. 
  
     - The argument `adapter_context' is the context attached to the virtual
       adapter in the call to ssh_virtual_adapter_attach.
  
     Arguments `adapter_ifnum', `adapter_name', `adapter_state', and 
     `adapter_context' are valid only for the duration of the callback. */
  typedef void (*SshVirtualAdapterStatusCB)(SshVirtualAdapterError error,
                                            SshInterceptorIfnum adapter_ifnum,
                                            const unsigned char *adapter_name,
  					  SshVirtualAdapterState adapter_state,
  					  void *adapter_context,
                                            void *context);
  
  /* **************************** Attach and Detach ****************************/
     
  /** A callback function of this type is called to notify about detachment 
      of a virtual adapter from the engine. The callback is meant only as a 
      destructor of the virtual adapter context, and thus should be called 
      whenever there is no possibility of `packet_cb' being called again. 
      The argument `adapter_context' is the context attached to the virtual 
      adapter in the call to ssh_virtual_adapter_attach. */
  typedef void (*SshVirtualAdapterDetachCB)(void *adapter_context);
     
  /** Attaches the packet callback and context to a virtual adapter.
  
     - The argument `packet_cb' specifies a callback function that is 
       called when a packet is received from the virtual adapter. The argument
       `adapter_context' is the context for this callback.
     
     - The optional argument `detach_cb' specifies an engine-level 
       destructor for `adapter_context'. It must be called when the 
       interceptor is done with virtual adapter, i.e. when the `packet_cb' 
       will not be called for this adapter again. Even in case of instant 
       failure, the `detach_cb' must be called.
  
     - The operation completion callback `callback' must be called to notify 
       about success or failure of the attachment. In failure cases `callback' 
       must be called after `detach_cb'. The argument `context' is the context 
       data for this callback. 
  
     NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_attach()! 
  */
  void ssh_virtual_adapter_attach(SshInterceptor interceptor,
  				SshInterceptorIfnum adapter_ifnum,
                                  SshVirtualAdapterPacketCB packet_cb,
                                  SshVirtualAdapterDetachCB detach_cb,
                                  void *adapter_context,
                                  SshVirtualAdapterStatusCB callback,
                                  void *context);
  
  /** Detach the virtual adapter `adapter_ifnum'. The success of the
      operation is notified by calling the callback function `callback'.
     
      The detach operation will fail with the error code 
      SSH_VIRTUAL_ADAPTER_NONEXISTENT if the virtual adapter was never 
      attached. Detaching a virtual adapter must generate an interface callback 
      for the interceptor.
     
      If a detach callback was specified in ssh_virtual_adapter_attach, then
      this `detach_cb' must be called before calling the operation completion
      callback `callback'.
     
      NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_detach()!
  */
  void ssh_virtual_adapter_detach(SshInterceptor interceptor,
  				SshInterceptorIfnum adapter_ifnum,
  				SshVirtualAdapterStatusCB callback,
  				void *context);
  
  /** Detach all configured virtual adapters. This is called when the engine 
      is stopped during interceptor is unloading. This function must call 
      `detach_cb' for each detached virtual adapter that defines `detach_cb'.
      
      NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO 
      ssh_virtual_adapter_detach_all()! */
  void ssh_virtual_adapter_detach_all(SshInterceptor interceptor);
  
  /* *************************** Configuration *********************************/
  
  #ifdef INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE
  
  /** Configures the virtual adapter `adapter_ifnum' with `state', `addresses',
      and `params'. The argument `adapter_ifnum' must be the valid interface 
      index of a virtual adapter that has been attached to the engine during
      pm connect.
      
      The argument `adapter_state' specifies the state to configure for the
      virtual adapter.
      
      The arguments `num_addresses' and `addresses' specify the IP addresses
      for the virtual adapter. The addresses must specify the netmask. If 
      `addresses' is NULL, the address configuration will not be changed.
      Otherwise the existing addresses will be removed from the virtual adapter
      and specified addresses will be added. To clear all addresses from the
      virtual adapter, specify `addresses' as non-NULL and `num_addresses' as 0.
      
      The argument `params' specifies optional parameters for the virtual 
      adapter. If `params' is non-NULL, then the existing params will be cleared
      and the specified params will be set for the virtual adapter. 
  
      Any configured interface addresses must survive interface state changes.
  
      If the define INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE is not
      defined then the interceptor does not support kernel level virtual
      adapter configure.
  */
  void ssh_virtual_adapter_configure(SshInterceptor interceptor,
  				   SshInterceptorIfnum adapter_ifnum,
  				   SshVirtualAdapterState adapter_state,
  				   SshUInt32 num_addresses,
  				   SshIpAddr addresses,
  				   SshVirtualAdapterParams params,
  				   SshVirtualAdapterStatusCB callback,
  				   void *context);
  
  #endif /* INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE */
  
  /* *************************** Virtual Adapter Status ************************/
  
  /** This function will call `callback' for virtual adapter `adapter_ifnum'.
      If `adapter_ifnum' equals SSH_INTERCEPTOR_INVALID_IFNUM, then this 
      function calls `callback' once for each existing virtual adapter with 
      error code SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE, and once with error code 
      SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT after enumerating all virtual 
      adapters. */
  void ssh_virtual_adapter_get_status(SshInterceptor interceptor,
  				    SshInterceptorIfnum adapter_ifnum,
  				    SshVirtualAdapterStatusCB callback,
  				    void *context);
  
  /* *************************** Utility functions *****************************/
  
  /** These generic utility functions that are implemented in files 
      virtual_adapter_misc.c and virtual_adapter_util.s, and they use the 
      virtual adapter API described above. */
  
  /** Initializes engine side virtual adapter contexts and attaches the existing 
      virtual adapters to engine. */
  SshVirtualAdapterError ssh_virtual_adapter_init(SshInterceptor interceptor);
  
  /** Unitializes engine side virtual adapter contexts and detaches virtual 
      adapters from the engine. */
  SshVirtualAdapterError ssh_virtual_adapter_uninit(SshInterceptor interceptor);
  
  /** Creates a pseudo Ethernet hardware address for the virtual adapter
      `adapter_ifnum'. The address is formatted in the buffer `buffer' which
      must have space for SSH_ETHERH_ADDRLEN bytes. */
  void 
  ssh_virtual_adapter_interface_ether_address(SshInterceptorIfnum adapter_ifnum,
  					    unsigned char *buffer);
  
  /** Create a pseudo Ethernet hardware address for the IP address `ip'.
      The address `ip' can be an IPv4 or an IPv6 address.  The address if
      formatted in the buffer `buffer' which must have space for
      SSH_ETHERH_ADDRLEN bytes. */
  void ssh_virtual_adapter_ip_ether_address(SshIpAddr ip, unsigned char *buffer);
  
  /** Encode virtual adapter params `params' to buffer `buffer'. This
      function returns TRUE on success. The caller must ssh_free the allocated 
      memory in `data'. */
  Boolean
  ssh_virtual_adapter_param_encode(SshVirtualAdapterParams params,
  				 unsigned char **data, size_t *len);
  
  /** Decode virtual adapter params from table `data' into `params'. This 
      function returns TRUE on success. */
  Boolean
  ssh_virtual_adapter_param_decode(SshVirtualAdapterParams params,
  				 const unsigned char *data, size_t len);
  
  #endif /* not VIRTUAL_ADAPTER_H */
  