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