【发布时间】: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.0 和 192.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