NATcheck.rar

  • PUDN用户
    了解作者
  • Visual C++
    开发工具
  • 6KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 34
    下载次数
  • 2009-11-25 11:30
    上传日期
NATcheck.c源码,适合初学者好好学习,希望大家能共同进步,一起加油
NATcheck.rar
  • NATcheck.c
    21.9KB
内容介绍
/* * NAT Check - test NATs and firewalls for P2P-friendliness. * Copyright 2004 Bryan Ford * You may freely use and distribute this program * according to the terms of the GNU General Public License. * * Credits: * Windows port by Philippe Verdy * MAC OS X port by Richard Elmore * * Version 3: added testing for TCP-based P2P connection support * Version 2: added test for loopback translation support * Version 1: first public release, UDP-only * * Known to compile under Linux, FreeBSD, and Windows/MinGW with -lws2_32. * Your mileage may vary. No warranty, blah blah blah. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <assert.h rel='nofollow' onclick='return false;'> #include <inttypes.h> #include <sys/types.h> #ifdef __APPLE__ #define _BSD_SOCKLEN_T_ #endif #ifdef WIN32 #include <winsock.h> #define socklen_t int #else /* not WIN32 */ #include <unistd.h> #include <netdb.h> #include <sys/socket.h> #include <sys/select.h> #include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h rel='nofollow' onclick='return false;'> #endif /* not WIN32 */ #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif #define HOST_NAME_MAX 256 #define NTRIES 20 #define SERV1 "pdos.lcs.mit.edu" #define SERV2 "tears.lcs.mit.edu" #define SERV3 "sure.lcs.mit.edu" #define SERVPORT 9856 #define REQMAGIC 0x76849268 #define REPLMAGIC 0x01967293 #define LOOPMAGIC 0x86836173 struct request { uint32_t magic; }; struct reply { uint32_t magic; struct in_addr pubaddr; uint16_t pubport; }; int verbose = 0; struct sockaddr_in tsin, usin, sin1, sin2, sin3; int tcp0, tcp1, tcp2, tcp3, tcp4, udp1, udp2, incb, inloop, maxsock; fd_set rfds, wfds; struct sockaddr_in myt1, myt2, myt3, myu1, myu2, myu3; int tcploop = 0, udploop = 0, t3toosoon = 0; int die(int level) { #ifdef WIN32 WSACleanup(); #endif if (level) exit(level); return level; } #ifdef WIN32 void perr(const char *msg) { LPVOID lpMsgBuf; int e; lpMsgBuf = (LPVOID)"Unknown error"; e = WSAGetLastError(); if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR)&lpMsgBuf, 0, NULL)) { fprintf(stderr, "%s: error %d: %s\n", msg, e, lpMsgBuf); LocalFree(lpMsgBuf); } else fprintf(stderr, "%s: error %d\n", msg, e); } /* Check for an error code indicating that a read or write would block */ int eblock() { int e = WSAGetLastError(); if (e == WSAEWOULDBLOCK) return 1; return 0; } /* Check for an error code indicating that a connect() is still in progress */ int econnblock() { int e = WSAGetLastError(); if (e == WSAEINPROGRESS || e == WSAEALREADY || e == WSAEWOULDBLOCK || e == WSAEINVAL) return 1; return 0; } /* Check for an error code indicating that a connect() is complete */ int econndone() { int e = WSAGetLastError(); if (e == WSAEISCONN) return 1; return 0; } #else /* not WIN32 */ #define perr(msg) perror(msg) #define eblock() (errno == EAGAIN || errno == EWOULDBLOCK) #define econnblock() (errno == EINPROGRESS || errno == EALREADY) #define econndone() (errno == EISCONN) #endif void perrdie(const char *msg) { perr(msg); die(1); } void getaddr(const char *hostname, struct in_addr *addr) { struct hostent *h; h = gethostbyname(hostname); if (h == 0) perrdie(hostname); if (h->h_addrtype != AF_INET) { fprintf(stderr, "%s: unexpected address type %d\n", hostname, h->h_addrtype); } *addr = *(struct in_addr*)(h->h_addr); } void lookup(int n, const char *hostname, struct sockaddr_in *sin) { getaddr(hostname, &sin->sin_addr); sin->sin_family = AF_INET; sin->sin_port = htons(SERVPORT); if (verbose) fprintf(stderr, "server %d: %s at %s:%d\n", n, hostname, inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); } int mksock(int type) { int sock = socket(AF_INET, type, 0); if (sock < 0) perrdie("socket"); return sock; } void setnonblock(int sock) { #ifdef WIN32 unsigned long fl = 1; if (ioctlsocket(sock, FIONBIO, &fl) < 0) perrdie("socketioctl"); #else int fl = fcntl(sock, F_GETFL); if (fl < 0) perrdie("fcntl"); if (fcntl(sock, F_SETFL, fl | O_NONBLOCK) < 0) perrdie("fcntl"); #endif } void setreuse(int sock) { const int one = 1; #ifdef SO_REUSEADDR if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void*)&one, sizeof(one)) < 0) perrdie("setsockopt(SO_REUSEADDR)"); #endif #ifdef SO_REUSEPORT if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const void*)&one, sizeof(one)) < 0) perrdie("setsockopt(SO_REUSEPORT)"); #endif } void listentcp() { struct sockaddr_in sin; socklen_t sinlen; int rc; while (1) { sinlen = sizeof(sin); rc = accept(tcp0, (struct sockaddr*)&sin, &sinlen); if (rc < 0) { if (eblock()) return; perrdie("accept"); } /* Got a new incoming connection. Make it nonblocking. */ setnonblock(rc); if (verbose) fprintf(stderr, "Connection from %s:%d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); /* Figure out what to do with it. */ if (sin.sin_addr.s_addr == sin3.sin_addr.s_addr && sin.sin_port == sin3.sin_port) { if (incb < 0) { incb = rc; FD_SET(incb, &rfds); maxsock = max(maxsock, incb); } else close(rc); } else { if (inloop < 0) { inloop = rc; FD_SET(inloop, &rfds); maxsock = max(maxsock, inloop); } else close(rc); } } } void checktcp(int servn, int *sock, const struct sockaddr_in *connsin, struct sockaddr_in *mysin) { struct request rq; struct reply rp; int rc; if (*sock < 0) return; /* See if we're waiting for a connect attempt to complete. */ if (FD_ISSET(*sock, &wfds)) { /* Retry the connection attempt. */ rc = connect(*sock, (const struct sockaddr*)connsin, sizeof(*connsin)); if (rc < 0 && econnblock()) return; /* still not done */ if (rc < 0 && !econndone()) perrdie("checktcp connect"); /* Try to send() our request into the TCP socket, until we either succeed or fail with a "hard error." In the former case, move this socket from wfds to rfds in order to wait for the server's reply. */ rq.magic = htonl(REQMAGIC); rc = send(*sock, (const char*)&rq, sizeof(rq), 0); if (rc < 0) { if (eblock()) return; perrdie("tcp send"); } if (verbose) fprintf(stderr, "Connection to server %d complete\n", servn); FD_CLR(*sock, &wfds); FD_SET(*sock, &rfds); return; } if (!FD_ISSET(*sock, &rfds)) return; /* Now see if there's any data available on the socket. */ rc = recv(*sock, (char*)&rp, sizeof(rp), 0); if (rc < 0) { if (eblock()) return; perrdie("tcp recv"); } if (rc < sizeof(rp)) { if (verbose) fprintf(stderr, "received runt TCP response from server %d\n", servn); goto closeit; } if (rp.magic != htonl(REPLMAGIC)) { if (verbose) fprintf(stderr, "received TCP reply with bad magic value\n"); goto closeit; } if (mysin->sin_addr.s_addr != INADDR_ANY) { if (verbose) fprintf(stderr, "received multiple TCP responses!?\n"); goto closeit; } if (verbose) fprintf(stderr, "Server %d reports my TCP address as %s:%d\n", servn, inet_ntoa(rp.pubaddr), ntohs(rp.pubport)); mysin->sin_addr = rp.pubaddr; mysin->sin_port = rp.pubport; /* When server 2 responds: */ if (servn == 2) { /* Make a TCP connection attempt to server 3. Since server 2 has just responded, this should mean that server 3 has already initiated a connection attempt inward through the NAT. While the server 1 and 2 connections are client/server, the server 3 connectio
评论
    相关推荐
    • TCP-makeholeDemo.zip
      TCP 打洞 ,穿越NAT,实现两个局域网间通信
    • natcheck.zip
      检测网络类型.检测网络类型,检测网络类型
    • natcheck-linux.rar
      this is a program that will help you to check wether your computer receive tcp or udp packet from internet or other computer
    • sendmail.8.10.0.Beta10.tar.Z
      被广泛使用的发送邮件(SMTP)服务器
    • ZtsFw.zip
      使用Firewall Hook Driver技术进行端口过滤的一个简单防火墙的代码。
    • hadoop-0.20.0.tar.gz
      Hadoop 是一个实现了 MapReduce 计算模型的开源分布式并行编程框架,借助于 Hadoop, 程序员可以轻松地编写分布式并行程序,将其运行于计算机集群上,完成海量数据的计算。
    • netbus.zip
      类似pcanywhere的一个木马程序,用于远程控制对方机器。
    • anywhere.zip
      一个类似PCAnywhere的远程控制软件源码,分客户端和服务器端。
    • hehegu.rar
      红河谷邀请码生成器(2010年7月28日测试通过)
    • FTP总集.rar
      七个FTP的客户端和服务器端程序的源码,能够实现文件的上传,下载,修改,删除等诸多功能