/* Copyright (c) 1995-1999 NEC USA, Inc.  All rights reserved.               */
/*                                                                           */
/* The redistribution, use and modification in source or binary forms of     */
/* this software is subject to the conditions set forth in the copyright     */
/* document ("Copyright") included with this distribution.                   */

/*
 * $Id: defs.h,v 1.25.4.5 1999/02/03 22:34:49 steve Exp $
 */

#ifndef DEFS_H
#define DEFS_H

#define SOCKS5_VERSION_NAME "Socks5 v1.0r10 "

#ifndef P
#if defined(__STDC__) || defined(HAVE_FUNC_PROTOTYPE)
#define P(x) x
#else
#define P(X) ()
#endif
#endif

#if defined(__SVR4) && !defined(__svr4__)
#define __svr4__
#endif

#if defined(sun) && defined(__svr4__)
#define CONST
#else
#define CONST const
#endif

#ifndef MIN
#define MIN(a, b) (((a) < (b))?(a):(b))
#endif

#ifndef MAX
#define MAX(a, b) (((a) > (b))?(a):(b))
#endif

#if F_SETOWN
#define recv_sigio(x) fcntl((x), F_SETOWN, getpid())
#elif defined FIOSETOWN
#define recv_sigio(x) do { int pid = getpid(); ioctl((x), FIOSETOWN, &pid);   } while (0)
#elif defined FIOSSAIOOWN
#define recv_sigio(x) do { int pid = getpid(); ioctl((x), FIOSSAIOOWN, &pid); } while (0)
#else 
#define recv_sigio(x) /* What should your OS do...??? */
#endif

#ifndef HAVE_STRERROR
#ifdef  HAVE_SYSERRLIST
extern int   sys_nerr;
extern char *sys_errlist[];
#define strerror(x) (((int)(x) < sys_nerr)?sys_errlist[(x)]:"Unknown error")
#else
#define strerror(x) "Inaccessible error string"
#define HAVE_STRERROR
#endif
#endif

#ifndef HAVE_STRDUP
static inline char *strdup(const char *s1) {
    char *s2 = malloc(strlen(s1)+1);
    if (s2) strcpy(s2,s1);
    return s2;
}
#define HAVE_STRDUP
#endif

#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif

#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif

#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif

#ifndef S_ISLNK
#define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK))
#endif

#ifndef IORETTYPE 
#define IORETTYPE int
#endif

#ifndef IOPTRTYPE 
#define IOPTRTYPE void *
#endif

#ifndef IOLENTYPE 
#define IOLENTYPE size_t
#endif

#define ADDRCOMP(a, b) ((a)->sin_port == (b)->sin_port && (a)->sin_addr.s_addr == (b)->sin_addr.s_addr)

#ifndef MAXNAMELEN
#define MAXNAMELEN 256
#endif

#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif

#ifndef GENERICBUFSIZE
#define GENERICBUFSIZE 4096      /* How big should the flow buffer be???     */
#endif

#ifndef HAVE_IPPORT_RESERVED
#define HAVE_IPPORT_RESERVED
#define IPPORT_RESERVED 1024
#endif

#ifndef INADDR_ANY
#define INADDR_ANY 0x00000000
#endif

#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK 0x7f000001
#endif

#define SOCKS_DEF_PORT    1080 /* tcp   */

#define INVALIDPORT (u_short)-1	/* A macro for realizing an invalid port...   */
#define INVALIDADDR (u_int)-1	/* A macro for realizing an invalid address.  */

/* authentication types */
#define AUTH_NONE      0x00
#define AUTH_GSSAPI    0x01
#define AUTH_PASSWD    0x02

/* error types */
#define AUTH_OK        0
#define AUTH_FAIL      -1

/* version */
#define DIRECT		  0
#define SOCKS4_VERSION    4
#define SOCKS5_VERSION    5

/* command */
#define SOCKS_CONNECT	1
#define SOCKS_BIND	2
#define SOCKS_UDP       3
#define SOCKS_PING      0x80
#define SOCKS_TRACER    0x81
#define SOCKS_ANY       0xff

/* UDP sub-command */
#define S5UDP_USECLIENTPORT	0xc1
#define S5UDP_BIND		0xc2
#define S5UDP_GETSOCKNAME	0xc3

/* reserved */
#define S5UDP_USECTRL	0x04

/* socks 4 errors */
#define SOCKS_NOERR     0
#define SOCKS_RESULT	90
#define SOCKS_FAIL	91
#define SOCKS_NO_IDENTD	92
#define SOCKS_BAD_ID	93

/* socks 5 errors */
#define SOCKS5_NOERR       0x00
#define SOCKS5_RESULT	   0x00
#define SOCKS5_FAIL	   0x01
#define SOCKS5_AUTHORIZE   0x02
#define SOCKS5_NETUNREACH  0x03
#define SOCKS5_HOSTUNREACH 0x04
#define SOCKS5_CONNREF     0x05
#define SOCKS5_TTLEXP      0x06
#define SOCKS5_BADCMND     0x07
#define SOCKS5_BADADDR     0x08

/* flags */
#define SOCKS5_FLAG_NONAME  0x01
#define SOCKS5_FLAG_VERBOSE 0x02
#define SOCKS5_IPV4ADDR 0x01 
#define SOCKS5_HOSTNAME 0x03
#define SOCKS5_IPV6ADDR 0x04

/* socks5 offsets */
#define RP_VERSION 0
#define RP_COMMAND 1
#define RP_REPLY   1
#define RP_AUTH    1
#define RP_RESERVE 2
#define RP_FLAGS   3
#define RP_HOSTOFF 4

/* socks4 offsets */
#define SP_VERSION 0
#define SP_COMMAND 1
#define SP_PORTOFF 2
#define SP_HOSTOFF 4
#define SP_USEROFF 8

#define MINHDRSIZE   10
#define IPV4HDRSIZE  10
#define IPV6HDRSIZE  22
#define MAXHDRSIZE   262
#define NAMEHDRSIZE(x) (7 + strlen((x)))

#define UDP_MAX_PAYLOAD ((2<<16) - 18 - 8) /* 8 = sizeof(struct udp), 18  = sizeof(struct ip) */

#ifdef HAVE_NETINET6_IN6_H
#define HOSTLEN(x)  (((x)[RP_FLAGS] == SOCKS5_HOSTNAME)?((x)[RP_HOSTOFF]+1): \
		    (((x)[RP_FLAGS] == SOCKS5_IPV4ADDR)?sizeof(struct in_addr):sizeof(struct in_addr6)))
#else
#define HOSTLEN(x)  (((x)[RP_FLAGS] == SOCKS5_HOSTNAME)?((x)[RP_HOSTOFF]+1):sizeof(struct in_addr))
#endif
#define HDRSIZE(x)  (RP_HOSTOFF + HOSTLEN((x)) + sizeof(u_short))

#ifdef HAVE_SHL_LOAD
#define S5LibHandle shl_t
#else
#define S5LibHandle void *
#endif

#ifdef __FreeBSD__
#define UNDERSCORE "_"
#else
#define UNDERSCORE
#endif

#endif
