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
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.
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.
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.
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.
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;
}