mirror of
https://github.com/ogoguel/activegs-ios.git
synced 2024-12-22 00:29:17 +00:00
461 lines
11 KiB
C
461 lines
11 KiB
C
/*
|
||
ActiveGS, Copyright 2004-2016 Olivier Goguel, https://github.com/ogoguel/ActiveGS
|
||
Based on Kegs, Copyright 2004 Kent Dickey, https://kegs.sourceforge.net
|
||
This code is covered by the GNU GPL licence
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#if defined(ACTIVEGS_ANDROID)
|
||
// not tester yet!
|
||
#define NO_MARINETTI_SUPPORT
|
||
#endif
|
||
|
||
#ifndef NO_MARINETTI_SUPPORT
|
||
#ifdef WIN32
|
||
#include <winsock2.h>
|
||
#include <ws2tcpip.h>
|
||
#include <stdio.h>
|
||
#pragma comment(lib, "Ws2_32.lib")
|
||
#else
|
||
#include <sys/types.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/in.h>
|
||
#include <netinet/in_systm.h>
|
||
#include <netinet/ip.h>
|
||
#include <netinet/tcp.h>
|
||
#include <arpa/inet.h>
|
||
#endif
|
||
#endif // NO MARINETTI SUPPORT
|
||
|
||
|
||
|
||
#define MAX_TCP_QUEUE 32
|
||
#define MAX_ETH_QUEUE 64
|
||
|
||
#define MAX_TCP_SIZE 2048
|
||
#define MAX_UDP_SIZE 2048
|
||
#define MTU 1500
|
||
|
||
|
||
#define TCPIP_ERR_NO_DEVICE 1 // No network device found
|
||
#define TCPIP_ERR_NO_CONNECTION 2 // Unable to connect to network device
|
||
#define TCPIP_ERR_STARTUP_FAILED 3 // Unable to initiate network access
|
||
#define TCPIP_ERR_UNSUPPORTED 4 // An unsupported operation was attempted
|
||
#define TCPIP_ERR_MEMORY 5 // Unable to allocate buffer memory
|
||
#define TCPIP_ERR_SEND 6 // Error sending packet
|
||
|
||
extern void marinetti_init();
|
||
extern void marinetti_shutdown();
|
||
|
||
|
||
#ifndef NO_MARINETTI_SUPPORT
|
||
|
||
// helpers
|
||
|
||
typedef unsigned short u16;
|
||
typedef unsigned long u32;
|
||
|
||
|
||
#pragma pack(push)
|
||
#pragma pack(1)
|
||
|
||
#ifdef WIN32
|
||
#define SockLastError() WSAGetLastError()
|
||
#define SockClose(X) if (X>=0) { closesocket(X); printf("\n sock %d closed\n",X); X=-1; }
|
||
#else
|
||
#define SockLastError() -1
|
||
#define SockClose(X) if (X>=0) { close(X); X=-1; }
|
||
#define SOCKET_ERROR -1
|
||
#endif
|
||
|
||
|
||
#define _LOG(...) do {} while(0)
|
||
#ifndef _DEBUG
|
||
#undef printf
|
||
#define printf(...) do {} while(0)
|
||
#endif
|
||
|
||
enum enum_response_type
|
||
{
|
||
RT_NA=0,
|
||
RT_UDP=100,
|
||
RT_ARP=101,
|
||
RT_DHCP=102,
|
||
RT_DNS=103,
|
||
RT_TCP=104
|
||
};
|
||
|
||
// ETH/IP/UDP/ARP/TCP/DHCP HEADER
|
||
|
||
#define dhcpdiscover 1
|
||
#define dhcpoffer 2
|
||
#define dhcprequest 3
|
||
#define dhcpdecline 4
|
||
#define dhcppack 5
|
||
#define dhcpnack 6
|
||
#define dhcprelease 7
|
||
#define dhcpinform 8
|
||
|
||
// DNS STRUCT
|
||
typedef in_addr IP_STRUCT;
|
||
|
||
#ifdef WIN32
|
||
#define GET_INT_FROM_IP(X) X.S_un.S_addr
|
||
#else
|
||
#define GET_INT_FROM_IP(X) X.s_addr
|
||
#endif
|
||
|
||
struct MAC_STRUCT
|
||
{
|
||
|
||
byte addr[6]; MAC_STRUCT& operator=(const byte* _ptr)
|
||
{
|
||
memcpy(addr,_ptr,6);
|
||
return *this;
|
||
};
|
||
|
||
void SetFromIP(IP_STRUCT _ip)
|
||
{
|
||
memset(addr,0x88,6);
|
||
*(int*)&addr[0]=GET_INT_FROM_IP(_ip);
|
||
};
|
||
} ;
|
||
|
||
|
||
#define IP_SET(i,d,c,b,a) GET_INT_FROM_IP(i) = ((a << 24) + (b << 16) + (c << 8) + d)
|
||
#define MAC_SET(m,a,b,c,d,e,f) m.addr[0]=a;m.addr[1]=b;m.addr[2]=c;m.addr[3]=d;m.addr[4]=e;m.addr[5]=f;
|
||
|
||
|
||
typedef struct
|
||
{
|
||
MAC_STRUCT dest_mac;
|
||
MAC_STRUCT source_mac;
|
||
unsigned short int type;
|
||
} ETH_HEADER;
|
||
|
||
|
||
#define FLAG_MF 0x2000
|
||
#define GET_OFFSET(X) ((X & 0x1FFF)*8)
|
||
|
||
typedef struct
|
||
{
|
||
unsigned char ihl:4;
|
||
unsigned char ver:4;
|
||
unsigned char tos;
|
||
unsigned short int length;
|
||
unsigned short int identification;
|
||
unsigned short int flag_offset;
|
||
// unsigned short int offset:13;
|
||
unsigned char ttl;
|
||
unsigned char protocol;
|
||
unsigned short int checksum;
|
||
IP_STRUCT ucSource;
|
||
IP_STRUCT ucDestination;
|
||
} IP_HEADER;
|
||
|
||
#define DHCP_SNAME_LEN 64
|
||
#define DHCP_FILE_LEN 128
|
||
#define DHCP_FIXED_NON_UDP 236
|
||
#define DHCP_OPTION_LEN 1500
|
||
|
||
typedef struct
|
||
{
|
||
byte op; /* 0: Message opcode/type */
|
||
byte htype; /* 1: Hardware addr type (net/if_types.h) */
|
||
byte hlen; /* 2: Hardware addr length */
|
||
byte hops; /* 3: Number of relay agent hops from client */
|
||
u32 xid; /* 4: Transaction ID */
|
||
u16 secs; /* 8: Seconds since client started looking */
|
||
u16 flags; /* 10: Flag bits */
|
||
IP_STRUCT ciaddr; /* 12: Client IP address (if already in use) */
|
||
IP_STRUCT yiaddr; /* 16: Client IP address */
|
||
IP_STRUCT siaddr; /* 18: IP address of next server to talk to */
|
||
IP_STRUCT giaddr; /* 20: DHCP relay agent IP address */
|
||
unsigned char chaddr [16]; /* 24: Client hardware address */
|
||
char sname [DHCP_SNAME_LEN]; /* 40: Server name */
|
||
char file [DHCP_FILE_LEN]; /* 104: Boot filename */
|
||
unsigned char options [DHCP_OPTION_LEN];
|
||
/* 212: Optional parameters
|
||
(actual length dependent on MTU). */
|
||
} DHCP_HEADER;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned short src_port;
|
||
unsigned short dest_port;
|
||
unsigned int seq_number;
|
||
unsigned int ack_number;
|
||
unsigned char padding1:4;
|
||
unsigned char data_offset:4;
|
||
unsigned char flags;
|
||
|
||
#define TCP_FIN (1 << 0)
|
||
#define TCP_SYN (1 << 1)
|
||
#define TCP_RST (1 << 2)
|
||
#define TCP_PSH (1 << 3)
|
||
#define TCP_ACK (1 << 4)
|
||
#define TCP_URG (1 << 5)
|
||
|
||
unsigned short window;
|
||
unsigned short checksum;
|
||
unsigned short urgent_pointer;
|
||
unsigned int options;
|
||
|
||
} TCP_HEADER;
|
||
|
||
typedef struct
|
||
{
|
||
u16 udp_src;
|
||
u16 udp_dst;
|
||
u16 udp_len;
|
||
u16 udp_chk;
|
||
} UDP_HEADER;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned short id; // identification number
|
||
unsigned char rd :1; // recursion desired
|
||
unsigned char tc :1; // truncated message
|
||
unsigned char aa :1; // authoritive answer
|
||
unsigned char opcode :4; // purpose of message
|
||
unsigned char qr :1; // query/response flag
|
||
unsigned char rcode :4; // response code
|
||
unsigned char cd :1; // checking disabled
|
||
unsigned char ad :1; // authenticated data
|
||
unsigned char z :1; // its z! reserved
|
||
unsigned char ra :1; // recursion available
|
||
unsigned short q_count; // number of question entries
|
||
unsigned short ans_count; // number of answer entries
|
||
unsigned short auth_count; // number of authority entries
|
||
unsigned short add_count; // number of resource entries
|
||
} DNS_HEADER;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned short qtype;
|
||
unsigned short qclass;
|
||
} QUESTION;
|
||
|
||
|
||
typedef struct
|
||
{
|
||
unsigned short type;
|
||
unsigned short _class;
|
||
unsigned int ttl;
|
||
unsigned short data_len;
|
||
} R_DATA;
|
||
|
||
|
||
typedef struct
|
||
{
|
||
char name[256];
|
||
R_DATA *resource;
|
||
char rdata[256];
|
||
} RES_RECORD;
|
||
|
||
typedef struct
|
||
{
|
||
char name[256];
|
||
QUESTION *ques;
|
||
} QUERY;
|
||
|
||
|
||
#define TCPIP_CMD_STARTUP 1 // Initializes the network module
|
||
#define TCPIP_CMD_GET_DATAGRAM 2 // Called by GS to get a datagram from the network
|
||
// XXXXYYYY = pointer to buffer to receive datagram
|
||
#define TCPIP_CMD_SEND_DATAGRAM 3 // Called by GS to send a datagram
|
||
// XXXXYYYY = pointer to parameters:
|
||
// LONG pointer to data
|
||
// WORD datagram length in bytes
|
||
#define TCPIP_CMD_CONNECT 4 // Connects to the network
|
||
#define TCPIP_CMD_DISCONNECT 5 // Disconnects from the network
|
||
#define TCPIP_CMD_SHUTDOWN 6 // Shuts down the network support
|
||
#define TCPIP_SET_IP_ADDRESS 7 // Pass in XXXXYYYY a pointerto the
|
||
// six byte MAC address of the LL
|
||
#define TCPIP_GETIPADDRESS 9 // returns the Macs IP Address in X and Y
|
||
// if IP Address could not be obtained will return 0
|
||
|
||
u16 ip_sum_calc(u16 len_ip_header,const byte* _buf);
|
||
u16 udp_sum_calc(u16 proto,u16 len_udp, const byte* src_addr,const byte* dest_addr, const byte* buff);
|
||
|
||
int dns_readname(const byte* reader,const byte* buffer,char outname[] );
|
||
|
||
extern IP_STRUCT client_ip_addr;
|
||
extern MAC_STRUCT client_mac_addr;
|
||
extern MAC_STRUCT gateway_mac_addr;
|
||
extern IP_STRUCT gateway_dns_addr;
|
||
extern const MAC_STRUCT broadcast_mac_addr;
|
||
extern IP_STRUCT local_ip_addr;
|
||
extern IP_STRUCT host_ip_addr;
|
||
|
||
struct tcp_queue;
|
||
|
||
enum PConnectionState
|
||
{
|
||
PCS_INITIALIZED=300,
|
||
PCS_SYNSENT,
|
||
PCS_SYNCHING,
|
||
PCS_BEINGESTABLISHED,
|
||
PCS_ESTABLISHED,
|
||
PCS_CLOSING,
|
||
PCS_CLEARINGQUEUE,
|
||
PCS_LASTACK,
|
||
PCS_CLOSED
|
||
};
|
||
|
||
enum PConnectionType
|
||
{
|
||
PCT_SERVER,
|
||
PCT_CLIENT,
|
||
PCT_HOST
|
||
};
|
||
|
||
struct PConnection
|
||
{
|
||
int type; // UDP, TCP, //ARP
|
||
int dest_port;
|
||
int source_port;
|
||
IP_STRUCT dest_ip;
|
||
MAC_STRUCT dest_mac;
|
||
int window;
|
||
int already_sent;
|
||
int send_seq;
|
||
int last_ack;
|
||
int state_seq;
|
||
int tcpsocket;
|
||
|
||
enum PConnectionState state;
|
||
enum PConnectionType socktype;
|
||
PConnection();
|
||
~PConnection();
|
||
void Reset();
|
||
|
||
tcp_queue* sendtcppacket(int _flags, int len, byte* data);
|
||
int sendudppacket(int len,const byte* data);
|
||
|
||
};
|
||
|
||
struct ARP_HEADER
|
||
{
|
||
u16 hwaddr_format; // Ethernet, Token Ring, etc
|
||
u16 protoaddr_format; // Same as Ether Type field
|
||
byte hwaddr_length; // Lenght of hardware address
|
||
byte protoaddr_length; // Length of protocol address
|
||
u16 opcode; // Request or Response
|
||
MAC_STRUCT src_hwaddr;
|
||
IP_STRUCT src_protoaddr;
|
||
MAC_STRUCT dst_hwaddr;
|
||
IP_STRUCT dst_protoaddr;
|
||
};
|
||
|
||
|
||
#define MAX_TCP_CONNECTION 100
|
||
extern PConnection PConnections[MAX_TCP_CONNECTION];
|
||
PConnection* init_connection( enum PConnectionType _socktype,int _type,int _srcport,IP_STRUCT _destip, int _destport, MAC_STRUCT _destmac, int _window);
|
||
void reset_connection( enum PConnectionType _socktype,int _type, int _srcport,IP_STRUCT _destip, int _destport);
|
||
PConnection* find_connection( enum PConnectionType _socktype,int _type, int _srcport,IP_STRUCT _destip, int _destport);
|
||
|
||
|
||
enum QUEUE_STATE
|
||
{
|
||
QS_TOSEND=1000,
|
||
QS_TOSENDANDRETRY,
|
||
QS_SENT,
|
||
QS_WAITACK,
|
||
QS_IDLE,
|
||
QS_FRAGMENT
|
||
};
|
||
|
||
struct eth_queue
|
||
{
|
||
// ne rien avoir ici!
|
||
struct
|
||
{
|
||
ETH_HEADER eth;
|
||
union
|
||
{
|
||
ARP_HEADER arp;
|
||
IP_HEADER ip;
|
||
byte padding[MTU];
|
||
|
||
};
|
||
};
|
||
|
||
int queuelen;
|
||
|
||
void print();
|
||
};
|
||
|
||
#define ETH_MAX_SIZE ((MTU - sizeof(ETH_HEADER) - sizeof(IP_HEADER))&~7)
|
||
|
||
struct tcp_queue
|
||
{
|
||
int queuelen;
|
||
int queueseq;
|
||
double timeout;
|
||
int tcplen; // taille des donn<6E>e tcp
|
||
int iplen; // taille du packet ip d<>fragment<6E>
|
||
enum QUEUE_STATE state;
|
||
PConnection* connection;
|
||
struct
|
||
{
|
||
ETH_HEADER eth;
|
||
IP_HEADER ip;
|
||
union
|
||
{
|
||
UDP_HEADER udp;
|
||
TCP_HEADER tcp;
|
||
byte padding[16384];
|
||
};
|
||
};
|
||
void print();
|
||
void Reset() { state=QS_IDLE; };
|
||
int isDNS()
|
||
{
|
||
return (GET_INT_FROM_IP(gateway_dns_addr)== GET_INT_FROM_IP(this->ip.ucDestination))
|
||
|| (GET_INT_FROM_IP(gateway_dns_addr)== GET_INT_FROM_IP(this->ip.ucSource)) ;
|
||
};
|
||
|
||
int isDHCP()
|
||
{
|
||
if (
|
||
ip.protocol == 17 // UDP
|
||
&& ntohs(udp.udp_dst) == 67
|
||
&& !memcmp(eth.dest_mac.addr, broadcast_mac_addr.addr,6)
|
||
)
|
||
return 1;
|
||
else
|
||
return 0;
|
||
};
|
||
int check_tcp();
|
||
};
|
||
|
||
eth_queue* findETHQueue();
|
||
extern eth_queue ethqueues[MAX_ETH_QUEUE];
|
||
tcp_queue* findTCPQueue();
|
||
tcp_queue* findTCPQueueByFragment(eth_queue* q);
|
||
extern tcp_queue tcpqueues[MAX_TCP_QUEUE];
|
||
|
||
|
||
|
||
void print_ip(const IP_STRUCT p);
|
||
void print_mac(const MAC_STRUCT mac);
|
||
void print_dns(const byte* _ptr);
|
||
void print_udp(const UDP_HEADER *p);
|
||
void print_arp(const ARP_HEADER * p);
|
||
void print_tcp(TCP_HEADER* p);
|
||
void print_dhcp(const byte *);
|
||
void print_ip_packet( const IP_HEADER* _header);
|
||
|
||
int init_server(void);
|
||
void server_loop(void);
|
||
|
||
|
||
int add_fragment(eth_queue* p);
|
||
int process_unfragmented(tcp_queue* p);
|
||
void reset_fragments();
|
||
|
||
#pragma pack(pop)
|
||
#endif
|