How can I resolve this error: segmentation fault? - c

#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.

Related

Resolving a domain name to an IP address in 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.

socket creation return -1 (Operation not permitted) [duplicate]

I'm learning how to work with raw sockets in Linux. I'm trying to create a socket like that:
if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
perror("socket() failed");
exit(-1);
}
But all I got after launch is:
socket() failed: Operation not permitted
I know that only root can create raw sockets, but if I run it with SUID bit or sudo - the
problem is the same. What's wrong? The system is Ubuntu 11.04.
Maybe I'm including needless headers?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
And I'm wondering - why SUID is useless?
My money on you not running your code correctly.
I've copied and pasted your exact code into an empty main(). I get the same error if I run it as myself, but it runs correctly under sudo. This is on Ubuntu.
The code:
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int sd;
if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
perror("socket() failed");
return -1;
}
return 0;
}
Run as myself:
aix#aix:~$ ./a.out
socket() failed: Operation not permitted
aix#aix:~$
Run as root:
aix#aix:~$ sudo ./a.out
aix#aix:~$
according to man: Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets
So you could run you application with sudo as was suggested below or set CAP_NET_RAW capability to it (actually you'll need CAP_NET_ADMIN too):
# setcap cap_net_raw,cap_net_admin=eip PATH_TO_YOUR_APPLICATION
Details could be found at http://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt
Header will not affect it in anyway.
Even if you would be adding some more unnecessary files it will not affect the working of the program.

nothing happens when trying to listen on a port

I'm trying to write a very simple program that just listens on a predefined port.here is the code:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd;
struct addrinfo hints,*res;
memset(&hints,0,sizeof(hints));
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
hints.ai_flags=AI_PASSIVE;
getaddrinfo(NULL,"5050",&hints,&res);
sockfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);
bind(sockfd,res->ai_addr,res->ai_addrlen); //returns 0(success)
listen(sockfd,1);//returns 0(success)
return 0;
}
but there is no sign of listening anywhere.i used netstat -l command to check if the program is listening or not.
You are missing an accept() call.
Also you are exiting from the program.
The socket would be active for the duration of your process only.
You have most of the parts but neglected to call accept(). Without that your program probably just returns quickly without doing anything useful.
Your program does listen, but it exits immediately, so anything it has done vanishes into the ether. If you want to accept connections you will have to call accept().
You also need to error-check every one of those calls. You can't just assume they all succeeded.

Loopback example using INADDR_LOOPBACK does not work

I am trying to set a loopback socket in C but nothing works. I'm trying to make a function that opens a socket with the loopback address ,send data to socket and from another function read the data but nothing works. I believe that I don't know how to use the functions related to connections. Here is what I accomplished so far:
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <iostream>
#include <cerrno>
#include <pthread.h>
int internal_s;
void function1(){
if ((internal_s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
perror_exit("socket");
/* Find server address */
struct sockaddr_in loopback;
struct sockaddr *serverptr = (struct sockaddr*)&loopback;
/*Convert port number to integer*/
loopback.sin_family = AF_INET; /* Internet domain */
loopback.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
loopback.sin_port=htons(10000);
/* Initiate connection */
if (bind(internal_s,serverptr, sizeof(loopback))<0)
perro("bind");
int test=1;
err=write(internal_s,&test,sizeof(int));
if(err<0)
perror(write);
}
void Open_Internal_sock(int socket_s){
struct sockaddr_in loopback;
struct sockaddr *serverptr = (struct sockaddr*)&loopback;
/*Convert port number to integer*/
loopback.sin_family = AF_INET; /* Internet domain */
loopback.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
loopback.sin_port=htons(10000);
/* Initiate connection */
if (bind(socket_s,serverptr, sizeof(loopback))<0)
perror("bind");//Invalid argument
int test;
if(read(socket_s,&test,sizeof(int))<0)
perror("read");//herer it prints:Transport endpoint is not connected
}
int main(){
function1(i);
Open_Internal_sock(internal_s);
}
In short, the client(sender, "writer") needs to call connect() and the server(listener, receiver, "reader") needs to cal listen() and accept().
The server and client also need separate threads of execution, because some of the socket operations block and would cause a single thread of execution to stop forever. Easiest is probably to make a server.c and client.c as separate programs.
Additionally, try compiling your code with warnings enabled, e.g., gcc -Wall . There are now quite many errors, which the compiler can point out for you. For clearer messages, try clang instead of gcc as a compiler.
I suggest looking at http://kohala.com/start/unpv12e/unpv12e.tar.gz . Unpack with tar xzvf unpv12e.tar.gz and look at unpv12e/tcpcliserv/tcpcli01.c and unpv12e/tcpcliserv/tcpserv01.c . In case you are tempted to copy&paste, notice that the Capital letters in, e.g., Listen() need to be changed to lower case for the code to work without unpv headers. This change also removes all checks for errors, so put in your own error handling.

Why I cant create raw socket in Ubuntu?

I'm learning how to work with raw sockets in Linux. I'm trying to create a socket like that:
if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
perror("socket() failed");
exit(-1);
}
But all I got after launch is:
socket() failed: Operation not permitted
I know that only root can create raw sockets, but if I run it with SUID bit or sudo - the
problem is the same. What's wrong? The system is Ubuntu 11.04.
Maybe I'm including needless headers?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
And I'm wondering - why SUID is useless?
My money on you not running your code correctly.
I've copied and pasted your exact code into an empty main(). I get the same error if I run it as myself, but it runs correctly under sudo. This is on Ubuntu.
The code:
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int sd;
if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
perror("socket() failed");
return -1;
}
return 0;
}
Run as myself:
aix#aix:~$ ./a.out
socket() failed: Operation not permitted
aix#aix:~$
Run as root:
aix#aix:~$ sudo ./a.out
aix#aix:~$
according to man: Only processes with an effective user ID of 0 or the CAP_NET_RAW capability are allowed to open raw sockets
So you could run you application with sudo as was suggested below or set CAP_NET_RAW capability to it (actually you'll need CAP_NET_ADMIN too):
# setcap cap_net_raw,cap_net_admin=eip PATH_TO_YOUR_APPLICATION
Details could be found at http://ftp.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt
Header will not affect it in anyway.
Even if you would be adding some more unnecessary files it will not affect the working of the program.

Resources