mirror of
https://github.com/ogoguel/activegs-ios.git
synced 2025-01-17 17:30:28 +00:00
740 lines
16 KiB
C++
740 lines
16 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
|
|||
|
*/
|
|||
|
|
|||
|
#include "defc.h"
|
|||
|
#include "sim65816.h"
|
|||
|
#include "marinetti.h"
|
|||
|
|
|||
|
#ifndef NO_MARINETTI_SUPPORT
|
|||
|
|
|||
|
const MAC_STRUCT broadcast_mac_addr={ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };
|
|||
|
|
|||
|
|
|||
|
void print_ip(IP_STRUCT _p)
|
|||
|
{
|
|||
|
#ifdef _DEBUG
|
|||
|
const byte*p = (const byte*)&_p;
|
|||
|
printf("%3d.%3d.%3d.%3d",p[0],p[1],p[2],p[3]);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
void print_mac(MAC_STRUCT _p)
|
|||
|
{
|
|||
|
#ifdef _DEBUG
|
|||
|
const byte*mac = (const byte*)&_p;
|
|||
|
printf("%0X.%0X.%0X.%0X.%0X.%0X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
int dns_readname(const byte* _reader,const byte* _buffer,char _outname[] )
|
|||
|
{
|
|||
|
unsigned char *name = (unsigned char*)_outname;
|
|||
|
const unsigned char *reader = (const unsigned char*)_reader;
|
|||
|
const unsigned char *buffer = (const unsigned char*)_buffer;
|
|||
|
|
|||
|
unsigned int p=0,jumped=0,offset;
|
|||
|
int i , j;
|
|||
|
|
|||
|
int count = 1;
|
|||
|
|
|||
|
name[0]='\0';
|
|||
|
|
|||
|
//read the names in 3www6google3com format
|
|||
|
while(*reader!=0)
|
|||
|
{
|
|||
|
if(*reader>=192)
|
|||
|
{
|
|||
|
offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000 ;)
|
|||
|
reader = buffer + offset - 1;
|
|||
|
jumped = 1; //we have jumped to another location so counting wont go up!
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
name[p++]=*reader;
|
|||
|
}
|
|||
|
|
|||
|
reader=reader+1;
|
|||
|
|
|||
|
if(jumped==0) count = count + 1; //if we havent jumped to another location then we can count up
|
|||
|
}
|
|||
|
|
|||
|
name[p]='\0'; //string complete
|
|||
|
if(jumped==1)
|
|||
|
{
|
|||
|
count = count + 1; //number of steps we actually moved forward in the packet
|
|||
|
}
|
|||
|
|
|||
|
//now convert 3www6google3com0 to www.google.com
|
|||
|
for(i=0;i<(int)strlen((const char*)name);i++)
|
|||
|
{
|
|||
|
p=name[i];
|
|||
|
for(j=0;j<(int)p;j++)
|
|||
|
{
|
|||
|
name[i]=name[i+1];
|
|||
|
i=i+1;
|
|||
|
}
|
|||
|
name[i]='.';
|
|||
|
}
|
|||
|
|
|||
|
name[i-1]='\0'; //remove the last dot
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
u16 ip_sum_calc(u16 len_ip_header,const byte* _buf)
|
|||
|
{
|
|||
|
u16 word16;
|
|||
|
u32 sum=0;
|
|||
|
u16 i;
|
|||
|
|
|||
|
const byte* buff = _buf;
|
|||
|
for (i=0;i<len_ip_header;i=i+2)
|
|||
|
{
|
|||
|
word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
|
|||
|
sum = sum + (u32) word16;
|
|||
|
}
|
|||
|
while (sum>>16)
|
|||
|
sum = (sum & 0xFFFF)+(sum >> 16);
|
|||
|
|
|||
|
sum = ~sum;
|
|||
|
return ((u16) sum);
|
|||
|
}
|
|||
|
|
|||
|
u16 udp_sum_calc(u16 _proto,u16 len_udp, const byte* src_addr,const byte* dest_addr, const byte* buff)
|
|||
|
{
|
|||
|
u16 word16;
|
|||
|
u32 sum=0;
|
|||
|
|
|||
|
int i;
|
|||
|
for (i=0;i<len_udp;i=i+2)
|
|||
|
{
|
|||
|
word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
|
|||
|
sum = sum + (u32)word16;
|
|||
|
}
|
|||
|
|
|||
|
while (sum>>16)
|
|||
|
sum = (sum & 0xFFFF)+(sum >> 16);
|
|||
|
|
|||
|
for (i=0;i<4;i=i+2)
|
|||
|
{
|
|||
|
word16 =((src_addr[i]<<8)&0xFF00)+(src_addr[i+1]&0xFF);
|
|||
|
sum=sum+ (u32)word16;
|
|||
|
word16 =((dest_addr[i]<<8)&0xFF00)+(dest_addr[i+1]&0xFF);
|
|||
|
sum=sum+(u32)word16;
|
|||
|
}
|
|||
|
|
|||
|
sum = sum + _proto + len_udp;
|
|||
|
while (sum>>16)
|
|||
|
sum = (sum & 0xFFFF)+(sum >> 16);
|
|||
|
sum = ~sum;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
return ((u16) sum);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void print_dns(const byte* _ptr)
|
|||
|
{
|
|||
|
DNS_HEADER* dns = (DNS_HEADER*)_ptr;
|
|||
|
|
|||
|
char namestr [256];
|
|||
|
const byte* name = (const byte*)(_ptr+sizeof(DNS_HEADER));
|
|||
|
dns_readname(name,_ptr, namestr);
|
|||
|
|
|||
|
#ifdef _DEBUG
|
|||
|
QUESTION* q = (QUESTION*)(_ptr+strlen((const char*)name)+1+sizeof(DNS_HEADER));
|
|||
|
|
|||
|
printf("nb_question:%d nb_answer;%d\n", ntohs(dns->q_count), ntohs(dns->ans_count));
|
|||
|
printf("dns query : %s\n",namestr);
|
|||
|
printf("question type:%d class: %d\n", ntohs(q->qtype), ntohs(q->qclass));
|
|||
|
#endif
|
|||
|
RES_RECORD answers[20];//s,auth[20],addit[20]; //the replies from the DNS server
|
|||
|
|
|||
|
//reading answers
|
|||
|
int stop=0;
|
|||
|
int i;
|
|||
|
byte* reader = (byte*)(_ptr+strlen((const char*)name)+1+sizeof(DNS_HEADER)+sizeof(QUESTION));
|
|||
|
byte* buf = (byte*)_ptr;
|
|||
|
|
|||
|
for(i=0;i<ntohs(dns->ans_count);i++)
|
|||
|
{
|
|||
|
stop = dns_readname(reader,buf,answers[i].name);
|
|||
|
reader+=stop;
|
|||
|
answers[i].resource=(R_DATA*)(reader);
|
|||
|
reader+=sizeof(R_DATA);
|
|||
|
if(ntohs(answers[i].resource->type)==1)
|
|||
|
{
|
|||
|
for(int j=0;j<ntohs(answers[i].resource->data_len);j++)
|
|||
|
answers[i].rdata[j]=reader[j];
|
|||
|
answers[i].rdata[ntohs(answers[i].resource->data_len)]=0;
|
|||
|
reader+=ntohs(answers[i].resource->data_len);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
stop = dns_readname(reader,buf,answers[i].rdata);
|
|||
|
reader+=stop;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for(i=0;i<ntohs(dns->ans_count);i++)
|
|||
|
{
|
|||
|
printf(" ### [DNS] Reply -- Name : %s ",answers[i].name);
|
|||
|
|
|||
|
if(ntohs(answers[i].resource->type)==1) //IPv4 address
|
|||
|
{
|
|||
|
long *p;
|
|||
|
p=(long*)answers[i].rdata;
|
|||
|
sockaddr_in a;
|
|||
|
a.sin_addr.s_addr=(*p); //working without ntohl
|
|||
|
printf("has IPv4 address : %s",inet_ntoa(a.sin_addr));
|
|||
|
}
|
|||
|
if(ntohs(answers[i].resource->type)==5) //Canonical name for an alias
|
|||
|
{
|
|||
|
printf("has alias name : %s",answers[i].rdata);
|
|||
|
}
|
|||
|
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
|
|||
|
if (i==0)
|
|||
|
printf(" ### [DNS] Query -- %s",namestr);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void print_udp(const UDP_HEADER *p)
|
|||
|
{
|
|||
|
printf(" ### [UDP] ");
|
|||
|
printf("len:%d, src: %d, dest %d ",ntohs(p->udp_len),ntohs(p->udp_src),ntohs(p->udp_dst));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void print_arp(const ARP_HEADER * p)
|
|||
|
{
|
|||
|
#ifdef DEBUG_ARP
|
|||
|
int arp_type = ntohs(p->opcode);
|
|||
|
printf("[ARP] -- type %d, ",arp_type);
|
|||
|
printf(", src:");
|
|||
|
print_ip(p->src_protoaddr);
|
|||
|
printf("/");
|
|||
|
print_mac(p->src_hwaddr);
|
|||
|
printf(", dest:");
|
|||
|
print_ip(p->dst_protoaddr);
|
|||
|
printf("/");
|
|||
|
print_mac(p->dst_hwaddr);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
void print_tcp(TCP_HEADER* p)
|
|||
|
{
|
|||
|
|
|||
|
#ifdef _DEBUG
|
|||
|
printf(" ### [TCP]");
|
|||
|
printf(" src_port:%d dst_port:%d",ntohs(p->src_port),ntohs(p->dest_port));
|
|||
|
printf(" s:%x",ntohl(p->seq_number));
|
|||
|
|
|||
|
if (p->flags & TCP_SYN)
|
|||
|
printf(" SYN");
|
|||
|
if (p->flags & TCP_ACK)
|
|||
|
{
|
|||
|
printf(" ACK");
|
|||
|
printf("%x ",ntohl(p->ack_number));
|
|||
|
}
|
|||
|
if (p->flags & TCP_RST)
|
|||
|
printf(" RST");
|
|||
|
if (p->flags & TCP_FIN)
|
|||
|
printf(" FIN");
|
|||
|
if (p->flags & TCP_PSH)
|
|||
|
printf(" PSH");
|
|||
|
if (p->flags & TCP_URG)
|
|||
|
printf(" URG");
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int tcp_queue::check_tcp()
|
|||
|
{
|
|||
|
TCP_HEADER* p = &this->tcp;
|
|||
|
|
|||
|
int len = this->iplen;
|
|||
|
|
|||
|
u16 chk = udp_sum_calc(6,len,(const byte*)&GET_INT_FROM_IP(this->ip.ucDestination),(const byte*)&GET_INT_FROM_IP(this->ip.ucSource),(const byte*)p);
|
|||
|
if (chk!=0 && p->checksum)
|
|||
|
{
|
|||
|
printf("tcp checksum errror!");
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void print_ip_packet(const IP_HEADER* p)
|
|||
|
{
|
|||
|
#ifdef DEBUG_IP
|
|||
|
int l =ntohs(p->length);
|
|||
|
printf("[IP] -- len:%3d", l);
|
|||
|
printf(" src_ip:");
|
|||
|
print_ip(p->ucSource);
|
|||
|
printf(" dest_ip:");
|
|||
|
print_ip(p->ucDestination);
|
|||
|
|
|||
|
short unsigned int flag_offset = ntohs(p->flag_offset);
|
|||
|
if (flag_offset & FLAG_MG)
|
|||
|
printf(" MF");
|
|||
|
printf("\n");
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
PConnection::PConnection()
|
|||
|
{
|
|||
|
memset(this,0,sizeof(PConnection));
|
|||
|
tcpsocket=-1;
|
|||
|
}
|
|||
|
|
|||
|
void PConnection::Reset()
|
|||
|
{
|
|||
|
// regarde si il y a encore des donn<6E>es <20> envoyer pour cette connection
|
|||
|
|
|||
|
for(int q=0;q<MAX_TCP_QUEUE;q++)
|
|||
|
{
|
|||
|
if (tcpqueues[q].state != QS_IDLE && tcpqueues[q].connection == this )
|
|||
|
{
|
|||
|
printf("*** reset queue : %x ***\n",tcpqueues[q].queueseq);
|
|||
|
tcpqueues[q].state = QS_IDLE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
SockClose(tcpsocket);
|
|||
|
state = PCS_CLOSED;
|
|||
|
}
|
|||
|
|
|||
|
PConnection::~PConnection()
|
|||
|
{
|
|||
|
Reset();
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
PConnection* init_connection(enum PConnectionType _socktype,int _type, int _srcport,IP_STRUCT _destip, int _destport, MAC_STRUCT _destmac, int _window)
|
|||
|
{
|
|||
|
if (_type != RT_TCP && _type != RT_UDP)
|
|||
|
{
|
|||
|
printf("type mismatch\n");
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
PConnection* p = find_connection(_socktype,_type,_srcport,_destip,_destport);
|
|||
|
if (p)
|
|||
|
{
|
|||
|
if (p->tcpsocket>0)
|
|||
|
return p;
|
|||
|
}
|
|||
|
else
|
|||
|
for(int tcpindex=0;tcpindex<MAX_TCP_CONNECTION;tcpindex++)
|
|||
|
{
|
|||
|
if (PConnections[tcpindex].tcpsocket ==-1)
|
|||
|
{
|
|||
|
p = &PConnections[tcpindex];
|
|||
|
p->source_port = _srcport;
|
|||
|
p->dest_port = _destport;
|
|||
|
p->dest_ip = _destip;
|
|||
|
p->dest_mac = _destmac;
|
|||
|
p->window = _window;
|
|||
|
p->already_sent = 0;
|
|||
|
p->type = _type;
|
|||
|
p->socktype = _socktype;
|
|||
|
p->state=PCS_CLOSED;
|
|||
|
|
|||
|
static int la = 0x300;
|
|||
|
|
|||
|
p->last_ack = la;
|
|||
|
p->send_seq = p-> last_ack;
|
|||
|
la += 0x010000;
|
|||
|
|
|||
|
printf("\nconnection created ");
|
|||
|
print_ip(_destip);
|
|||
|
printf("\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (p==NULL)
|
|||
|
{
|
|||
|
printf("\n *** too many open connections ****\n");
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if (_socktype == PCT_CLIENT)
|
|||
|
{
|
|||
|
p->tcpsocket = _window;
|
|||
|
p->window = 16384;
|
|||
|
p->state=PCS_SYNSENT;
|
|||
|
p->state_seq = p->send_seq;
|
|||
|
p->sendtcppacket(TCP_SYN,0,NULL);
|
|||
|
|
|||
|
return p;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (_type==RT_TCP) // TCP
|
|||
|
{
|
|||
|
p->tcpsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|||
|
if (p->tcpsocket < 0)
|
|||
|
{
|
|||
|
printf("cannot create socket\n");
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
// envoie la commande
|
|||
|
struct sockaddr_in server;
|
|||
|
server.sin_family = AF_INET;
|
|||
|
if (GET_INT_FROM_IP(_destip)==GET_INT_FROM_IP(host_ip_addr))
|
|||
|
server.sin_addr = local_ip_addr; // host loop back
|
|||
|
else
|
|||
|
server.sin_addr = _destip;
|
|||
|
server.sin_port = htons( _destport );
|
|||
|
memset(&(server.sin_zero),0,8);
|
|||
|
|
|||
|
int err = connect(p->tcpsocket,(struct sockaddr *) &server,sizeof(server) );
|
|||
|
if (err < 0)
|
|||
|
{
|
|||
|
printf("connect send failed with err:%d\n",SockLastError());
|
|||
|
p->Reset();
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
p->state=PCS_INITIALIZED;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// udp
|
|||
|
p->tcpsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|||
|
if (p->tcpsocket < 0)
|
|||
|
{
|
|||
|
printf("cannot open udp socket\n");
|
|||
|
p->Reset();
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
p->state=PCS_INITIALIZED;
|
|||
|
}
|
|||
|
return p;
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
int PConnection::sendudppacket(int _len, const byte* _data)
|
|||
|
{
|
|||
|
tcp_queue* packet = findTCPQueue();
|
|||
|
if (!packet) return 0;
|
|||
|
|
|||
|
// UDP
|
|||
|
int udp_len = sizeof(UDP_HEADER)+_len;
|
|||
|
packet->udp.udp_len = htons(udp_len);
|
|||
|
packet->udp.udp_dst = htons(source_port); // inverse
|
|||
|
packet->udp.udp_src = htons(dest_port);
|
|||
|
memcpy((byte*)&packet->udp+sizeof(UDP_HEADER),_data,_len);
|
|||
|
u16 chk = udp_sum_calc(17,udp_len,(const byte*)&dest_ip,(const byte*)&client_ip_addr,(const byte*)&packet->udp);
|
|||
|
packet->udp.udp_chk = htons(chk);
|
|||
|
|
|||
|
|
|||
|
// IP
|
|||
|
packet->ip.ucSource = dest_ip;
|
|||
|
packet->ip.ucDestination = client_ip_addr;
|
|||
|
packet->ip.protocol = 17; // udp
|
|||
|
packet->ip.ver = 4;
|
|||
|
packet->ip.ihl = 5;
|
|||
|
packet->ip.ttl = 64;
|
|||
|
|
|||
|
|
|||
|
int iplen = sizeof(IP_HEADER) + udp_len ;
|
|||
|
packet->ip.length = htons(iplen);
|
|||
|
u16 chkip= ip_sum_calc(sizeof(IP_HEADER),(const byte*)&packet->ip);
|
|||
|
packet->ip.checksum = htons(chkip);
|
|||
|
|
|||
|
// ETH
|
|||
|
packet->eth.dest_mac = client_mac_addr;
|
|||
|
packet->eth.source_mac = dest_mac;
|
|||
|
packet->eth.type = htons(0x0800); //IP
|
|||
|
|
|||
|
int eth_len = iplen+sizeof(ETH_HEADER);
|
|||
|
packet->queuelen = eth_len ;
|
|||
|
packet->iplen = udp_len;
|
|||
|
packet->state = QS_TOSEND;
|
|||
|
return eth_len;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
tcp_queue* PConnection::sendtcppacket(int _flags,int _len, byte* _data)
|
|||
|
{
|
|||
|
|
|||
|
tcp_queue* packet = findTCPQueue();
|
|||
|
if (!packet) return 0;
|
|||
|
|
|||
|
// TCP
|
|||
|
const int offset = 5;
|
|||
|
int tcp_header_len = offset*4;
|
|||
|
int tcp_len = tcp_header_len + _len;
|
|||
|
|
|||
|
packet->tcp.flags = _flags ;
|
|||
|
packet->tcp.ack_number = htonl(last_ack);
|
|||
|
|
|||
|
packet->tcp.seq_number = htonl (send_seq );
|
|||
|
packet->tcp.window = htons(16384);
|
|||
|
packet->tcp.data_offset = offset;
|
|||
|
packet->tcp.dest_port = htons(source_port); // inverse
|
|||
|
packet->tcp.src_port = htons(dest_port);
|
|||
|
memcpy((byte*)&packet->tcp+tcp_header_len,_data,_len);
|
|||
|
|
|||
|
u16 chk = udp_sum_calc(6,tcp_len,(const byte*)&dest_ip,(const byte*)&client_ip_addr,(const byte*)&packet->tcp);
|
|||
|
packet->tcp.checksum = htons(chk);
|
|||
|
|
|||
|
// IP
|
|||
|
packet->ip.ucSource = dest_ip;
|
|||
|
packet->ip.ucDestination = client_ip_addr;
|
|||
|
packet->ip.protocol = 6;
|
|||
|
packet->ip.ver = 4;
|
|||
|
packet->ip.ihl = 5;
|
|||
|
packet->ip.ttl = 64;
|
|||
|
|
|||
|
|
|||
|
int iplen = sizeof(IP_HEADER) + tcp_len ;
|
|||
|
packet->ip.length = htons(iplen);
|
|||
|
u16 chkip= ip_sum_calc(sizeof(IP_HEADER),(const byte*)&packet->ip);
|
|||
|
packet->ip.checksum = htons(chkip);
|
|||
|
|
|||
|
// ETH
|
|||
|
packet->eth.dest_mac = client_mac_addr;
|
|||
|
packet->eth.source_mac = dest_mac;
|
|||
|
packet->eth.type = htons(0x0800);
|
|||
|
|
|||
|
int eth_len = iplen+sizeof(ETH_HEADER);
|
|||
|
packet->queuelen = eth_len ;
|
|||
|
packet->queueseq = send_seq+_len;
|
|||
|
packet->state = QS_TOSENDANDRETRY;
|
|||
|
packet->connection = this;
|
|||
|
|
|||
|
packet->tcplen = _len;
|
|||
|
packet->iplen = tcp_len;
|
|||
|
send_seq+=_len;
|
|||
|
already_sent += _len;
|
|||
|
|
|||
|
if (already_sent > window)
|
|||
|
{
|
|||
|
printf("****window error****\n");
|
|||
|
}
|
|||
|
return packet; // nb d'octect envoy<6F>s
|
|||
|
}
|
|||
|
|
|||
|
PConnection* find_connection(enum PConnectionType _socktype,int _type,int _srcport,IP_STRUCT _destip, int _destport)
|
|||
|
{
|
|||
|
for(int i=0;i<MAX_TCP_CONNECTION;i++)
|
|||
|
{
|
|||
|
PConnection* p = &PConnections[i];
|
|||
|
if (
|
|||
|
p
|
|||
|
&&
|
|||
|
(p->type == _type)
|
|||
|
&&
|
|||
|
(p->source_port == _srcport)
|
|||
|
&&
|
|||
|
(p->dest_port == _destport)
|
|||
|
&&
|
|||
|
(GET_INT_FROM_IP(p->dest_ip) == GET_INT_FROM_IP(_destip))
|
|||
|
&&
|
|||
|
(p->state != PCS_CLOSED)
|
|||
|
)
|
|||
|
return p;
|
|||
|
}
|
|||
|
return NULL ;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void reset_connection(enum PConnectionType _socktype, int _type,int _srcport,IP_STRUCT _destip, int _destport)
|
|||
|
{
|
|||
|
PConnection* p = find_connection(_socktype,_type,_srcport,_destip,_destport);
|
|||
|
if (p)
|
|||
|
p->Reset();
|
|||
|
else
|
|||
|
printf("ignoring reset on unknown connection\n");
|
|||
|
}
|
|||
|
|
|||
|
void eth_queue::print()
|
|||
|
{
|
|||
|
|
|||
|
#ifdef DEBUG_ETH
|
|||
|
if (this->eth.type==htons(0x0806))
|
|||
|
print_arp(&this->arp);
|
|||
|
else
|
|||
|
{
|
|||
|
print_ip_packet(&this->ip);
|
|||
|
int frag_offset = ntohs(this->ip.flag_offset);
|
|||
|
if (frag_offset & FLAG_MF)
|
|||
|
printf(" F");
|
|||
|
|
|||
|
printf("id:%x offset:%d ",this->ip.identification,GET_OFFSET(frag_offset));
|
|||
|
switch(this->ip.protocol)
|
|||
|
{
|
|||
|
case 17: // udp
|
|||
|
printf("/UDP");
|
|||
|
break;
|
|||
|
case 6: // tcp
|
|||
|
printf("/TCP");
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
printf("\n");
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void tcp_queue::print()
|
|||
|
{
|
|||
|
|
|||
|
if (this->ip.protocol == 17 ) // UDP
|
|||
|
{
|
|||
|
print_udp(&this->udp);
|
|||
|
if (isDNS())
|
|||
|
print_dns((const byte*)&this->udp+sizeof(UDP_HEADER));
|
|||
|
}
|
|||
|
else
|
|||
|
if (this->ip.protocol == 6 ) // TCP
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
print_tcp(&this->tcp);
|
|||
|
|
|||
|
int offset =this->tcp.data_offset*4;
|
|||
|
int l = ntohs(this->ip.length);
|
|||
|
int tcplen = l - sizeof(IP_HEADER) - offset;
|
|||
|
if (tcplen)
|
|||
|
printf(" [tcplen:%d]",tcplen);
|
|||
|
}
|
|||
|
else
|
|||
|
printf("unknown protocol : %d",this->ip.protocol);
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// SERVER
|
|||
|
|
|||
|
int server_sock;
|
|||
|
|
|||
|
int init_server(void)
|
|||
|
{
|
|||
|
// nb_client = 0;
|
|||
|
|
|||
|
server_sock = socket(AF_INET, SOCK_STREAM, 0);
|
|||
|
|
|||
|
if(server_sock == SOCKET_ERROR)
|
|||
|
{
|
|||
|
printf("server init failed\n");
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
struct sockaddr_in sin;
|
|||
|
|
|||
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
|||
|
sin.sin_port = htons(8080);
|
|||
|
sin.sin_family = AF_INET;
|
|||
|
|
|||
|
if(bind(server_sock,(struct sockaddr *)&sin, sizeof sin) == SOCKET_ERROR)
|
|||
|
{
|
|||
|
printf("cannot bind\n");
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
if(listen(server_sock, 0) == SOCKET_ERROR)
|
|||
|
{
|
|||
|
printf("cannot listent\n");
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
void server_loop(void)
|
|||
|
{
|
|||
|
for(int i=0;i<MAX_TCP_CONNECTION;i++)
|
|||
|
{
|
|||
|
PConnection* p = &PConnections[i];
|
|||
|
if (p->state != PCS_CLOSED) // *** ON ATTEND LA FIN DE LA CONNECTION => BCP PLUS RAPIDE??
|
|||
|
{
|
|||
|
// server not ready to accept new connection
|
|||
|
return ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int max = server_sock;
|
|||
|
|
|||
|
fd_set rdfs;
|
|||
|
|
|||
|
|
|||
|
FD_ZERO(&rdfs);
|
|||
|
|
|||
|
// add the connection socket
|
|||
|
FD_SET(server_sock, &rdfs);
|
|||
|
|
|||
|
timeval timeout;
|
|||
|
timeout.tv_usec = 1;
|
|||
|
timeout.tv_sec = 0;
|
|||
|
|
|||
|
if(select(max + 1, &rdfs, NULL, NULL, &timeout) == -1)
|
|||
|
{
|
|||
|
// printf("failed select\n");
|
|||
|
return ;
|
|||
|
}
|
|||
|
|
|||
|
if(FD_ISSET(server_sock, &rdfs))
|
|||
|
{
|
|||
|
// new client
|
|||
|
struct sockaddr csin = { 0 };
|
|||
|
socklen_t sinsize = sizeof(struct sockaddr);
|
|||
|
int csock = accept(server_sock, &csin, &sinsize);
|
|||
|
if(csock == SOCKET_ERROR)
|
|||
|
{
|
|||
|
printf("failed accept\n");;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
max = csock > max ? csock : max;
|
|||
|
|
|||
|
FD_SET(csock, &rdfs);
|
|||
|
IP_STRUCT *ip_client = (IP_STRUCT*)&csin.sa_data[0];
|
|||
|
MAC_STRUCT mac_client;
|
|||
|
mac_client.SetFromIP(*ip_client);
|
|||
|
|
|||
|
|
|||
|
for(int i=0;i<MAX_TCP_CONNECTION;i++)
|
|||
|
{
|
|||
|
PConnection* p = &PConnections[i];
|
|||
|
if (p->state == PCS_SYNSENT)
|
|||
|
{
|
|||
|
printf("\n*** INGORING %d from ",csock);
|
|||
|
print_ip(*ip_client);
|
|||
|
printf("\n");
|
|||
|
return ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
printf("\n*** connection %d from ",csock);
|
|||
|
print_ip(*ip_client);
|
|||
|
printf("\n");
|
|||
|
|
|||
|
// g<>n<EFBFBD>re un port random pour ne pallier le IPOPENUSER qui ne s base que sur les ports!
|
|||
|
static int free_port=100;
|
|||
|
init_connection(PCT_CLIENT,RT_TCP, 80, *ip_client, free_port++, mac_client,csock);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
#endif
|