2 * Hyper Operating System Application Framework
5 * @brief %jp{TCP/IP プロトコル}
7 * Copyright (C) 2006-2007 by Project HOS
8 * http://sourceforge.jp/projects/hos/
14 #include "tcpip_local.h"
15 #include "library/algorithm/ipchecksum/ipchecksum.h"
18 static void Tcpip_IcmpRecv(C_TCPIP *self, const unsigned char *pubBuf, int iSize);
23 void Tcpip_UdpRecv(C_TCPIP *self, const unsigned char *pubBuf, int iSize)
25 const unsigned char ubDumy[2] = {0, 17};
29 unsigned short uhDstPort;
30 unsigned short uhSrcPort;
31 unsigned short uhUdpSize;
32 unsigned short uhCheckSum;
35 uhDstPort = IP_GET_HALFWORD(&pubBuf[20]);
36 uhSrcPort = IP_GET_HALFWORD(&pubBuf[22]);
37 uhUdpSize = IP_GET_HALFWORD(&pubBuf[24]);
38 uhCheckSum = IP_GET_HALFWORD(&pubBuf[26]);
41 /* ---------------------- */
43 /* ---------------------- */
45 IpCheckSum_Create(&ics);
47 /* UDP擬似ヘッダ(pseudo header)*/
48 IpCheckSum_Update(&ics, &pubBuf[12], 8); /* 送信元アドレス& 送信先アドレス */
49 IpCheckSum_Update(&ics, ubDumy, 2);
50 IpCheckSum_Update(&ics, &pubBuf[24], 2); /* パケット長 */
53 IpCheckSum_Update(&ics, &pubBuf[20], 6);
54 IpCheckSum_Update(&ics, &pubBuf[28], uhUdpSize - 8);
56 uhSum = IpCheckSum_GetDigest(&ics);
58 IpCheckSum_Delete(&ics);
60 if ( uhCheckSum != 0x0000 && uhCheckSum != uhSum )
67 pFile = self->pUdpHead;
72 if ( pFile->uhPortNum == uhDstPort )
78 } while ( pFile == self->pUdpHead );
84 void Tcpip_TcpRecv(C_TCPIP *self, const unsigned char *pubBuf, int iSize)
86 const unsigned char *pubRecvTcp;
87 unsigned short uhMyPort;
88 unsigned short uhYourPort;
90 pubRecvTcp = &pubBuf[20];
92 uhYourPort = (pubRecvTcp[0] << 8) + pubRecvTcp[1];
93 uhMyPort = (pubRecvTcp[2] << 8) + pubRecvTcp[3];
95 if ( pubRecvTcp[13] == TCP_FLAG_SYN )
97 unsigned long uwSeqNum;
98 unsigned char *pubSendBuf;
99 unsigned char *pubSendTcp;
102 pubSendBuf = self->ubSendBuf;
103 pubSendTcp = &pubSendBuf[20];
106 /******** IPヘッダ ********/
108 /* バージョン4, ヘッダ長 0x14 */
109 pubSendBuf[0] = 0x45;
112 pubSendBuf[1] = 0x00;
115 pubSendBuf[2] = iSize / 256;
116 pubSendBuf[3] = iSize % 256;
119 pubSendBuf[4] = self->uhPacketId / 256;
120 pubSendBuf[5] = self->uhPacketId % 256;
124 pubSendBuf[6] = 0x00;
125 pubSendBuf[7] = 0x00;
128 pubSendBuf[8] = 0xff;
131 pubSendBuf[9] = 0x06; /* TCP */
134 memcpy(&pubSendBuf[12], &pubBuf[16], 4);
137 memcpy(&pubSendBuf[16], &pubBuf[12], 4);
141 /******** TCP ********/
144 pubSendTcp[0] = 0x00;
146 IP_SET_HALFWORD(&pubRecvTcp[0], uhMyPort);
147 IP_SET_HALFWORD(&pubRecvTcp[2], uhYourPort);
149 uwSeqNum = IP_GET_WORD(&pubRecvTcp[4]);
150 IpCheckSum_Create(&ics);
151 IpCheckSum_Update(&ics, &pubSendBuf[20], iSize - 20);
152 uhSum = IpCheckSum_GetDigest(&ics);
153 IpCheckSum_Delete(&ics);
162 void Tcpip_Recv(VPARAM Param)
165 unsigned char *pubRecvBuf;
169 self = (C_TCPIP *)Param;
171 pubRecvBuf = self->ubRecvBuf;
176 if ( (iSize = File_Read(self->hIp, pubRecvBuf, 2048)) < 20 )
182 switch ( pubRecvBuf[9] )
184 case 0x01: /* ICMP */
185 Tcpip_IcmpRecv(self, pubRecvBuf, iSize);
189 Tcpip_TcpRecv(self, pubRecvBuf, iSize);
193 Tcpip_UdpRecv(self, pubRecvBuf, iSize);
200 void Tcpip_IcmpRecv(C_TCPIP *self, const unsigned char *pubBuf, int iSize)
203 unsigned short uhSum;
204 unsigned char *pubSendBuf;
206 pubSendBuf = self->ubSendBuf;
209 /******** IPヘッダ ********/
211 /* バージョン4, ヘッダ長 0x14 */
212 pubSendBuf[0] = 0x45;
215 pubSendBuf[1] = 0x00;
218 pubSendBuf[2] = iSize / 256;
219 pubSendBuf[3] = iSize % 256;
222 pubSendBuf[4] = self->uhPacketId / 256;
223 pubSendBuf[5] = self->uhPacketId % 256;
227 pubSendBuf[6] = 0x00;
228 pubSendBuf[7] = 0x00;
231 pubSendBuf[8] = 0xff;
234 pubSendBuf[9] = 0x01; /* ICMP */
237 memcpy(&pubSendBuf[12], &pubBuf[16], 4);
240 memcpy(&pubSendBuf[16], &pubBuf[12], 4);
244 /******** ICMP ********/
247 pubSendBuf[20] = 0x00;
250 pubSendBuf[21] = 0x00;
253 pubSendBuf[22] = 0x00;
254 pubSendBuf[23] = 0x00;
257 pubSendBuf[24] = pubBuf[24];
258 pubSendBuf[25] = pubBuf[25];
261 pubSendBuf[26] = pubBuf[26];
262 pubSendBuf[27] = pubBuf[27];
265 memcpy(&pubSendBuf[28], &pubBuf[28], iSize - 28);
268 IpCheckSum_Create(&ics);
269 IpCheckSum_Update(&ics, &pubSendBuf[20], iSize - 20);
270 uhSum = IpCheckSum_GetDigest(&ics);
271 IpCheckSum_Delete(&ics);
273 pubSendBuf[22] = uhSum / 256;
274 pubSendBuf[23] = uhSum % 256;
278 File_Write(self->hIp, pubSendBuf, iSize);