【问题标题】:Detecting incoming port for TFTP data?检测 TFTP 数据的传入端口?
【发布时间】:2015-06-09 19:43:41
【问题描述】:

我正在实现一个 TFTP 客户端(UDP 套接字)。

目前我必须关闭我的 Windows 8 机器上的整个防火墙,否则数据不会到达 TFTP 客户端。传出连接请求发生在端口 69 上,但来自 TFTP 服务器的第一个数据包在不同的随机端口上传输回来。所以我的问题是:如何确保 TFTP 客户端(作为应用程序)能够在防火墙开启的机器上接收数据包?

当我在 Visual Studio 2005 中以调试模式运行 TFTP 客户端时,除非我关闭防火墙,否则客户端也不会接收数据包。我该如何解决?

谢谢

更新(代码)

void main(void)
{
    unsigned short OPCODE = htons((unsigned short)1);
    char* fileName = "thisfile.cnf.xml";
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    SOCKET sockfd;
    int n;
    char buf[256] = {0};
    int L;
    struct sockaddr_in servaddr;
    char recvline[1000];
    int rc;

    wVersionRequested = MAKEWORD( 2, 2 );
    err = WSAStartup( wVersionRequested, &wsaData );
    memcpy(buf, &OPCODE, 2);
    sprintf_s(&buf[2], 254, "%s%c%s%c", fileName, '\0', "octet", '\0');
    L = (int) strlen(fileName) + 9;
    sockfd=socket(AF_INET,SOCK_DGRAM,0);
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr=inet_addr("212.158.10.33");
    servaddr.sin_port=htons(69);
    rc = sendto(sockfd,buf,L,0, (struct sockaddr *)&servaddr,sizeof(servaddr));

    while (1)
    {
       printf("Receive 1st packet...\n");
       /* This call gets blocked unless firewall is off */
       n=recvfrom(sockfd,recvline,1000,0,NULL,NULL);
       printf("%d bytes received\n", n);
       break;
    }
}

【问题讨论】:

    标签: c sockets udp tftp


    【解决方案1】:

    TFTP协议有如下流程:

    1. 客户端从随机选择的 CTID 端口向服务器的 69 端口发送 RRQWRQ 请求:

      客户端:CTID ------> 服务器:69

    2. 服务器从随机选择的 STID 端口回复客户端的 CTID:

      客户端:CTID

    3. 该传输的所有后续数据包都根据需要在客户端的 CTID 和服务器的 STID 之间发送。

      客户端:CTID 服务器:STID

    每台机器都选择自己的 TID 端口用于将发送到另一方的目标 TID 端口的数据包。

    如上所见,CTID 和 STID 是由相应的机器选择的,最好是随机的。在您的代码中,您没有为您的请求设置 源端口,因此它是由操作系统随机选择的。这对您的传出数据包来说很好,但防火墙不知道入站数据包将来自哪里。所以你需要bind()你的套接字到一个特定的端口,然后你可以在你的防火墙中打开它。否则,请检查您的防火墙设置,看看它是否有一个可用的规则,该规则将允许来自最近发送出 UDP 数据包的 IP 地址的入站 UDP 数据包,或类似的规则。

    【讨论】:

    • 让操作系统随机选择源端口是完美的。您只需确保生成的端口在防火墙中打开。即使您使用bind(),您仍然可以绑定到端口 0 以获取随机分配的端口,然后查询套接字以发现分配的端口,然后您可以相应地打开防火墙(甚至通过防火墙 API 自动打开)。否则,你必须事先预留一个端口池,确保它们在防火墙中都是开放的,并且只绑定到这些端口。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多