I'm newbee and just making my first steps in c++ under linux.
So I have some task about sockets. I'm following guides, especially this one. And code examples are not working. I started with this:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "echo_socket"
int main(void)
{
int s, s2, t, len;
struct sockaddr_un local, remote;
char str[100];
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(s, (struct sockaddr *)&local, len) == -1) {
perror("bind");
exit(1);
}
return 0;
}
I've figured out that to compile it (Code::Blocks) there must be one more include:
#include <unistd.h>
But after successful run I'm getting message "Bind: Operation not permitted". What is wrong? I've tried to run it under root and still it is not working.
Some Unix systems won't allow you to create sockets everywhere. Make sure you have the right permissions and the right file system underneath. (Fat32 as it is used on sdcards in mobile phones won't allow additional flags to files and might get you into trouble)
Finally on newer systems there are security things running like selinux which might block the creation of sockets.
On my example I had to change
#define SOCK_PATH "echo_socket"
to
#define SOCK_PATH "/dev/socket/echo_socket"
after that it worked immediately. (executable started in root shell)
Because of no permission.
You can
#define SOCK_PATH "/home/username/echo_socket"
and it will run normally.
Related
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.
#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.
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.
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.
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.