Resolve IP address given in hexadecimal format using getnameinfo() - c

I have a simple program in C, which resolves IP addresses into hostnames.
#include <stdio.h> /* stderr, stdout */
#include <netinet/in.h> /* in_addr structure */
#include <strings.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc, char **argv) {
if ( argc == 2) {
struct sockaddr_in sa;
sa.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &sa.sin_addr);
char node[NI_MAXHOST];
int res = getnameinfo((struct sockaddr*)&sa, sizeof(sa), node, sizeof(node), NULL, 0, 0);
if (res)
{
printf("%s\n", gai_strerror(res));
return 1;
}
printf("%s\n", node);
return 0;
}
}
It works fine (i.e. ./a.out 10.1.1.2) but I need to modify it so that it accepts IP addresses in HEX format.
Is there some function to convert hex IP addresses to decimal?

I haven't tested this but should work.
#include <stdio.h> /* stderr, stdout */
#include <netinet/in.h> /* in_addr structure */
#include <strings.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc, char **argv) {
if ( argc == 2) {
struct sockaddr_in sa;
char a[2048] = {'\0'}; // placeholder not to overflow and initialised.
if( NULL == strchr(argv[1],'.') )
{
unsigned int unit0, uint1, uint2, uint3;
sscanf(argv[1], "%2x%2x%2x%2x", &uint0, &uint1, &uint2, &uint3);
sprintf(a,"%u.%u.%u.%u",uint0, uint1, uint2, uint3);
}
else
strcpy(a.argv[1]);
sa.sin_family = AF_INET;
inet_pton(AF_INET, a, &sa.sin_addr);
char node[NI_MAXHOST];
int res = getnameinfo((struct sockaddr*)&sa, sizeof(sa), node, sizeof(node), NULL, 0, 0);
if (res)
{
printf("%s\n", gai_strerror(res));
return 1;
}
printf("%s\n", node);
return 0;
}
}
Thanks

Related

Can't handle with a written on C-language UDP client-server problem for Mac

I am writing a udp client-server program for MacOS on C-language. Found a realisation of UDP-protocol, and it works properly on Linux (checked by myself), but when I try to build it on Mac it returns a warning of undeclared variable MSG_CONFIRM, and when I try to Run it, the program doesn't get or send any message.
I've already tried to find a solution in Google but there is no any. What can I try next?
This is the "client"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include "utils.h"
#define BUF_SIZE 1024
int main(int argc, char ** argv) {
Args args = get_args(argc, argv);
int sock_fd;
struct sockaddr_in server_addr;
if ( (sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
throw(BAD_EXIT_STATUS, "Socket creation failed");
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(args.port);
server_addr.sin_addr.s_addr = inet_addr(args.IP);
while(1) {
char buffer[BUF_SIZE];
char *hello = readline(stdin);
int n;
socklen_t len;
sendto(sock_fd, (const char *) hello, strlen(hello), MSG_CONFIRM,
(const struct sockaddr *) &server_addr, sizeof(server_addr));
n = recvfrom(sock_fd, (char *) buffer, BUF_SIZE, MSG_WAITALL,
(struct sockaddr *) &server_addr, &len);
buffer[n] = '\0';
printf("[Server]: %s", buffer);
}
close(sock_fd);
return 0;
}
This is the "server"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <math.h>
#include "utils.h"
#include "obrab.h"
#define BUF_SIZE 1024
#ifndef MSG_CONFIRM
#define MSG_CONFIRM 2048
#endif
int main(int argc, char** argv) {
Args args = get_args(argc, argv);
int sock_fd;
struct sockaddr_in server_addr, client_addr;
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
throw(BAD_EXIT_STATUS, "Socket creation failed");
}
memset(&server_addr, 0, sizeof(server_addr));
memset(&client_addr, 0, sizeof(client_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(args.port);
server_addr.sin_addr.s_addr = inet_addr(args.IP);
if (bind(sock_fd, (const struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) {
throw(BAD_EXIT_STATUS, "Bind failed");
}
while(1) {
char buffer[BUF_SIZE];
int n;
socklen_t len;
n = recvfrom(sock_fd, (char*) buffer, BUF_SIZE,
MSG_WAITALL, (struct sockaddr*) &client_addr, &len);
buffer[n] = '\0';
if (fork() == 0) {
char *hello = buffer;
sendto(sock_fd, (const char *) hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &client_addr, len);
} else {
printf("[Client]: %s", buffer);
}
}
}
I also created some header-files, there is a code below
"keys.h"
#ifndef keys_h
#define keys_h
// Struct for console arguments
unsigned short int prt;
char* L2ADDR;
char* L2LOGFILE;
unsigned short int L2WAIT;
typedef struct Args {
// unsigned short int (*L2PORT) (unsigned short int L2PORT); // -p
// char* (*L2WAIT) (char* L2ADDR); //-a
// char* (*L2LOGFILE) (char* L2LOGFILE); //-l
// unsigned short int (*L2WAIT) (unsigned short int L2WAIT); //-w
} Args;
char ip[] = "128.0.0.1";
unsigned a, b, c, d;
// reception and recognition of args
Args get_args(int argc, char **argv) {
Args args = {};
int opt;
char *opts = "palwvh";
while((opt = getopt(argc, argv, opts)) != -1) {
switch(opt) {
case 'p':
break;
case 'a':
if (sscanf(ip, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && a < 256) printf("YES\n");
else {
perror("NO\n");
exit(2);
}
break;
case 'l':
// currentParser = lblog;
break;
case 'w':
// currentParser = lbwait;
break;
case 'v':
printf("Version: 0.0.1 omega\n");
break;
case 'h':
printf("Use can use following keys: \n"
"\t-v -- prints out a version of the program;\n"
"\t-h -- output of the manual;\n"
"\t-w N -- Imitates job pausing serving process for N sec;\n"
"\t-d -- Set up program in daemon-mode;\n"
"\t-l /path/to/log -- set up a path to log-file;\n"
"\t-a ip -- Set up an adress in what server listens;\n"
"\t-p port -- Set up port, in what server listens.\n\n");
break;
default:
perror("Unknown key! Use -h key to read manual");
}
}
return args;
}
#endif /* keys_h */
"Utils.h"
#ifndef UTILS_H
#define UTILS_H
#define BAD_EXIT_STATUS 1
typedef struct Args {
int waitFor; // -w N
bool isDaemon; // -d
char* logFile; // -l path
char* IP; // -a IP
int port; // -p port
} Args;
Args get_args(int, char**);
void throw(int, char*);
char * readline(FILE*);
#endif
When you compile you need to write a command like this: ./server -a ip -p port (entered 127.0.0.1 and 8080) Then you need to run a client in another window with similar key parameters. In theory you write messages in client and then they are sent to server. But it doesn't send or get any message.

Encapsulation and auxiliary functions for using UDP sockets on a client and server

I am using the UDP auxiliary functions encapsulated below replacing the calls the functions of the sockets libraries to simulate and allow some testing on the UDP client and server. But I am not able to make the connection between them and pass the arguments correctly.
/********auxiliary functions for using UDP sockets*********/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <strings.h>
#include "tp_socket.h"
#define MTU 1024
int tp_mtu(void)
{
fprintf(stderr,"tp_mtu called\n");
return MTU;
}
int tp_sendto(int so, char* buff, int buff_len, so_addr* to_addr)
{
int count;
fprintf(stderr,"tp_sendto called (%d bytes)\n", buff_len);
count = sendto(so, (void*)buff, buff_len, 0,
(struct sockaddr*) to_addr, sizeof(struct sockaddr_in));
fprintf(stderr,"tp_sendto returning (sent %d bytes)\n", count);
return count;
}
int tp_recvfrom(int so, char* buff, int buff_len, so_addr* from_addr)
{
int count;
unsigned int sockaddr_len = sizeof(struct sockaddr_in);
fprintf(stderr,"tp_recvfrom called (%d bytes)\n",buff_len);
count = recvfrom(so,(void*)buff,(size_t)buff_len,0,
(struct sockaddr*) from_addr, &sockaddr_len);
fprintf(stderr,"tp_recvfrom returning (received %d bytes)\n",count);
return count;
}
int tp_init(void)
{
fprintf(stderr,"tp_init called\n");
return 0;
}
int tp_socket(unsigned short port)
{
int so;
struct sockaddr_in local_addr;
int addr_len =sizeof(local_addr);
fprintf(stderr,"tp_socket called\n");
if ((so=socket(PF_INET,SOCK_DGRAM,0))<0) {
return -1;
}
if (tp_build_addr(&local_addr,INADDR_ANY,port)<0) {
return -2;
}
if (bind(so, (struct sockaddr*)&local_addr, sizeof(local_addr))<0) {
return -3;
}
return so;
}
int tp_build_addr(so_addr* addr, char* hostname, int port)
{
struct hostent* he;
fprintf(stderr,"tp_build_addr called\n");
addr->sin_family = PF_INET;
addr->sin_port = htons(port);
if (hostname==NULL) {
addr->sin_addr.s_addr = INADDR_ANY;
} else {
if ((he=gethostbyname(hostname))==NULL) {
return -1;
}
bcopy(he->h_addr,&(addr->sin_addr.s_addr),sizeof(in_addr_t));
}
return 0;
}
My code at the moment of the UDP client:
/********clientUDP*********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include "tp_socket.h"
int main(int argc, char *argv[])
{
so_addr to_addr;
char *ip_server;
char my_buffer[10];
int port_servidor, tam_buffer;
if (argc != 5)
{
perror("Error");
exit(-1);
}
*ip_server = argv[1];
port_server = atoi(argv[2]);
char arquivo = argv[3];
tam_buffer = atoi(argv[4]);
tp_init();
tp_socket(port);
tp_build_addr(&to_addr, ip_server, port_server);
exit(0);
}
My code at the moment of the UDP server:
/********serverUDP*********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include "tp_socket.h"
int main(int argc, char *argv[])
{
so_addr my_addr;
int aux, so, mtu, port_server,tam_buffer,n;
char *archive;
char buffer[10];
FILE *file;
if (argc != 3)
{
perror("Error");
exit(-1);
}
port_server = atoi(argv[1]);
tam_buffer = atoi(argv[2]);
aux = tp_init();
if (aux < 0)
{
perror("error");
exit(aux);
}
mtu = tp_mtu();
so = tp_socket(port_server);
tp_recvfrom(so, buffer, 10 , &my_addr);
n = read( so,tam_buffer,1);
file = fopen(archive,"r");
if ( file != NULL )
{
n=fread(buffer,1,atoi(argv[2]),file);
while ( n > 0)
{
write(so,buffer,n);
n=fread(buffer,1, atoi(argv[2]),file);
}
} else
{
printf("error\n");
exit(0);
}
fclose(file);
shutdown(so,2);
close();
return 0;
}
Could someone please explain how I use the auxiliary functions to connect the client to the server and transfer files? I've be I've been locked up a long time at this stage.

Can't finish transferring a file when using a multi-threaded server in C

I have a multi-threaded client that can transfer a batch of files to a new directory that the client itself makes. My client used to use a single-threaded server.
For an assignment I'm supposed to transform my single-threaded server into a multi-threaded server that creates a new thread for each client request. I'm also supposed to time the whole operation and output it to the client (which I got to work when the server was single threaded). The code for both the multi-threaded client (which works with a single-thread server) and the multi-thread server (which does not work well) are below:
client.c
#include <sys/uio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <string.h>
#include <strings.h>
#include "Timer.h"
#define N_THREADS 10
char * files[] = {
"/usr/share/dict/words",
"/usr/include/sqlite3.h",
"/usr/include/tclDecls.h",
"/usr/include/bfd.h",
"/usr/include/libmng.h",
"/usr/include/elf.h",
"/usr/include/gmpxx.h",
"/usr/include/tkDecls.h",
"/usr/include/H5overflow.h",
"/usr/include/tcl.h",
"/usr/include/gmp-x86_64.h",
"/usr/include/curses.h",
"/usr/include/lcms.h",
"/usr/include/netapi.h",
"/usr/include/gcrypt.h",
"/usr/include/zlib.h",
"/usr/include/ldap.h",
"/usr/include/geos_c.h",
"/usr/include/kdb.h",
"/usr/include/tk.h",
"/usr/include/yaml.h"
};
#define files_length() (sizeof files / sizeof files[0])
void error(char *msg)
{
perror(msg);
exit(-1);
}
struct sockaddr_in make_server_addr(char *host, short port)
{
struct sockaddr_in addr;
bzero(&addr, sizeof addr);
struct hostent *hp = gethostbyname(host);
if ( hp == 0 )
error(host);
addr.sin_family = AF_INET;
bcopy(hp->h_addr_list[0], &addr.sin_addr, hp->h_length);
addr.sin_port = htons(port);
return addr;
}
int connect_socket(char *host, short port)
{
int status;
int tries = 3;
struct sockaddr_in addr = make_server_addr(host, port);
int s = socket(AF_INET, SOCK_STREAM, 0);
if ( s == -1 )
error("socket()");
status = connect(s, (struct sockaddr*)&addr, sizeof addr);
if ( status < 0 )
error("connect refused");
return s;
}
void request_file_from_server(int server_socket, char *file)
{
int len = strlen(file);
int n = write(server_socket, file, len);
if ( n != len )
error("short write");
}
void read_file_from_server(int server_socket, char *file)
{
char buf[BUFSIZ];
int n;
mode_t mode = 0666;
int ofd = open(file, O_WRONLY | O_CREAT, mode);
if ( ofd == -1 )
perror("open()");
while ( (n = read(server_socket, buf, BUFSIZ)) > 0 )
write(ofd, buf, n);
close(ofd);
}
struct Thread_data
{
int id;
pthread_t thread_id;
char * host;
short port;
char path[BUFSIZ];
};
void make_file_name(char *local_name, char *dir, char *original_path)
{
char *p = rindex(original_path, '/');
if ( !p )
error("rindex()");
sprintf(local_name, "%s/%s", dir, p+1);
}
int remote_copy(struct Thread_data * data, char * file)
{
int server_socket = connect_socket(data->host, data->port);
request_file_from_server(server_socket, file);
char local_name[BUFSIZ];
make_file_name(local_name, data->path, file);
read_file_from_server(server_socket, local_name);
close(server_socket);
}
void make_empty_dir_for_copies(struct Thread_data * data)
{
mode_t mode = 0777;
sprintf(data->path, "./Thread_%d", (data->id + 1));
mkdir(data->path, mode);
}
#define N_FILES_TO_COPY files_length() // copy them all
void *thread_work(void *arg)
{
struct Thread_data * data = (struct Thread_data *)arg;
make_empty_dir_for_copies(data);
for ( int i=0; i < N_FILES_TO_COPY; ++i )
remote_copy(data, files[i]);
pthread_exit(0);
}
void start_threads(char *host, short port, struct Thread_data thread_args[])
{
for ( int i = 0; i < N_THREADS; ++i )
{
struct Thread_data * t = &thread_args[i];
t->id = i;
t->host = host;
t->port = port;
pthread_create(&t->thread_id, NULL, thread_work, t);
}
}
void join_threads(struct Thread_data thread_args[], double *eTime)
{
for ( int i=0; i < N_THREADS; i++ )
pthread_join(thread_args[i].thread_id, NULL);
Timer_elapsedUserTime(eTime);
printf("Elapsed time for transferring all files: %lf\n", *eTime);
pthread_exit(0);
}
int main(int argc, char *argv[])
{
if ( argc != 3 )
{
fprintf(stderr, "Usage: %s host port\n", argv[0]);
exit(-1);
}
struct Thread_data thread_args[N_THREADS];
char *host = argv[1];
short port = atoi(argv[2]);
double eTime;
Timer_start();
start_threads(host,port,thread_args);
join_threads(thread_args, &eTime);
}
server.c
#include <sys/types.h>
#include <signal.h>
#include <sys/uio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <pthread.h>
#include <string.h>
#include "Timer.h"
#define BACKLOG 200
// more than this in the queue, and client connect will fail
#define NUM_THREADS 200
void error(char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(-1);
}
struct sockaddr_in make_server_addr(short port)
{
struct sockaddr_in addr;
memset(&addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
return addr;
}
int create_server_socket(short port)
{
int s = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
struct sockaddr_in my_addr = make_server_addr(port);
if ( s == -1 )
error("socket()");
bind(s, (struct sockaddr*)&my_addr, sizeof my_addr);
listen(s, BACKLOG);
return s;
}
void get_file_request(int socket, char *fileName)
{
char buf[BUFSIZ];
int n = read(socket, buf, BUFSIZ);
if ( n < 0 )
error("read from socket");
buf[n] = '\0';
strcpy(fileName, buf);
printf("Server got file name of '%s'\n", fileName);
}
void write_file_to_client_socket(char *file, int socket)
{
char buf[BUFSIZ];
int n;
int ifd = open(file, O_RDONLY);
if ( ifd == -1 )
error("open()");
while ( (n = read(ifd, buf, BUFSIZ)) > 0 )
write(socket, buf, n);
close(ifd);
}
void * handle_request(void * c_socket)
{
int *client_socket = (int*)c_socket;
char fileName[BUFSIZ];
get_file_request(*client_socket, fileName);
write_file_to_client_socket(fileName, *client_socket);
close(*client_socket);
pthread_exit(0);
return NULL;
}
void time_out(int arg)
{
fprintf(stderr, "Server timed out\n");
exit(0);
}
void set_time_out(int seconds)
{
struct itimerval value = {0};
// bzero(&value, sizeof value);
/* timerclear(&value.it_interval); timerclear(&value.it_value); */
value.it_value.tv_sec = seconds;
setitimer(ITIMER_REAL, &value, NULL);
signal(SIGALRM, time_out);
}
void accept_client_requests(int server_socket)
{
pthread_t threads;
int client_socket;
struct sockaddr_in client_addr;
socklen_t sin_size = sizeof client_addr;
set_time_out(10);
while ( (client_socket =
accept(server_socket, (struct sockaddr*)&client_addr, &sin_size)) )
{
set_time_out(10);
pthread_create(&threads,0, handle_request,&client_socket);
}
}
int main(int argc, char *argv[])
{
if ( argc != 2 )
error("usage: server port");
short port = atoi(argv[1]);
int server_socket = create_server_socket(port);
accept_client_requests(server_socket);
shutdown(server_socket, 2);
return 0;
}
The issue happens when using handle_request when I am using accept and creating a new pthread. It gets to whatever the last file is (in this case /usr/include/yaml.h), hangs and then times out. Without a timeout it would hang indefinitely.
I don't really know much about multi-threading with pthreads, so I'm just going off of my professors instructions which basically said to create the thread and handle the request like you would in a single threaded server. In my single threaded server, handle_request was passed in an int (which now gets converted).
Does anyone know why my server would hang on the last transferred file until it times out?
There's a flaw in the accept_client_requests function. You have a variable
int client_socket;
The address of that variable is passed to pthread_create
pthread_create(&threads,0, handle_request,&client_socket);
pthread_create passes the pointer to handle_request which stores it as a local pointer
int *client_socket = (int *)c_socket;
The problem is that the pointer is still pointing to the client_socket variable in the accept_client_requests function. So when accept_client_requests gets another connection, the client_socket is changed, and every thread currently running has its client_socket changed, which should cause all sorts of chaos.
The solution is to malloc an int to hold the client_socket, and then pass that address to the thread.
int *temp = malloc( sizeof(int) );
*temp = client_socket;
pthread_create(&threads, 0, handle_request, temp);
pthread_detach(threads);
When the thread is finished, it should free the memory.
The accept_client_requests function should also call pthread_detach on every thread that it creates, so that resources can be reclaimed when the thread finishes.
Without the pthread_detach the system will expect to see a pthread_join before cleaning up the thread.

Error in server programming

I'm trying to write a simple code for a server to print something from a function
This code gives me an error :
request for member ‘sin_addr’ in something not a structure or union
and I don't understand why
can you help me?
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
void printsin(struct sockaddr_in *s, char *str1, char *str2) {
printf("%s\n", str1);
printf("%s: ", str2);
printf("%d = ,", s.sin_addr.s_addr);
printf(" %d = ", s.sin_port);
printf("\n");
}
int main(int argc, char *argv[])
{
int socket_fd, cc, fsize;
struct sockaddr_in s_in, from;
struct { char head; u_long body; char tail;} msg;
socket_fd = socket (AF_INET, SOCK_DGRAM, 0);
bzero((char *) &s_in, sizeof(s_in)); /* They say you must do this */
s_in.sin_family = (short)AF_INET;
s_in.sin_addr.s_addr = htonl(INADDR_ANY); /* WILDCARD */
s_in.sin_port = htons((u_short)0x3333);
printsin( &s_in, "RECV_UDP", "Local socket is:");
fflush(stdout);
bind(socket_fd, (struct sockaddr *)&s_in, sizeof(s_in));
for(;;) {
fsize = sizeof(from);
cc = recvfrom(socket_fd,&msg,sizeof(msg),0,(struct sockaddr *)&from,&fsize);
//printsin( &from, "recv_udp: ", "Packet from:");
printf("Got data ::%c%ld%c\n",msg.head,(long) ntohl(msg.body),msg.tail);
fflush(stdout);
}
return 0;
}
Thank you
printf("%d = ,", s->sin_addr.s_addr);
printf(" %d = ", s->sin_port);
That should fix it you pass it in as a pointer then you never deference it.

Obtaining SubnetMask in C

I wanted to get the IP address and the subnet mask. Now the IP part is done, however I couldn't find any socket function that would return a structure with the subnet mask in it.
Does a socket function exist, that returns it in a structure?
Thanks!
In Unix using getifaddrs
struct ifaddrs haves a member named ifa_netmask (Netmask of interface)
#include <arpa/inet.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
int main ()
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_in *sa;
char *addr;
getifaddrs (&ifap);
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family==AF_INET) {
sa = (struct sockaddr_in *) ifa->ifa_netmask;
addr = inet_ntoa(sa->sin_addr);
printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr);
}
}
freeifaddrs(ifap);
return 0;
}
Output
Interface: lo Address: 255.0.0.0
Interface: eth0 Address: 255.255.255.0
In windows using IPHelper.
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
/* Note: could also use malloc() and free() */
int __cdecl main()
{
PIP_ADAPTER_INFO pAdapterInfo;
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *) MALLOC(sizeof (IP_ADAPTER_INFO));
GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
printf("\tIP Mask: \t%s\n", pAdapterInfo->IpAddressList.IpMask.String);
}
if (pAdapterInfo)
FREE(pAdapterInfo);
return 0;
}
Borrowed code from Linux Man page and referred to the code from Keine Lust:
#define _GNU_SOURCE /* To get defns of NI_MAXSERV and NI_MAXHOST */
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/if_link.h>
#include <string.h> /* strcasecmp() */
int get_addr_and_netmask_using_ifaddrs(const char* ifa_name,
char *addr, char *netmask)
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_in *sa;
char *s;
int found = 0;
if (getifaddrs(&ifap) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
for (ifa = ifap; ifa && !found; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
if (strcasecmp(ifa_name, ifa->ifa_name))
continue;
/* IPv4 */
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
sa = (struct sockaddr_in *) ifa->ifa_addr;
s = inet_ntoa(sa->sin_addr);
strcpy(addr, s);
sa = (struct sockaddr_in *) ifa->ifa_netmask;
s = inet_ntoa(sa->sin_addr);
strcpy(netmask, s);
found = 1;
}
freeifaddrs(ifap);
if (found)
return EXIT_SUCCESS;
return EXIT_FAILURE;
}
int main(void)
{
char *addr = malloc(NI_MAXHOST);
char *netmask = malloc(NI_MAXHOST);
if (!get_addr_and_netmask_using_ifaddrs ("enp6s0", addr, netmask))
printf("[%s]%s %s\n", __func__, addr, netmask);
else
printf("interface error.\n");
free(addr);
free(netmask);
return 0;
}

Resources