/* 
*            Copyright (c) 1998-2001 by NETsilicon Inc.
*
*  This software is copyrighted by and is the sole property of
*  NETsilicon.  All rights, title, ownership, or other interests
*  in the software remain the property of NETsilicon.  This
*  software may only be used in accordance with the corresponding
*  license agreement.  Any unauthorized use, duplication, transmission,
*  distribution, or disclosure of this software is expressly forbidden.
*
*  This Copyright notice may not be removed or modified without prior
*  written consent of NETsilicon.
*
*  NETsilicon, reserves the right to modify this software
*  without notice.
*
*  NETsilicon
*  411 Waverley Oaks Road                  USA 781.647.1234
*  Suite 227                               http://www.netsilicon.com
*  Waltham, MA 02452                       AmericaSales@netsilicon.com
*
*************************************************************************
*  $Name: netos6_branch $
*  $Date: 2004/08/30 20:52:12 $
*  $Source: /cvs_tick/netsilicon_netos2/netos/h/tcpip/fpublic.h,v $
*  $Revision: 1.15.2.2 $
***************************************************************************
*  File Description: Public Socket Functions                        
***************************************************************************/

/* Application API functions */

#ifndef _FPUBLIC_
#define _FPUBLIC_
#ifdef __cplusplus
extern "C"
{
#endif

/* Device Configuration Functions - ll_config can be called
   with a physical device name, e.g. "eth0", in which case
   it will bring up the physical link and optionally assign
   a new IP address.  If called with ipaddr 0xFFFFFFFF then
   the current address assignment, which may be zero, is
   not altered, otherwise the current address is altered to ipaddr.
   Note that 0xFFFFFFFF and 0x00000000 are NOT valid addresses
   for an alias, e.g. "eth0:0", and ll_config will return and
   error (FNS_EADDRNOTAVAIL) if called on an alias with an invalid
   address.

   If ll_config is called with an alias device name, e.g. "eth0:0",
   then an IP alias address is created for the interface.  However,
   the physical interface is NOT brought up (it might already be
   up but if not its left down) until ll_config is called on
   the physical interface, e.g. "eth0" in this example.  Note
   that since ipaddr == 0x00000000 is legal on the primary device,
   "eth0" in this example, then the device can be brought online
   to communicate via an alias address in spite of the fact that
   no primary address has been assigned.  

   So, for example, automatic IPv4 link-local address assignment can
   be made to "eth0:0" and the interface can operate with a link-local
   address, and DHCP can be used to bring up "eth0" and when it does
   a routable address can be configured by DHCP.
*/
typedef void (*addr_conflict_cb)(const char *devname, u32 ipaddr, char *ll_addr, int ll_len);

extern  int  ll_config(const char *devname, u32 ipaddr, u32 netmask, 
                       unsigned mtu, u32 unused);

/* ll_unconfig brings down an interface physically if the device
   name corresponds to the physical device, e.g., "eth0".  It
   does not remove any configured IP addresses including aliases
   when called on the primary device.  If, however, it is called
   with an alias address name like "eth0:0" then the physical 
   interface is NOT brought down, but the alias address is physically
   deleted and cannot be restored without calling ll_config() again
   for the alias device, "eth0:0" in this example, using a valid
   IP address (i.e. 0xFFFFFFFF will NOT work to restore the alias
   address).  
*/
extern  int  ll_unconfig( const char *devname );

/* ll_arp_address is intended to be used to determine if an address is
   in use, and after deciding to use the address, to send some gratuitous
   ARPs to flush any stale ARP caches. If it is called with non 0 is_announcement 
   then it sends ARP probes, otherwise it sends it sends gratuitous ARPs
   If called with blocking set to true (nonzero) to send probes
   then the caller is blocked in os_sleep until the probing is complete.
*/

extern int ll_arp_address(const char *devname, u32 probe_addr, unsigned int probe_count, unsigned int interval,
                          int is_announcement, int blocking );

/* ll_register_dup_addr_callback registers a callback which is called if the 
   stack detects a duplicate address conflict (another host using our address)
   The callback is called from arp_up.
*/
extern int ll_register_dup_addr_callback(const char *ifname, addr_conflict_cb conflict_cb);


/* Routing functions */
extern  int  ip_add_static_route(const char *devname, u32 daddress, u32 subnet,
			                     u32 gateway, int cost, char mode);

extern  int  ip_del_static_route(u32 ip_address, u32 ip_mask);

/* route leaking (redistribution) functions */
extern  int  ip_add_route_leak( int dest_proto, int src_proto, void *parm );
extern  int  ip_del_route_leak( int dest_proto, int src_proto );
/* New API call to selectively enable/disable ICMP router advertisements
 * on an interface.  Works on aliases like eth0:1 as well as primary
 * devices.  Device must already have a valid IP address
 */
extern  int  ip_router_advertisements(char *devname, int bEnable);

/* API to get the routing table. */
typedef struct _ip_route_entry {
    u32     dest;               /* Destination IP addr for this route */
    u32     mask;               /* Mask for destination */
    long    if_index;           /* Index of local IF for this route */
    /* Note: for multiple IP addresses add some space to accomodate
       address name like "eth0:3".  We ASSume that nobody in their right
       mind is going to have more than 999 addresses on a single interface!!
    */
    char    if_name[MAX_DEV_NAME+4]; /* Name of interface from Fusion device table */
    long    metric1;            /* Primary routing metric */
    long    metric2;            /* Alternate routing metric */
    long    metric3;            /* Alternate routing metric */
    long    metric4;            /* Alternate routing metric */
    long    metric5;
    u32     next_hop;           /* IP addr of next hop */
    long    rt_type;            /* Type of this route */
    long    owner;              /* How this route was learned */
    long    age;                /* No. of seconds since updating this route */
}ip_route_entry, *ip_route_entry_ptr;

typedef struct _ip_route_tbl {
    int  count;
    ip_route_entry_ptr  tbl;
}ip_route_tbl, *ip_route_tbl_ptr;

/* Route Modes */
#define	DEL_ROUTE	0
#define ADD_ROUTE	1
#define UPD_ROUTE	2

/* Route types */
#define ROUTE_TYPE_OTHER    1
#define ROUTE_TYPE_INVALID  2
#define ROUTE_TYPE_DIRECT   3
#define ROUTE_TYPE_INDIRECT 4

/* Route owners */

#define ROUTE_OWNER_RIP         2
#define ROUTE_OWNER_OSPF        3
#define ROUTE_OWNER_STATIC      4
#define ROUTE_OWNER_LOCAL       5
#define ROUTE_OWNER_OTHER       255

extern int ip_get_routing_table(ip_route_tbl_ptr route_table);

/* Socket functions */
extern  int  fns_accept(int fd, saddr * addrp, int * addrlen, int * errp);
extern  int  fns_bind(int fd, saddr * name, int namelen, int *errp);
extern  int  fns_blocking(int fd, int *errp);
extern  int  fns_caccept(int fd, saddr * addrp, int * addrlen, int *errp);
extern  int  fns_close( int sd, int *errp );
extern  int  fns_connect(int fd, saddr * name, int namelen, int *errp);
extern  int  fns_getpeername(int sd, saddr * name, int * namelen, int *errp);
extern  int  fns_getserr (int sd);
extern  int  fns_getsockname(int fd, saddr * saddrp, int * addrsize, int *errp);

/*** Fast UDP Sockets API ***/
extern int fsock_errno;

int fns_fsock_init(int numfd, int *errp);
int fns_fsocket (int domain, int type, int protocol, int *erp);
int fns_fbind(int fd, struct sockaddr_in *addr, int addrlen, int *errp);
char *fns_fgetbuff(int fd, int szData, int *errp);
int fns_fsendto(int fd, char *buf, int len, int flags,struct sockaddr_in *sa,
				int salen, int *errp);
int fns_fsocket_close(int fd, int *errp);

/** end Fast UDP Sockets API **/

extern  int  fns_ip_bind(int s, int pref_sock, int * errp);
extern  int  fns_listen(int fd, int backlog, int *errp);
extern  int  fns_nonblocking(int fd, int *errp);
extern  int  fns_nselect(struct sel * selp, int cnt, u32 * waitp, 
                        int (*pfi)(struct sel *, int, u32, void *), 
                        void * arg, int * errp);
extern  int  fns_pioctl(int fd, int cmnd, char * addr, int len, u16 flags, int *errp);
extern  int  fns_recv(int fd, char * buf, int buf_len, int flags, int * errp);
extern  int  fns_recvfrom(int fd, char * buf, int buflen, int flags, 
                     saddr * saddrp, int * addrlenp, int * errp);
extern  int  fns_recvh(int fd, char * buf, int buf_len, int flags,
                      char * hdr, int * hdrlenp, int * errp);
extern  int  fns_recvht(int fd, char * buf, int buf_len, int flags,
			        char * hdr, int * hdrlenp, u32 * timep, int * errp);
extern  int  fns_reject(int fd, int *errp);
extern  int  fns_send(int fd, char * buf, int buf_len, int flags, int * errp);
extern  int  fns_sendh(int fd, char * buf, int buf_len, int flags, 
                      char * hdr, int hdrlen, int * errp);
extern  int  fns_sendto(int fd, char * buf, int buflen, int flags, 
                       saddr * saddrp, int saddrlen, int * errp);

extern int fns_sockatmark(int fd, int *errp);

extern  int	 fns_setsockopt (int sd, int level, int optname, char *optval, 
                          int optlen, int *errp);
extern  int fns_getsockopt (int sd, int level, int optname, char *optval, 
                         int *optlen, int *errp);

extern	int  fns_shutdown(int fd, int direction, int *errp);
extern  int  fns_socket(int af, int type, int protocol, int * errp);
extern  int  fns_socketpair(int af, int type, int protocol, int sv[2]);

/* Convenience functions */
extern  char *adr2str(saddr * addrp, char * buf);

/* High level convenience functions */
extern  int  fns_tcp_open (int pref_sock, u16 dport,char *daddr, int * errp);
extern  int  fns_udp_open(int pref_sock, int * errp);

/* Function to allow run-time over-ride of default Path MTU discovery 
   parameters of operation */
extern int fusion_ip_pmtu_set_cache_params(int cache_size,int cache_lifetime,
										   int timer_short, int timer_long,
										   int val_table_len,
										   u16 *val_table);

/* Function to allow setting the default time-to-live value to place into 
   outgoing packets */
extern int fns_ip_default_ttl(int default_ttl);

/* Function to configure Fusion to be able top forward packets or not */
extern int fns_ip_forwarding(u8 ip_forwarding);

/* Function to allow setting the default time-to-live value to place into 
   outgoing TCP segments */
extern int fns_tcp_default_ttl(int tcp_default_ttl);

/* Function to allow setting the TCP idle interval for keepalive processing */
extern int fns_tcp_ka_interval(int ka_interval);

/* Function to allow setting the TCP garbage option for keepalive processing */
extern int fns_tcp_garbage(u8 garbage);

/* Function to allow restore the default TCP garbage behavior for keepalive processing */
export int fns_tcp_garbage_default(void);

#ifdef AUTO_IPV4_CONF

typedef void (*fns_autoip_addr_configured)(void *user_handle, u32 local_addr, u32 mask, int bNew);
typedef void (*fns_autoip_addr_conflict)(void *user_handle, u32 local_addr, u32 mask);

extern int fns_auto_ipv4_conf(char *devname, 
                       void *user_handle,
                       u32 local_addr,
                       fns_autoip_addr_configured addr_configured,
                       fns_autoip_addr_conflict addr_conflict);

extern int fns_auto_ipv4_unconf( char *devname );
#endif

#ifdef RARP_CLIENT


/**************** New RARP API ***************************/

#define RARP_SUCCESS  1
#define RARP_TIMEOUT  2
#define RARP_FAIL     3  /* Probably only occurs if out of memory */

/* NOTE:  The IP address is passed to the callback function in NETWORK order.
          This makes it directly suitable for use with ll_config().
*/

typedef void (*fns_rarp_callback)(void *user_handle, int status, u32 ipaddr, u32 classmask);

/* New RARP API which is asynchronous.  It calls a callback when either it
   has acquired an address or it has timed out.  NOTE:  it does *NOT* automatically
   assign the address to the interface.  That is the responsibility of
   the application callback.  The initial retransmit interval, rexmt_int, is in SECONDS.
   It is backed off exponentially (doubled) each retransmission.  Furthermore, the
   actuall retransmit time after doubling is randomized by a small pseudo-random
   value to avoid collisions when many boxes are powered on at once.
*/

extern  int fns_rarp_ask(char *devname, void *user_handle, u8 retx_int, fns_rarp_callback cb);


/* If the fns_rarp_ask function was called to request an address using RARP, then
   calling fns_rarp_stop_client will shutoff the timeout and ignore any RARP reply
   that is received thereafter.  Note:  no error results if called and RARP
   is not in process.
*/
extern int fns_rarp_stop_client(char *devname);

#endif /* RARP_CLIENT */

#ifdef PING_ARP


/****************** Ping ARP API ************************/

/* Callback function supplied by user.  Note that callback includes the IP address
   of the machine (server) that sent the ping.
*/
typedef void (*fns_ping_arp_callback)(void *user_handle, u32 ipaddr, u32 classmask, u32 servaddr );

extern int fns_ping_arp_start(char *devname, void *user_handle, fns_ping_arp_callback cb);

extern int fns_ping_arp_stop(char *devname);

#endif /* PING_ARP */
#ifdef __cplusplus
}
#endif
#endif /* _FPUBLIC_ */


