I have written a C program that can set an IP address and a subnet mask of the user's choice for any available network interface. I am able to establish communication between two computers connected to each other by an ethernet cable by simply using this program to configure an IP and a netmask for each of them. However, this method does not work on the WiFi interface.
Here's what I did when the two laptops were connected by an ethernet cable (inet_config
is my C program that sets an IP and a netmask for any network interface).
First Laptop:
inet_config eth0 192.168.1.0 255.255.255.0
Second Laptop:
inet_config eth0 192.168.1.1 255.255.255.0
This sets the IP addresses of the ethernet interfaces on the first and second laptops to 192.168.1.0
and 192.168.1.1
respectively. The subnet masks of the ethernet interfaces on both laptops are set to 255.255.255.0
.
Now, I am able to use nc
to establish communication between the two laptops. However, the connection is not established if I use WiFi interfaces instead of ethernet. I found that when I use WiFi, the connect()
syscall returns the error EHOSTUNREACH (No route to host)
. Can anyone tell me what I need to do in order to get this running on WiFi?
The source code for inet_config
is here:
/* 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;
}