【问题标题】:Can manually set up Ethernet but not WiFi communication using C program可以使用 C 程序手动设置以太网但不能设置 WiFi 通信
【发布时间】:2016-10-08 17:31:28
【问题描述】:

我编写了一个 C 程序,它可以为任何可用的网络接口设置用户选择的 IP 地址和子网掩码。我能够在两台计算机之间建立通信通过以太网电缆相互连接,只需使用此程序为每台计算机配置 IP 和网络掩码。但是,该方法在 WiFi 接口上不起作用。

这是我在两台笔记本电脑通过以太网电缆连接时所做的(inet_config 是我的 C 程序,它为任何网络接口设置 IP 和网络掩码)。

第一台笔记本电脑:

inet_config  eth0  192.168.1.0  255.255.255.0

第二台笔记本电脑:

inet_config  eth0  192.168.1.1  255.255.255.0

这会将第一台和第二台笔记本电脑上以太网接口的 IP 地址分别设置为 192.168.1.0192.168.1.1。两台笔记本电脑上以太网接口的子网掩码都设置为255.255.255.0

现在,我可以使用nc 在两台笔记本电脑之间建立通信。但是,如果我使用 WiFi 接口而不是以太网,则无法建立连接。我发现当我使用 WiFi 时,connect() 系统调用返回错误EHOSTUNREACH (No route to host)。谁能告诉我我需要做什么才能让它在 WiFi 上运行?

inet_config的源代码在这里:

/* inet_config.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>

#define _COMMAND_NAME   argv[0]
#define _INTERFACE_NAME argv[1]
#define _INET_ADDRESS   argv[2]
#define _SUBNET_MASK    argv[3]

int main(int argc, char ** argv)
{
    int sockfd, ioctl_result, inet_conv_result, subnet_conv_result;
    struct ifreq ifr;
    struct sockaddr_in inet_addr, subnet_mask;

    /* Check argument count */

    if(argc != 4)
    {
        fprintf(stderr, "Usage: %s interface_name ip_addr subnet_mask\n", _COMMAND_NAME);
        exit(EXIT_FAILURE);
    }

    /* Initialization */

    bzero((char *)&ifr, sizeof(ifreq));
    bzero((char *)&inet_addr, sizeof(struct sockaddr_in));
    bzero((char *)&subnet_mask, sizeof(struct sockaddr_in));

    strcpy(ifr.ifr_name, _INTERFACE_NAME);

    /* Prepare inet_address and subnet_mask structures */

    inet_addr.sin_family = AF_INET;
    inet_conv_result = inet_pton(AF_INET, _INET_ADDRESS, &(inet_addr.sin_addr));

    if(inet_conv_result == 0)
    {
        fprintf(stderr, "inet_pton: Invalid IPv4 address format\n");
        exit(_EXIT_FAILURE);
    }
    if(inet_conv_result < 0)
    {
        perror("inet_pton");
        exit(EXIT_FAILURE);
    }

    subnet_mask.sin_family = AF_INET;
    subnet_conv_result = inet_pton(AF_INET, _SUBNET_MASK, &(subnet_mask.sin_addr));

    if(subnet_conv_result == 0)
    {
        fprintf(stderr, "inet_pton: Invalid subnet mask format\n");
        exit(_EXIT_FAILURE);
    }
    if(subnet_conv_result < 0)
    {
        perror("inet_pton");
        exit(EXIT_FAILURE);
    }

    /* Open socket for network device configuration */

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0)
    {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    /* Call ioctl to configure network devices */

    memcpy(&(ifr.ifr_addr), &inet_addr, sizeof(struct sockaddr)); // Set IP address
    ioctl_result = ioctl(sockfd, SIOCSIFADDR, &ifr);
    if(ioctl_result < 0)
    {
        perror("SIOCSIFADDR");
        exit(EXIT_FAILURE);
    }

    memcpy(&(ifr.ifr_addr), &subnet_mask, sizeof(struct sockaddr)); //Set subnet mask
    ioctl_result = ioctl(sockfd, SIOCSIFNETMASK, &ifr);
    if(ioctl_result < 0)
    {
        perror("SIOCSIFNETMASK");
        exit(EXIT_FAILURE);
    }

    printf("Network devices configured\n");

    return 0;
}

【问题讨论】:

  • Wi-Fi连接方式是ad-hoc还是Access Point
  • @Dmitry 根据我在您包含的链接上阅读的内容,我想要设置的是一个 ad-hoc 网络。它不包括路由器。这里应该只连接两台计算机。我所做的是在两台笔记本电脑的无线接口上手动设置 IP 和网络掩码。然后,我让两台笔记本电脑中的一台传输目的地是另一台计算机的 IP 地址的数据包。没有做任何其他事情。如我的帖子中所述,我收到一条错误消息。如果我做同样的事情,但改用有线接口并将以太网电缆连接到每台笔记本电脑的端口,则相同的程序可以工作。

标签: c sockets networking wifi ioctl


【解决方案1】:

首先,您需要在两台计算机上将 Wi-Fi 卡设置为 ad-hoc 模式。之后可以设置IP地址和网络掩码。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
相关资源
最近更新 更多