Resolving a domain name to an IP address in C - c

I have been trying to figure out how to do this for a day or two now. I have tried to copy code online too and I keep getting a segmentation fault for some reason and I don't have clue why.
Here is my code I currently have. (Copied from a YouTube video in which the code ran flawlessly.)
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <netdb.h>
int main(int argc, char *argv[]){
struct hostent *host_info;
struct in_addr *address;
char input[20];
strcpy(input, "stackoverflow.com");
printf("Will do a DNS query on: %s\n", input);
host_info = gethostbyname(input);
address = (struct in_addr *) (host_info->h_addr);
printf("%s has address %s\n", input, inet_ntoa(*address));
}

I guess most of the gethostbyname function fails to execute. You can check whether its return value is null. In addition, you can try the inet_ntop function instead of the inet_ntoa function.

Related

Simulate a server-side GET request for a C program

I am currently investigating a compiled C program. I know that it makes several network requests due to several calls to socket, gethostbyname and connect throughout the code. Furthermore, I know it is making a GETrequest because i have run strings on the program and found one.
I would like to run this program so that I can investigate it without it making any network calls; however to do this I would have to simulate a get request just with the functions given.
I have the following code, which I have compiled and added to LD_PRELOAD:
#include <netdb.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol) {
fprintf(stderr, "socket(%d, %d, %d)\n", domain, type, protocol);
// TODO Return actual socket which contains request
return 1;
}
struct hostent HOST;
struct hostent *gethostbyname(const char*name) {
fprintf(stderr, "gethostbyname(%s)\n", name);
return &HOST;
}
int connect(int sockfd, const struct sockaddr *addr, socklen_t addr_len) {
int name_len = addr_len - sizeof(struct sockaddr);
fprintf(stderr, "Connecting to: %*.s\n", name_len, addr->sa_data);
return 0;
}
Which appears to work, but I can make little sense of what it prints to and receives from the socket.
I am also open to other solutions to the problem.

How can I resolve this error: segmentation fault?

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[]){
int sockfd;
struct sockaddr_in serv_addr;
struct hostent *hp;
char buff[100];
//Create socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
perror("Failed to create socket!");
exit(1);
}
serv_addr.sin_family = AF_INET;
hp = gethostbyname(argv[1]); *
I think the error might be on the above line but I don't know how to solve
this.
When I compile, build and run this code in Geany, Linux, I get a segmentation fault error message. Why is it so and how can I resolve it?
You need to check that argc[1] exists.
A simple :
if (!argv[1])
return (-1);
will probably do the trick.
Tip : Valgrind and GDB are two very powerful tools to find where your errors come from and solve them.
It takes a bit of time to get used to reading the logs from these but I guarantee that once you'll be used to it, not only will most of your timeouts and SegFaults be much easier to solve but you'll also be able to optimise the memory consumption of your programs as it tracks memory leaks, allocs and free(s).
If you use linux,
ulimit -a
ulimit -c ulimited // set core file size limitless
then run executable again.A core file will be created.This is snapshot of last stack before segmentation fault.
gdb [executable] core
Now You can see where segmentation fault raises.
I think your problem lies here
hp = gethostbyname(argv[1]);
you should have sent something on console as parameter otherwise this space (argv[1]) is invalid thus segmentation fault occurs.
In your case parameter should be name of computer you are trying to connect to. For example:
./program hosToConnectTo
should do the trick.

Segmentation fault generated by mkfifo() in C

I've been trying to debug this for a few hours now and I'm still stuck...
I get a segmentation fault with a "mkfifo" call in this code (it is only a part of my entire code, since I figured the rest was not relevant here) :
#include "marketfunc.h"
#include "error.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define PIPE_PATH "./pipe.fifo"
struct myStruct
{
int x;
int y;
int z;
};
struct myStruct *s;
int main(int argc, char **argv)
{
s = malloc(sizeof(struct myStruct));
// 'int marketfunc_init(int x)' is defined in a perfectly working extern library
if(marketfunc_init(1) == -1) error("failed to initialize marketfunc library", 5);
printf("test1\n");
// Segmentation fault
if(mkfifo(PIPE_PATH, 0666) == -1) error("failed to create pipe", 1);
printf("test2\n");
//...
}
Which produces this output (executableFile beeing the name of my file):
test1
bin/executableFile: Segmentation fault (core dumped)
The gdb backtrace produces this:
#0 strchrnul () at ../sysdeps/x86_64/strchr.S:32
#1 0x00007ffff7a5ed82 in __find_specmb (format=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>)
at printf-parse.h:108
#2 _IO_vfprintf_internal (s=0x7fffffffb5a0, format=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>,
ap=0x7fffffffdd58) at vfprintf.c:1332
#3 0x00007ffff7a63f31 in buffered_vfprintf (s=s#entry=0x7ffff7dd41c0 <_IO_2_1_stderr_>,
format=format#entry=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>, args=args#entry=0x7fffffffdd58)
at vfprintf.c:2356
#4 0x00007ffff7a5eeae in _IO_vfprintf_internal (s=0x7ffff7dd41c0 <_IO_2_1_stderr_>,
format=format#entry=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>, ap=ap#entry=0x7fffffffdd58)
at vfprintf.c:1313
#5 0x00007ffff7b0c595 in error_tail (status=status#entry=4199947, errnum=errnum#entry=1,
message=message#entry=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>, args=args#entry=0x7fffffffdd58)
at error.c:201
#6 0x00007ffff7b0c6ed in __error (status=4199947, errnum=1,
message=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>) at error.c:251
#7 0x0000000000400b78 in main (argc=1, argv=0x7fffffffdf38) at src/executableFile.c:75
Though the "pipe.fifo" file is created...
Thanks in advance for your help !
EDIT:
error is simply defined as such in error.c and it's signature in error.h:
#include "error.h"
#include <stdlib.h>
#include <stdio.h>
void error(char *msg, int ret)
{
perror(msg);
exit(ret);
}
If you look at the stack trace, you will see that the call to error() shows up as:
0x00007ffff7b0c6ed in __error (status=4199947, errnum=1, message=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>) at error.c:251
This is NOT the error() function that you defined. But rather, it is the error() function defined in error.h with the following signature:
void error(int status, int errnum, const char *format, ...);
See error.h.
As you can see, this function expects a char* format as the last argument, which is getting some junk off the stack 0xffffffffffffff60, because you don't pass in the third argument at all. It would seem that the linker is resolving the call to error() to the wrong function.
As a quick fix, I would rename things as follows:
rename your file `error.h` to `error_my.h`
your definition of `error()` to, say, `error_my()`
replace the calls to `error()` with `error_my()`.
Your code would look like:
#include "marketfunc.h"
#include "error_my.h" // <=======================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define PIPE_PATH "./pipe.fifo"
struct myStruct
{
int x;
int y;
int z;
};
struct myStruct *s;
int main(int argc, char **argv)
{
s = malloc(sizeof(struct myStruct));
// 'int marketfunc_init(int x)' is defined in a perfectly working extern library
if(marketfunc_init(1) == -1) error_my("failed to initialize marketfunc library", 5); // <=======================
printf("test1\n");
// Segmentation fault
if(mkfifo(PIPE_PATH, 0666) == -1) error_my("failed to create pipe", 1); // <=======================
printf("test2\n");
//...
}
Print out errno when mkfifo() fails to figure out why it is failing in the first place.

cant get libsensors to work properly

here is my code concerning libsensors.
libraries:
#include <unistd.h>
#include <sensors/sensors.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
code concerning libsensors:
char sd[16384]="^\0",bf[1];
char buf2[8192]="^\0";
sensors_chip_name const* scn;
int c=0;
int t4=1;
while((scn=sensors_get_detected_chips(0,&c))!=0)
{
sensors_feature const *fea;
int f=0;
strcat(sd,scn->prefix);
printf("%s",scn->prefix);
strcat(sd,":");
strcat(sd,scn->path);
strcat(sd,"(");
while((fea=sensors_get_features(scn,&f))!=0)
{
strcat(sd,fea->name);
strcat(sd,"(");
sensors_subfeature const *sb;
int s=0;
while((sb=sensors_get_all_subfeatures(scn,fea,&s))!=0)
{
t4++;
strcat(sd,sb->name);
strcat(sd,",");
int t3=-1;
int i=0;
char t8[sizeof(sb->number)];
memcpy(&t8,&(sb->number),sizeof(sb->number));
strcat(sd,t8);
strcat(sd,"!");
}
strcat(sd,")");
}
strcat(sd,")");
}
so when I try to print anything nothing happens. char array called sd returns empty. it simply seems that there are no sensors to be read.
when I run sensors from terminal it works perfectly fine. I see a couple of cores and chips temps.
I implemented this code from some post on here and to be frank I don't totally understand it.
Posting #user3629249 comment as a community answer.
It it required to first call sensors_init() otherwise the chips list will be empty.
This function expects a sensors configuration file as argument, or NULL to use the default one.
Also, you can find an usage example in this related question: Has anyone been able to use libsensors properly?

Name server IP of linux machine using C language

I have to get name server IP of my system using C language.I am using Linux machine.
I have tried.
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/cdefs.h>
int main()
{
int res_init(void);
printf("_res.nscount %d\n",_res.nscount);
//printf("_res.nsaddr_list[0] %s\n",_res.nsaddr_list[0]);
return 0;
}
But I am getting _res.nscount as 0.Am I doing anything wrong?
You declared res_init() instead of calling it. Try:
Int main()
{
res_init();
/* ... */
However, nsaddr_list[0] isn't a string, so you won't be able to print it with printf("%s"). You'll have to use inet_ntoa() or similar to convert its sin_addr.s_addr value to a printable string.

Resources