Line 355... |
Line 355... |
|
|
static void IPFrameReschedule(IPFrame *frame)
|
static void IPFrameReschedule(IPFrame *frame)
|
{
|
{
|
int length;
|
int length;
|
length = frame->length - TCP_DATA;
|
length = frame->length - TCP_DATA;
|
if(frame->packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_ACK))
|
if(frame->packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN))
|
++length;
|
++length;
|
if(frame->socket == NULL || frame->socket->state == IP_UDP || length == 0 ||
|
if(frame->socket == NULL || frame->socket->state == IP_UDP || length == 0 ||
|
++frame->retryCnt > 4)
|
++frame->retryCnt > 4)
|
{
|
{
|
FrameFree(frame); //can't be ACK'ed
|
FrameFree(frame); //can't be ACK'ed
|
Line 452... |
Line 452... |
packet[TCP_CHECKSUM] = (unsigned char)(checksum >> 8);
|
packet[TCP_CHECKSUM] = (unsigned char)(checksum >> 8);
|
packet[TCP_CHECKSUM+1] = (unsigned char)checksum;
|
packet[TCP_CHECKSUM+1] = (unsigned char)checksum;
|
}
|
}
|
}
|
}
|
|
|
if(socket && (packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_ACK)))
|
length2 = length - TCP_DATA;
|
|
if(socket && (packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN)))
|
length2 = 1;
|
length2 = 1;
|
frame->socket = socket;
|
frame->socket = socket;
|
frame->timeout = 0;
|
frame->timeout = 0;
|
frame->retryCnt = 0;
|
frame->retryCnt = 0;
|
if(socket)
|
if(socket)
|
Line 466... |
Line 467... |
|
|
|
|
static void TCPSendPacket(IPSocket *socket, IPFrame *frame, int length)
|
static void TCPSendPacket(IPSocket *socket, IPFrame *frame, int length)
|
{
|
{
|
uint8 *packet = frame->packet;
|
uint8 *packet = frame->packet;
|
int flags;
|
int flags, count;
|
|
|
flags = packet[TCP_FLAGS];
|
flags = packet[TCP_FLAGS];
|
memcpy(packet, socket->headerSend, TCP_SEQ);
|
memcpy(packet, socket->headerSend, TCP_SEQ);
|
packet[TCP_FLAGS] = (uint8)flags;
|
packet[TCP_FLAGS] = (uint8)flags;
|
if(flags & TCP_FLAGS_SYN)
|
if(flags & TCP_FLAGS_SYN)
|
Line 483... |
Line 484... |
packet[TCP_SEQ+3] = (uint8)socket->seq;
|
packet[TCP_SEQ+3] = (uint8)socket->seq;
|
packet[TCP_ACK] = (uint8)(socket->ack >> 24);
|
packet[TCP_ACK] = (uint8)(socket->ack >> 24);
|
packet[TCP_ACK+1] = (uint8)(socket->ack >> 16);
|
packet[TCP_ACK+1] = (uint8)(socket->ack >> 16);
|
packet[TCP_ACK+2] = (uint8)(socket->ack >> 8);
|
packet[TCP_ACK+2] = (uint8)(socket->ack >> 8);
|
packet[TCP_ACK+3] = (uint8)socket->ack;
|
packet[TCP_ACK+3] = (uint8)socket->ack;
|
packet[TCP_WINDOW_SIZE] = 128;
|
count = FrameFreeCount - FRAME_COUNT_WINDOW;
|
packet[TCP_WINDOW_SIZE+1] = 0;
|
if(count < 1)
|
|
count = 1;
|
|
count *= 512;
|
|
packet[TCP_WINDOW_SIZE] = (uint8)(count >> 8);
|
|
packet[TCP_WINDOW_SIZE+1] = (uint8)count;
|
packet[TCP_URGENT_POINTER] = 0;
|
packet[TCP_URGENT_POINTER] = 0;
|
packet[TCP_URGENT_POINTER+1] = 0;
|
packet[TCP_URGENT_POINTER+1] = 0;
|
IPSendPacket(socket, frame, length);
|
IPSendPacket(socket, frame, length);
|
}
|
}
|
|
|
Line 635... |
Line 640... |
(packet[TCP_SEQ+2] << 8) | packet[TCP_SEQ+3];
|
(packet[TCP_SEQ+2] << 8) | packet[TCP_SEQ+3];
|
ack = (packet[TCP_ACK] << 24) | (packet[TCP_ACK+1] << 16) |
|
ack = (packet[TCP_ACK] << 24) | (packet[TCP_ACK+1] << 16) |
|
(packet[TCP_ACK+2] << 8) | packet[TCP_ACK+3];
|
(packet[TCP_ACK+2] << 8) | packet[TCP_ACK+3];
|
|
|
//Check if start of connection
|
//Check if start of connection
|
if(packet[TCP_FLAGS] & TCP_FLAGS_SYN)
|
if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) == TCP_FLAGS_SYN)
|
{
|
{
|
if(IPVerbose)
|
if(IPVerbose)
|
printf("S");
|
printf("S");
|
//Check if duplicate SYN
|
//Check if duplicate SYN
|
for(socket = SocketHead; socket; socket = socket->next)
|
for(socket = SocketHead; socket; socket = socket->next)
|
Line 661... |
Line 666... |
if(socket->state == IP_LISTEN &&
|
if(socket->state == IP_LISTEN &&
|
packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
|
packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
|
memcmp(packet+TCP_DEST_PORT, socket->headerRcv+TCP_DEST_PORT, 2) == 0)
|
memcmp(packet+TCP_DEST_PORT, socket->headerRcv+TCP_DEST_PORT, 2) == 0)
|
{
|
{
|
//Create a new socket
|
//Create a new socket
|
frameOut = IPFrameGet(0);
|
frameOut = IPFrameGet(FRAME_COUNT_SEND);
|
if(frameOut == NULL)
|
if(frameOut == NULL)
|
return 0;
|
return 0;
|
socketNew = (IPSocket*)malloc(sizeof(IPSocket));
|
socketNew = (IPSocket*)malloc(sizeof(IPSocket));
|
if(socketNew == NULL)
|
if(socketNew == NULL)
|
return 0;
|
return 0;
|
Line 731... |
Line 736... |
++socket->ack;
|
++socket->ack;
|
TCPSendPacket(socket, frameOut, TCP_DATA);
|
TCPSendPacket(socket, frameOut, TCP_DATA);
|
if(socket->state == IP_FIN_SERVER)
|
if(socket->state == IP_FIN_SERVER)
|
IPClose2(socket);
|
IPClose2(socket);
|
else
|
else
|
|
{
|
socket->state = IP_FIN_CLIENT;
|
socket->state = IP_FIN_CLIENT;
|
|
if(socket->funcPtr)
|
|
socket->funcPtr(socket);
|
|
}
|
}
|
}
|
else if(packet[TCP_FLAGS] & TCP_FLAGS_RST)
|
else if(packet[TCP_FLAGS] & TCP_FLAGS_RST)
|
{
|
{
|
if(socket->state == IP_FIN_SERVER)
|
if(socket->state == IP_FIN_SERVER)
|
IPClose2(socket);
|
IPClose2(socket);
|
else
|
else
|
|
{
|
socket->state = IP_FIN_CLIENT;
|
socket->state = IP_FIN_CLIENT;
|
|
if(socket->funcPtr)
|
|
socket->funcPtr(socket);
|
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
//TCP payload
|
|
if(packet[TCP_HEADER_LENGTH] != 0x50)
|
|
{
|
|
if(IPVerbose)
|
|
printf("length error\n");
|
|
return 0;
|
|
}
|
|
|
|
//Check if packets can be removed from retransmition list
|
//Check if packets can be removed from retransmition list
|
if(ack != socket->seqReceived)
|
if(ack != socket->seqReceived)
|
{
|
{
|
OS_MutexPend(IPMutex);
|
OS_MutexPend(IPMutex);
|
for(frame2 = FrameResendHead; frame2; )
|
for(frame2 = FrameResendHead; frame2; )
|
Line 761... |
Line 766... |
framePrev = frame2;
|
framePrev = frame2;
|
frame2 = frame2->next;
|
frame2 = frame2->next;
|
if(framePrev->socket == socket && (int)(ack - framePrev->seqEnd) >= 0)
|
if(framePrev->socket == socket && (int)(ack - framePrev->seqEnd) >= 0)
|
{
|
{
|
//Remove packet from retransmition queue
|
//Remove packet from retransmition queue
|
|
if(socket->timeout)
|
socket->timeout = SOCKET_TIMEOUT;
|
socket->timeout = SOCKET_TIMEOUT;
|
FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
|
FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
|
FrameFree(framePrev);
|
FrameFree(framePrev);
|
}
|
}
|
}
|
}
|
Line 772... |
Line 778... |
socket->seqReceived = ack;
|
socket->seqReceived = ack;
|
}
|
}
|
|
|
bytes = ip_length - (TCP_DATA - IP_VERSION_LENGTH);
|
bytes = ip_length - (TCP_DATA - IP_VERSION_LENGTH);
|
|
|
|
//Check if SYN/ACK
|
|
if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) ==
|
|
(TCP_FLAGS_SYN | TCP_FLAGS_ACK))
|
|
{
|
|
//Ack SYN/ACK
|
|
socket->ack = seq + 1;
|
|
frameOut = IPFrameGet(FRAME_COUNT_SEND);
|
|
if(frameOut)
|
|
{
|
|
frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
|
|
TCPSendPacket(socket, frameOut, TCP_DATA);
|
|
}
|
|
if(socket->funcPtr)
|
|
socket->funcPtr(socket);
|
|
return 0;
|
|
}
|
|
else if(packet[TCP_HEADER_LENGTH] != 0x50)
|
|
{
|
|
if(IPVerbose)
|
|
printf("length error\n");
|
|
return 0;
|
|
}
|
|
|
//Copy packet into socket
|
//Copy packet into socket
|
if(socket->ack == seq && bytes > 0)
|
if(socket->ack == seq && bytes > 0)
|
{
|
{
|
//Insert packet into socket linked list
|
//Insert packet into socket linked list
|
|
if(socket->timeout)
|
socket->timeout = SOCKET_TIMEOUT;
|
socket->timeout = SOCKET_TIMEOUT;
|
if(IPVerbose)
|
if(IPVerbose)
|
printf("D");
|
printf("D");
|
FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
|
FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
|
socket->ack += bytes;
|
socket->ack += bytes;
|
|
|
//Ack data
|
//Ack data
|
frameOut = IPFrameGet(FRAME_MIN_COUNT);
|
frameOut = IPFrameGet(FRAME_COUNT_SEND);
|
if(frameOut)
|
if(frameOut)
|
{
|
{
|
frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
|
frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
|
TCPSendPacket(socket, frameOut, TCP_DATA);
|
TCPSendPacket(socket, frameOut, TCP_DATA);
|
}
|
}
|
Line 797... |
Line 827... |
socket->funcPtr(socket);
|
socket->funcPtr(socket);
|
//Using frame
|
//Using frame
|
return 1;
|
return 1;
|
}
|
}
|
|
|
if(bytes > 0)
|
if(bytes)
|
{
|
{
|
//Ack with current offset since data missing
|
//Ack with current offset since data missing
|
frameOut = IPFrameGet(FRAME_MIN_COUNT);
|
frameOut = IPFrameGet(FRAME_COUNT_SEND);
|
if(frameOut)
|
if(frameOut)
|
{
|
{
|
frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
|
frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
|
TCPSendPacket(socket, frameOut, TCP_DATA);
|
TCPSendPacket(socket, frameOut, TCP_DATA);
|
}
|
}
|
Line 891... |
Line 921... |
//PING request?
|
//PING request?
|
if(packet[IP_PROTOCOL] == 1)
|
if(packet[IP_PROTOCOL] == 1)
|
{
|
{
|
if(packet[PING_TYPE] != 8)
|
if(packet[PING_TYPE] != 8)
|
return 0;
|
return 0;
|
frameOut = IPFrameGet(0);
|
frameOut = IPFrameGet(FRAME_COUNT_SEND);
|
if(frameOut == NULL)
|
if(frameOut == NULL)
|
return 0;
|
return 0;
|
packetOut = frameOut->packet;
|
packetOut = frameOut->packet;
|
EthernetCreateResponse(packetOut, packet, frameIn->length);
|
EthernetCreateResponse(packetOut, packet, frameIn->length);
|
frameOut->packet[PING_TYPE] = 0; //PING reply
|
frameOut->packet[PING_TYPE] = 0; //PING reply
|
Line 1011... |
Line 1041... |
}
|
}
|
|
|
|
|
uint8 *MyPacketGet(void)
|
uint8 *MyPacketGet(void)
|
{
|
{
|
return (uint8*)IPFrameGet(0);
|
return (uint8*)IPFrameGet(FRAME_COUNT_RCV);
|
}
|
}
|
|
|
|
|
//Set FrameSendFunction only if single threaded
|
//Set FrameSendFunction only if single threaded
|
void IPInit(IPFuncPtr FrameSendFunction)
|
void IPInit(IPFuncPtr FrameSendFunction)
|
Line 1044... |
Line 1074... |
|
|
//To open a socket for listen set IPAddress to 0
|
//To open a socket for listen set IPAddress to 0
|
IPSocket *IPOpen(IPMode_e Mode, uint32 IPAddress, uint32 Port, IPFuncPtr funcPtr)
|
IPSocket *IPOpen(IPMode_e Mode, uint32 IPAddress, uint32 Port, IPFuncPtr funcPtr)
|
{
|
{
|
IPSocket *socket;
|
IPSocket *socket;
|
uint8 *ptr;
|
uint8 *ptrSend, *ptrRcv;
|
static int portSource=0x1000;
|
IPFrame *frame;
|
|
static int portSource=0x1007;
|
(void)Mode;
|
(void)Mode;
|
(void)IPAddress;
|
(void)IPAddress;
|
|
|
socket = (IPSocket*)malloc(sizeof(IPSocket));
|
socket = (IPSocket*)malloc(sizeof(IPSocket));
|
if(socket == NULL)
|
if(socket == NULL)
|
Line 1063... |
Line 1094... |
socket->readOffset = 0;
|
socket->readOffset = 0;
|
socket->funcPtr = funcPtr;
|
socket->funcPtr = funcPtr;
|
socket->userData = 0;
|
socket->userData = 0;
|
socket->userFunc = NULL;
|
socket->userFunc = NULL;
|
socket->userPtr = NULL;
|
socket->userPtr = NULL;
|
ptr = socket->headerSend;
|
ptrSend = socket->headerSend;
|
|
ptrRcv = socket->headerRcv;
|
|
|
if(IPAddress == 0)
|
if(IPAddress == 0)
|
{
|
{
|
//Setup listing port
|
//Setup listing port
|
socket->headerRcv[TCP_DEST_PORT] = (uint8)(Port >> 8);
|
socket->headerRcv[TCP_DEST_PORT] = (uint8)(Port >> 8);
|
socket->headerRcv[TCP_DEST_PORT+1] = (uint8)Port;
|
socket->headerRcv[TCP_DEST_PORT+1] = (uint8)Port;
|
}
|
}
|
else
|
else
|
{
|
{
|
//Setup receive port
|
|
socket->headerRcv[TCP_DEST_PORT] = (uint8)(portSource >> 8);
|
|
socket->headerRcv[TCP_DEST_PORT+1] = (uint8)portSource;
|
|
|
|
//Setup sending packet
|
//Setup sending packet
|
memset(ptr, 0, UDP_LENGTH);
|
memset(ptrSend, 0, UDP_LENGTH);
|
memcpy(ptr+ETHERNET_DEST, ethernetAddressGateway, 6);
|
memset(ptrRcv, 0, UDP_LENGTH);
|
memcpy(ptr+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
|
|
ptr[ETHERNET_FRAME_TYPE] = 0x08;
|
//Setup Ethernet
|
ptr[IP_VERSION_LENGTH] = 0x45;
|
memcpy(ptrSend+ETHERNET_DEST, ethernetAddressGateway, 6);
|
ptr[IP_TIME_TO_LIVE] = 0x80;
|
memcpy(ptrSend+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
|
ptr[IP_PROTOCOL] = 0x11; //UDP
|
ptrSend[ETHERNET_FRAME_TYPE] = 0x08;
|
memcpy(ptr+IP_SOURCE, ipAddressPlasma, 4);
|
|
ptr[IP_DEST] = (uint8)(IPAddress >> 24);
|
//Setup IP
|
ptr[IP_DEST+1] = (uint8)(IPAddress >> 16);
|
ptrSend[IP_VERSION_LENGTH] = 0x45;
|
ptr[IP_DEST+2] = (uint8)(IPAddress >> 8);
|
ptrSend[IP_TIME_TO_LIVE] = 0x80;
|
ptr[IP_DEST+3] = (uint8)IPAddress;
|
|
ptr[TCP_SOURCE_PORT] = (uint8)(portSource >> 8);
|
//Setup IP addresses
|
ptr[TCP_SOURCE_PORT+1] = (uint8)portSource;
|
memcpy(ptrSend+IP_SOURCE, ipAddressPlasma, 4);
|
|
ptrSend[IP_DEST] = (uint8)(IPAddress >> 24);
|
|
ptrSend[IP_DEST+1] = (uint8)(IPAddress >> 16);
|
|
ptrSend[IP_DEST+2] = (uint8)(IPAddress >> 8);
|
|
ptrSend[IP_DEST+3] = (uint8)IPAddress;
|
|
ptrRcv[IP_SOURCE] = (uint8)(IPAddress >> 24);
|
|
ptrRcv[IP_SOURCE+1] = (uint8)(IPAddress >> 16);
|
|
ptrRcv[IP_SOURCE+2] = (uint8)(IPAddress >> 8);
|
|
ptrRcv[IP_SOURCE+3] = (uint8)IPAddress;
|
|
memcpy(ptrRcv+IP_DEST, ipAddressPlasma, 4);
|
|
|
|
//Setup ports
|
|
ptrSend[TCP_SOURCE_PORT] = (uint8)(portSource >> 8);
|
|
ptrSend[TCP_SOURCE_PORT+1] = (uint8)portSource;
|
|
ptrSend[TCP_DEST_PORT] = (uint8)(Port >> 8);
|
|
ptrSend[TCP_DEST_PORT+1] = (uint8)Port;
|
|
ptrRcv[TCP_SOURCE_PORT] = (uint8)(Port >> 8);
|
|
ptrRcv[TCP_SOURCE_PORT+1] = (uint8)Port;
|
|
ptrRcv[TCP_DEST_PORT] = (uint8)(portSource >> 8);
|
|
ptrRcv[TCP_DEST_PORT+1] = (uint8)portSource;
|
++portSource;
|
++portSource;
|
ptr[TCP_DEST_PORT] = (uint8)(Port >> 8);
|
|
ptr[TCP_DEST_PORT+1] = (uint8)Port;
|
|
}
|
}
|
|
|
if(Mode == IP_MODE_TCP)
|
if(Mode == IP_MODE_TCP)
|
{
|
{
|
socket->headerRcv[IP_PROTOCOL] = 0x06; //TCP
|
if(IPAddress)
|
ptr[IP_PROTOCOL] = 0x06;
|
socket->state = IP_TCP;
|
|
else
|
|
socket->state = IP_LISTEN;
|
|
ptrSend[IP_PROTOCOL] = 0x06; //TCP
|
|
ptrRcv[IP_PROTOCOL] = 0x06;
|
}
|
}
|
else if(Mode == IP_MODE_UDP)
|
else if(Mode == IP_MODE_UDP)
|
{
|
{
|
socket->state = IP_UDP;
|
socket->state = IP_UDP;
|
socket->headerRcv[IP_PROTOCOL] = 0x11; //UDP
|
ptrSend[IP_PROTOCOL] = 0x11; //UDP
|
ptr[IP_PROTOCOL] = 0x11;
|
ptrRcv[IP_PROTOCOL] = 0x11;
|
}
|
}
|
|
|
|
//Add socket to linked list
|
OS_MutexPend(IPMutex);
|
OS_MutexPend(IPMutex);
|
socket->next = SocketHead;
|
socket->next = SocketHead;
|
|
socket->prev = NULL;
|
|
if(SocketHead)
|
|
SocketHead->prev = socket;
|
SocketHead = socket;
|
SocketHead = socket;
|
OS_MutexPost(IPMutex);
|
OS_MutexPost(IPMutex);
|
|
|
|
if(Mode == IP_MODE_TCP && IPAddress)
|
|
{
|
|
//Send TCP SYN
|
|
frame = IPFrameGet(0);
|
|
if(frame)
|
|
{
|
|
frame->packet[TCP_FLAGS] = TCP_FLAGS_SYN;
|
|
frame->packet[TCP_DATA] = 2; //maximum segment size = 536
|
|
frame->packet[TCP_DATA+1] = 4;
|
|
frame->packet[TCP_DATA+2] = 2;
|
|
frame->packet[TCP_DATA+3] = 24;
|
|
TCPSendPacket(socket, frame, TCP_DATA+4);
|
|
++socket->seq;
|
|
}
|
|
}
|
return socket;
|
return socket;
|
}
|
}
|
|
|
|
|
void IPWriteFlush(IPSocket *Socket)
|
void IPWriteFlush(IPSocket *Socket)
|
Line 1144... |
Line 1213... |
//printf("IPWrite(0x%x, %d)", Socket, Length);
|
//printf("IPWrite(0x%x, %d)", Socket, Length);
|
while(Length)
|
while(Length)
|
{
|
{
|
if(Socket->frameSend == NULL)
|
if(Socket->frameSend == NULL)
|
{
|
{
|
Socket->frameSend = IPFrameGet(FRAME_MIN_COUNT);
|
Socket->frameSend = IPFrameGet(FRAME_COUNT_SEND);
|
Socket->sendOffset = 0;
|
Socket->sendOffset = 0;
|
}
|
}
|
frameOut = Socket->frameSend;
|
frameOut = Socket->frameSend;
|
offset = Socket->sendOffset;
|
offset = Socket->sendOffset;
|
if(frameOut == NULL)
|
if(frameOut == NULL)
|