1 :
2 :
3 :
4 :
5 :
6 :
7 :
8 :
9 :
10 :
11 :
12 :
13 :
14 :
15 :
16 :
17 : #include <stdio.h>
18 : #include <string.h>
19 : #include "CSocket.h"
20 :
21 :
22 : #ifdef WINDOWS
23 : #ifndef _WIN32_WCE
24 : #pragma comment(lib,"wsock32.lib ")
25 : #else
26 : #pragma comment(lib,"winsock.lib ")
27 : #endif
28 : #endif
29 :
30 :
31 :
32 :
33 :
34 :
35 :
36 :
40 : CWinSock::CWinSock()
41 : {
42 : m_fStartUp = FALSE;
43 : }
44 :
45 :
49 : CWinSock::~CWinSock()
50 : {
51 : Release();
52 : }
53 :
54 :
55 :
62 : BOOL
63 : CWinSock::Startup(BYTE mn,BYTE mj)
64 : {
65 : #ifdef WINDOWS
66 : int nRC;
67 : if(m_fStartUp) WSACleanup();
68 : m_wVR = MAKEWORD(mn,mj);
69 : nRC=WSAStartup(m_wVR,&m_wsdata);
70 : if(m_wsdata.wVersion != m_wVR){
71 : return FALSE;
72 : }
73 : if(nRC) return FALSE;
74 : #endif
75 : m_fStartUp = TRUE;
76 : return TRUE;
77 : }
78 :
79 :
88 : BOOL
89 : CWinSock::GetHostByName(LPSTR szHost,int nMaxCount,LPCSTR szName){
90 : LPHOSTENT lpHost;
91 : struct in_addr addr;
92 : szHost[0] = '\0';
93 :
94 : lpHost = gethostbyname(szName);
95 : if (lpHost == NULL)
96 : {
97 : return FALSE;
98 : }
99 :
100 :
101 : addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
102 :
103 :
104 : if((int)strlen(inet_ntoa(addr)) >= nMaxCount){
105 : return FALSE;
106 : }
107 :
108 :
109 : strcpy(szHost,inet_ntoa(addr));
110 : return TRUE;
111 : }
112 :
121 : BOOL
122 : CWinSock::GetHostByAddr(LPSTR szName,int nMaxCount,LPCSTR szIPAddr){
123 : LPHOSTENT lpHost;
124 : struct in_addr iaHost;
125 : szName[0] = '\0';
126 : iaHost.s_addr=inet_addr(szIPAddr);
127 : lpHost = gethostbyaddr((const char *)&iaHost,sizeof(in_addr),AF_INET);
128 : if(lpHost == NULL){
129 : return FALSE;
130 : }
131 :
132 : if((int)strlen(lpHost->h_name) >= nMaxCount){
133 : return FALSE;
134 : }
135 : strcpy(szName,lpHost->h_name);
136 : return TRUE;
137 : }
138 :
139 :
144 : BOOL
145 : CWinSock::Release(void){
146 : #ifdef WINDOWS
147 : if(m_fStartUp){
148 : WSACleanup();
149 : }
150 : #endif
151 : m_fStartUp = FALSE;
152 : return TRUE;
153 : }
154 :
155 :
156 :
157 :
161 : CSocket::CSocket(){
162 :
163 : }
164 :
165 :
169 : BOOL
170 : CSocket::Connect(LPSTR szHost,WORD nPort){
171 : LPHOSTENT lpHost;
172 : m_addr.sin_port = htons(nPort);
173 : m_addr.sin_family = AF_INET;
174 :
175 :
176 :
177 : if((m_addr.sin_addr.s_addr=inet_addr(szHost)) == INADDR_NONE){
178 : if ((lpHost = gethostbyname (szHost)) == NULL){
179 :
180 :
181 :
182 :
183 : return FALSE;
184 : }
185 : memcpy(&m_addr.sin_addr, lpHost->h_addr,lpHost->h_length);
186 : }
187 :
188 :
199 :
200 : m_socket = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
201 : if (!IS_VALIDSOCKET(m_socket))
202 : {
203 : #ifdef _DISPMESSAGE
204 : MessageBox(NULL,_T("socket()"),_T("Error"),NULL);
205 : #endif
206 : return FALSE;
207 : }
208 : int nRet = ::connect(m_socket,
209 : (LPSOCKADDR)&m_addr,
210 : sizeof(struct sockaddr));
211 : if (nRet == SOCKET_ERROR)
212 : {
213 : #ifdef _DISPMESSAGE
214 : MessageBox(NULL,_T("connect()"),_T("Error"),NULL);
215 : #endif
216 : return FALSE;
217 : }
218 : return TRUE;
219 : }
220 :
221 :
225 : BOOL
226 : CSocket::Close()
227 : {
228 : ::shutdown(m_socket,2);
229 : #ifdef WINDOWS
230 : ::closesocket(m_socket);
231 : #else
232 : ::close(m_socket);
233 : #endif
234 : return TRUE;
235 : }
236 :
237 :
238 :
242 : char*
243 : CSocket::GetHostname(char* lpHostName,int iCount){
244 :
245 : LPHOSTENT lpHost;
246 : lpHost = gethostbyaddr((const char *)&m_addr.sin_addr,sizeof(in_addr),AF_INET);
247 : if(lpHost == NULL){
248 : return FALSE;
249 : }
250 :
251 : if((int)strlen(lpHost->h_name) >= iCount){
252 : return NULL;
253 : }
254 : strcpy(lpHostName,lpHost->h_name);
255 : return lpHostName;
256 :
257 : }
258 :
262 : char*
263 : CSocket::GetHostaddr(char* lpHost){
264 : strcpy(lpHost,inet_ntoa(m_addr.sin_addr));
265 : return lpHost;
266 : }
267 :
271 : BOOL
272 : CSocket::SendData(LPVOID pData,int dwLen)
273 : {
274 : int bsend;
275 : char *bufp;
276 : bufp = (char*)pData;
277 :
278 : do{
279 : bsend = ::send(m_socket,bufp,dwLen,0);
280 : if(bsend==SOCKET_ERROR){
281 : return FALSE;
282 : }
283 : bufp += bsend; dwLen -= bsend;
284 : }while(dwLen>0);
285 :
286 : return TRUE;
287 : }
288 :
292 : BOOL
293 : CSocket::SendStr(LPCSTR szStr)
294 : {
295 : this->SendData((LPVOID)szStr,strlen(szStr));
296 : return TRUE;
297 : }
298 :
302 : BOOL
303 : CSocket::RecvData(LPVOID pBuf,int dwLen,DWORD* pdwRecvLen)
304 : {
305 :
306 : DWORD dwByteRecv=0;
307 : char *point=(char*)pBuf;
308 : int rread;
309 : while(1){
310 : rread=::recv(m_socket,point,dwLen-dwByteRecv,0);
311 : if((rread)==SOCKET_ERROR || rread==0) {
312 : break;
313 : }
314 : dwByteRecv += rread;
315 : point = (char*)pBuf + dwByteRecv;
316 : if((DWORD)dwLen <= dwByteRecv) break;
317 : }
318 : if(dwByteRecv == 0) {
319 : return FALSE;
320 :
321 : }
322 : if(pdwRecvLen)
323 : *pdwRecvLen = (DWORD)dwByteRecv;
324 : return TRUE;
325 : }
326 :
330 : BOOL
331 : CSocket::RecvDataOnce(LPVOID pBuf,int dwLen,DWORD* pdwRecvLen)
332 : {
333 : DWORD dwByteRecv=0;
334 : dwByteRecv=::recv(m_socket,(char*)pBuf,dwLen,0);
335 : if(dwByteRecv == 0) return FALSE;
336 : if(pdwRecvLen)
337 : *pdwRecvLen = (DWORD)dwByteRecv;
338 : return TRUE;
339 : }
340 :
345 : BOOL
346 : CSocket::RecvLine(char* pBuf,int dwLen,DWORD* pdwRecvLen)
347 : {
348 : DWORD dwRecv;
349 : *pdwRecvLen = 0;
350 : int iCnt=0;
351 : while(1){
352 : if(!this->RecvData(pBuf,1,&dwRecv)) return FALSE;
353 : *pdwRecvLen++;
354 :
355 : if(*pBuf == '\r'){
356 : if(!this->RecvData(pBuf,1,&dwRecv)) return FALSE;
357 : *pBuf = '\0';
358 : break;
359 : }else if(*pBuf == '\n'){
360 : *pBuf = '\0';
361 : break;
362 : }
363 :
364 : pBuf++;
365 : iCnt++;
366 : if(iCnt >= dwLen-1) return FALSE;
367 : }
368 :
369 : return TRUE;
370 : }
371 :
372 :
376 : BOOL
377 : CSocket::Listen(WORD nPort)
378 : {
379 : int ret;
380 : m_socket = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
381 : if(!IS_VALIDSOCKET(m_socket)){
382 : return FALSE;
383 : }
384 : m_addr.sin_port=htons(nPort);
385 : m_addr.sin_family = AF_INET;
386 : #ifdef WINDOWS
387 : m_addr.sin_addr.S_un.S_addr = INADDR_ANY;
388 : #endif
389 : ret = ::bind(m_socket,
390 : (LPSOCKADDR)&m_addr,
391 : sizeof(struct sockaddr));
392 : if(ret == SOCKET_ERROR){
393 : ::closesocket(m_socket);
394 :
395 : return FALSE;
396 : }
397 : ret = ::listen(m_socket,SOMAXCONN);
398 : if(ret == SOCKET_ERROR){
399 : ::closesocket(m_socket);
400 : return FALSE;
401 : }
402 :
403 : return TRUE;
404 : }
405 :
409 : BOOL
410 : CSocket::Accept(CSocket& soc)
411 : {
412 : #ifdef WINDOWS
413 : int nLen =sizeof(soc.m_addr);
414 : #else
415 : socklen_t nLen = sizeof(soc.m_addr);
416 : #endif
417 : soc.m_socket=::accept(m_socket,(LPSOCKADDR)&soc.m_addr,&nLen);
418 : if(!IS_VALIDSOCKET(soc.m_socket)){
419 :
420 : return FALSE;
421 : }
422 :
423 : return TRUE;
424 : }
425 :
426 :
427 :
428 :
432 : CSocketUDP::CSocketUDP(){
433 : return;
434 : }
435 :
436 :
442 : BOOL CSocketUDP::StartUDP(WORD wLocalPort,LPCSTR szServer,WORD wServerPort){
443 : m_socket = socket(PF_INET, SOCK_DGRAM, 0);
444 : if(!IS_VALIDSOCKET(m_socket)){
445 : return FALSE;
446 : }
447 :
448 : m_ServerPort = wServerPort;
449 :
450 :
451 : struct sockaddr_in sockname;
452 :
453 : if(wLocalPort){
454 :
455 :
456 : sockname.sin_family = AF_INET;
457 : sockname.sin_addr.s_addr = INADDR_ANY;
458 : sockname.sin_port = htons((unsigned short)wLocalPort);
459 : memset(sockname.sin_zero,(int)0,sizeof(sockname.sin_zero));
460 :
461 :
462 :
463 : if(bind(m_socket,(struct sockaddr *)&sockname,sizeof(sockname)) == SOCKET_ERROR){
464 : return FALSE;
465 : }
466 :
467 : }
468 :
469 : if(szServer && wServerPort){
470 :
471 : struct hostent *serverhostent;
472 :
473 :
474 : m_ServerAddr = inet_addr((char*)szServer);
475 : if ((long)m_ServerAddr == -1) {
476 :
477 :
478 : serverhostent = gethostbyname(szServer);
479 :
480 :
481 :
482 : if (serverhostent == NULL) {
483 : return FALSE;
484 : }else{
485 :
486 : m_ServerAddr = *((unsigned long *)((serverhostent->h_addr_list)[0]));
487 : }
488 : }
489 : }
490 :
491 :
492 : return TRUE;
493 : }
494 :
495 : BOOL
496 : CSocketUDP::SendTo(LPCSTR lpBuf,DWORD dwBufSize){
497 :
498 : struct sockaddr_in serversockaddr;
499 :
500 :
501 : serversockaddr.sin_family = AF_INET;
502 : serversockaddr.sin_addr.s_addr = m_ServerAddr;
503 : serversockaddr.sin_port = htons((unsigned short)m_ServerPort);
504 : memset(serversockaddr.sin_zero,(int)0,sizeof(serversockaddr.sin_zero));
505 :
506 : if(sendto(m_socket, (char*)lpBuf, dwBufSize, 0,(struct sockaddr *)&serversockaddr,sizeof(serversockaddr)) == SOCKET_ERROR){
507 : return FALSE;
508 : }
509 :
510 : return TRUE;
511 : }
512 :
513 : BOOL
514 : CSocketUDP::RecvFrom(LPSTR lpBuf,DWORD dwBufSize,DWORD* pdwByteRecv){
515 :
516 :
517 : int buf_len;
518 :
519 : struct sockaddr_in serversockaddr;
520 :
521 : #ifdef WINDOWS
522 : int sockaddr_size;
523 : #else
524 : socklen_t sockaddr_size ;
525 : #endif
526 :
527 :
528 : sockaddr_size = sizeof(serversockaddr);
529 : buf_len = recvfrom(m_socket, lpBuf, dwBufSize , 0,(struct sockaddr *)&serversockaddr,&sockaddr_size);
530 : if (buf_len == SOCKET_ERROR ){
531 : return FALSE;
532 : }
533 : *pdwByteRecv=buf_len;
534 : return TRUE;
535 : };
536 :
537 :
538 : BOOL CSocketUDP::Close(){
539 : ::closesocket(m_socket);
540 : return TRUE;
541 : };
542 :
543 : #ifndef NO_CPING
544 :
545 :
546 :
547 :
551 : CPing::CPing()
552 : {
553 :
554 : m_ucTTL = 0;
555 : m_lTimeout_sec = 5;
556 : m_lTimeout_usec = 0;
557 : return;
558 : }
559 :
560 : int
561 : CPing::Ping(LPCSTR pstrHost)
562 : {
563 : SOCKET rawSocket;
564 : LPHOSTENT lpHost;
565 : struct sockaddr_in saDest;
566 : struct sockaddr_in saSrc;
567 : DWORD dwTimeSent;
568 : DWORD dwElapsed;
569 : u_char cTTL;
570 : int nRet;
571 :
572 :
573 : rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
574 : if (rawSocket == SOCKET_ERROR)
575 : {
576 :
577 : return CPING_SOCKETERROR;
578 : }
579 :
580 :
581 : lpHost = gethostbyname(pstrHost);
582 : if (lpHost == NULL)
583 : {
584 : closesocket(rawSocket);
585 : return CPING_DNSERROR;
586 : }
587 :
588 :
589 : saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
590 : saDest.sin_family = AF_INET;
591 : saDest.sin_port = 0;
592 :
593 :
594 :
595 :
596 :
597 : if(m_ucTTL){
598 : if (setsockopt(rawSocket, IPPROTO_IP, IP_TTL, (char *)&m_ucTTL, sizeof(m_ucTTL)) == SOCKET_ERROR)
599 : {
600 : closesocket(rawSocket);
601 : return CPING_SETOPTERROR;
602 : }
603 : }
604 :
605 :
606 : SendEchoRequest(rawSocket, &saDest);
607 :
608 : nRet = WaitForEchoReply(rawSocket);
609 : if (nRet == SOCKET_ERROR)
610 : {
611 : closesocket(rawSocket);
612 : return CPING_SELECTERROR;
613 : }
614 : if (!nRet)
615 : {
616 : closesocket(rawSocket);
617 : return CPING_TIMEOUT;
618 : }
619 :
620 :
621 : dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
622 :
623 : dwElapsed = GetTickCount() - dwTimeSent;
624 :
625 : m_ucTTL = cTTL;
626 : m_iReplayTime = dwElapsed;
627 : #ifdef _UNICODE
628 :
629 :
630 : ::MultiByteToWideChar(CP_ACP, 0,
631 : inet_ntoa(saSrc.sin_addr), -1,
632 : m_szReplyHost, sizeof(m_szReplyHost)/sizeof(TCHAR));
633 :
634 : #else
635 : ::wsprintf(m_szReplyHost,inet_ntoa(saSrc.sin_addr));
636 : #endif
637 : nRet = closesocket(rawSocket);
638 :
639 : if(m_ucIcmpType == ICMP_ECHOREPLY){
640 : return dwElapsed;
641 : }else{
642 : return CPING_UNREACHED;
643 : }
644 : }
645 :
646 :
647 :
648 :
649 : int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
650 : {
651 : static ECHOREQUEST echoReq;
652 : static nId = 1;
653 : static nSeq = 1;
654 : int nRet;
655 :
656 :
657 : echoReq.icmpHdr.Type = ICMP_ECHOREQ;
658 : echoReq.icmpHdr.Code = 0;
659 : echoReq.icmpHdr.Checksum = 0;
660 : echoReq.icmpHdr.ID = nId++;
661 : echoReq.icmpHdr.Seq = nSeq++;
662 :
663 :
664 :
665 :
666 :
667 : for (nRet = 0; nRet < REQ_DATASIZEDEF; nRet++)
668 : echoReq.cData[nRet] = ' '+nRet;
669 :
670 :
671 : echoReq.dwTime = GetTickCount();
672 :
673 :
674 : echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));
675 :
676 :
677 : nRet = sendto(s,
678 : (LPSTR)&echoReq,
679 : sizeof(ECHOREQUEST),
680 : 0,
681 : (LPSOCKADDR)lpstToAddr,
682 : sizeof(SOCKADDR_IN));
683 :
684 : if (nRet == SOCKET_ERROR)
685 : return CPING_SOCKETERROR;
686 : return (nRet);
687 : }
688 :
689 : u_short CPing::in_cksum(u_short *addr, int len)
690 : {
691 : register int nleft = len;
692 : register u_short *w = addr;
693 : register u_short answer;
694 : register int sum = 0;
695 :
696 :
702 :
703 : while( nleft > 1 ) {
704 : sum += *w++;
705 : nleft -= 2;
706 : }
707 :
708 :
709 :
710 : if( nleft ) {
711 :
712 :
713 :
714 :
715 :
716 : sum += *(u_short *)w;
717 : }
718 :
719 :
722 : sum = (sum >> 16) + (sum & 0xffff);
723 :
724 :
725 : sum += (sum >> 16);
726 :
727 :
728 : answer = ~sum;
729 : return (answer);
730 : }
731 : int CPing::WaitForEchoReply(SOCKET s)
732 : {
733 : struct timeval Timeout;
734 : fd_set readfds;
735 :
736 : readfds.fd_count = 1;
737 : readfds.fd_array[0] = s;
738 : Timeout.tv_sec = m_lTimeout_sec;
739 : Timeout.tv_usec = m_lTimeout_usec;
740 :
741 : return(select(1, &readfds, NULL, NULL, &Timeout));
742 : }
743 :
744 : DWORD CPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL)
745 : {
746 : ECHOREPLY echoReply;
747 : int nRet;
748 : int nAddrLen = sizeof(struct sockaddr_in);
749 :
750 :
751 : nRet = recvfrom(s,
752 : (LPSTR)&echoReply,
753 : sizeof(ECHOREPLY),
754 : 0,
755 : (LPSOCKADDR)lpsaFrom,
756 : &nAddrLen);
757 :
758 :
759 : if (nRet == SOCKET_ERROR)
760 : return CPING_SOCKETERROR;
761 :
762 :
763 :
764 :
765 : *pTTL = echoReply.ipHdr.TTL;
766 :
767 : m_ucIcmpType = echoReply.echoRequest.icmpHdr.Type;
768 :
769 : return(echoReply.echoRequest.dwTime);
770 : }
771 : #endif
772 :
773 : #if defined(_WIN32_WCE_PSPC)
774 : #endif
775 :
776 :
777 :