I am trying to receive the IP address from a given domain. The domain is sent from a client to a local server and in the server I need to find the IP.
This is my code:
int hostname_to_ip(char * hostname, char* ip)
{
struct hostent *he;
struct in_addr **addr_list;
int i;
if ( (he = gethostbyname( hostname ) ) == NULL)
{
herror("gethostbyname");
return 1;
}
addr_list = (struct in_addr **) he->h_addr_list;
for(i = 0; addr_list[i] != NULL; i++)
{
strcpy(ip , inet_ntoa(*addr_list[i]) );
return 0;
}
return 1;
}
int main() {
int s;
struct sockaddr_in server, client;
int c, l, i;
char buffer[100];
char ip[100];
struct hostent *ipAddress;
struct in_addr **addr_list;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0) {
printf("Socket creation error!\n");
return 1;
}
memset(&server, 0, sizeof(server));
server.sin_port = htons(1234);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
if (bind(s, (struct sockaddr *) &server, sizeof(server)) < 0) {
printf("Bind error!\n");
return 1;
}
l = sizeof(client);
memset(&client, 0, sizeof(client));
for (i = 0; i < 10000; i++) {
recvfrom(s, &buffer, sizeof(buffer), MSG_WAITALL, (struct sockaddr *) &client, &l);
printf("%s\n", "Client connected: ");
printf("%s\n", buffer);
char *host = buffer;
hostname_to_ip(buffer, ip);
printf("%s\n", ip);
}
close(s);
}
Message received is: unknown host and I cannot find why.
I am sure that i send a correct domain such as "www.google.com"
It looks like this for loop is malformed:
for(i = 0; addr_list[i] != NULL; i++) {
strcpy(ip , inet_ntoa(*addr_list[i]) );
return 0;
}
It will bail out and return after the very first iteration.
I would start by fixing that.
Related
I am trying to connect to my local UNIX server i made from another remote device. the Server is up and listening to the port i specified. i also added a new firewall rule to open that port but still my client cannot connect. it shows ERROR CONNECTION REFUSED
here is my server code
int main() {
int fd, i,svclient,rval,msg;
int clients[10], num_clients;
fd_set read_set,write_set;
char buf[100];
struct sockaddr_in addr;
if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
bzero((char *) &addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(4001);
//strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
//strcpy(addr.sun_path, NAME);
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("bind error");
exit(-1);
}
printf("Bind complet...\n");
if (listen(fd, 20) == -1) {
perror("listen error");
exit(-1);
}
num_clients = 0;
int size = sizeof(fd);
while (1) {
int clientfd;
struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
for (i = 0; i < num_clients; i++) { //at first this part will not excute
FD_SET(clients[i], &read_set);
}
select(fd + num_clients + 1, &read_set, NULL, NULL, NULL);
if (FD_ISSET(fd, &read_set)) {
if ( (clients[num_clients++] = accept(fd,(struct sockaddr*)&client_addr,&addrlen)) == -1) {
perror("accept error");
continue;
}
/*printf("incoming message..................... !\n \n");*/
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
for (i = 0; i < num_clients; i++) {
if (FD_ISSET(clients[i], &read_set)) {
msg = read(clients[i], buf, sizeof(buf));
if(msg > 0){
buf[msg] = 0;
int savedclnt = clients[i];
printf("%s \n \n", buf);
/*for(int p=0;p<num_clients;p++)
{
if( clients[p]!= savedclnt){
write(clients[p],buf,msg);
}
}*/
}
}
}
}
}
and my client
int main( )
{
struct uci_context *uci;
uci = uci_init();
int sockfd;
int ret;
struct sockaddr_in dest;
struct addrinfo hint, *res = NULL;
struct hostent *host;
char *hostip;
char *string;
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
puts("Unble to create socket");
exit(1);
}
hostip = ucix_get_option(uci, "pack_mon", "pack_monitoring", "address");
string = ucix_get_option(uci, "pack_mon", "pack_monitoring", "port");
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(atoi(string));
memset(&hint, '\0', sizeof hint);
hint.ai_family = PF_UNSPEC;
hint.ai_flags = AI_NUMERICHOST;
printf(" %s- %s\n", hostip, string );
if(isdigit(hostip[0])){
ret = getaddrinfo(hostip, NULL, &hint, &res);// this is more efficient than inet_addr
if (ret) {
exit(1);
}
}else if( (host = gethostbyname(hostip)) != 0){
memcpy((char*)&dest.sin_addr , (char*)host->h_addr , (sizeof dest.sin_addr)+1);
}else{
exit(1);
printf("cannot resolve ip address");
}
if ( connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0 )
{
perror("ERROR Connecting" );
exit(1);
}else{
printf("Port number %s is open.....\n",string);
}
char *message;
message = "help";
write(sockfd,message,strlen(message));
close(sockfd);
freeaddrinfo(res);
return 0;
}
FIREWALL RULE
sudo iptables -I INPUT -p tcp --dport 4001 -j ACCEPT
Error is :
192.168.10.155- 4001
ERROR Connecting: Connection refused
and this logs are coming from this codes :
printf(" %s- %s\n", hostip, string );
perror("ERROR Connecting");
exit(1);
Your client has no code to specify the IP address it wants to connect to. All the code that could do that has been commented out.
Update: Now your bug is here:
strncpy((char*)&dest.sin_addr , (char*)host->h_addr , sizeof dest.sin_addr);
The strncpy function is only suitable for C-style strings. You need to use memcpy or something similar. This will only copy part of the IP address if any octet other than its last one (in network byte order) is zero.
Update: Now your bug is here:
printf("%d\n", connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0);
perror("hmmmm" );
exit(1);
This calls connect, then calls printf and then calls perror. The problem is, the call to printf can modify errno even if it succeeds. Thus your call to perror can print a totally irrelevant error message.
Using thread, I wanted to launch UDP server on background.
But the server start and loop forever checking if any packet is received.
The same thread work fine if I use TCP server instead.
the test code is the following:
int udp_server_listen () {
printf("udp_server_listen \n");
int res;
unsigned char rsp_buf[1024];
struct sockaddr_in src;
socklen_t srclen;
memset(&src, 0, sizeof(src));
srclen = sizeof(src);
listen(s , 3);
//Accept and incoming connection
int c = sizeof(struct sockaddr_in);
int client_sock;
while( (client_sock = accept(s, (struct sockaddr *)&src, (socklen_t*)&c)) )
{
sleep(1);
printf("OK \n");
}
}
void *thread_udp_cr_listen (void *v)
{
udp_server_listen();
return NULL;
}
int s;
int main()
{
printf("start test \n");
struct sockaddr_in *local = malloc(sizeof (struct sockaddr_in *));
s = socket(AF_INET, SOCK_DGRAM, 0); // UDP
printf("create socket end\n");
int reusaddr = 1;
int reusport = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0)
{
printf("setsockopt(SO_REUSEADDR) failed \n");
}
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &reusport, sizeof(int)) < 0)
{
printf("setsockopt(SO_REUSEPORT) failed \n");
}
struct timeval tv;
tv.tv_sec = 2; /* 30 Secs Timeout */
tv.tv_usec = 0; // Not init'ing this can cause strange errors
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
fcntl(s, F_SETFL, O_NONBLOCK);
printf(" Bind to a specific network interface and a specific local port\n");
int i = 0;
for(;i<6;i++)
{
if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0)
{
printf("bind Faild %d\n", i);
sleep(1);
continue;
}
break;
}
error = pthread_create(&udp_cr_server_thread, NULL, &thread_udp_cr_listen, NULL);
if (error<0)
{
printf("thread error \n");
}
pthread_join(udp_cr_server_thread, NULL);
}
You have one serious problem here:
struct sockaddr_in *local = malloc(sizeof (struct sockaddr_in *));
because you're just allocating the size of a pointer instead of the size of the struct itself.
This should of course be:
struct sockaddr_in *local = malloc(sizeof (struct sockaddr_in));
Two more problems with the same variable in this line:
if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0)
This should be:
if (bind(s, (struct sockaddr *)local, sizeof(*local)) < 0)
The client reads a number, sends it to the server which finds its divisors, then the server sends the divisosr back to client which prints them.
int main(){
int s;
struct sockaddr_in server,client;
int l, conn;
s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0){
printf("Error on creating the server.");
return 1;
}
memset(&server, 0, sizeof(server));
server.sin_port = htons(1234);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
if (bind(s,(struct sockaddr *) &server, sizeof(server)) < 0){
printf("Eroare la bind.");
return 1;
}
listen(s,5);
l = sizeof(client);
memset(&client, 0, sizeof(client));
while (1){
uint16_t n, array[10], arraytosend[10];
conn = accept(s,(struct sockaddr *) &client,&l);
recv(conn, &n, sizeof(n), MSG_WAITALL);
n = ntohs(n);
int d, i=0;
for (d=2; d<=n/2; d++){
if ( n % d == 0){
arraytosend[i] = htonl(array[d]) ;
i++;
}
}
send (conn, &array, sizeof(array), 0);
close(conn);
}
}
Client:
int main(){
uint16_t n, array[10], arrayrec[10];
struct sockaddr_in server;
int c;
c = socket(AF_INET, SOCK_STREAM, 0);
if (c < 0){
printf("Eroare la creare socket client.");
return 1;
}
memset(&server, 0, sizeof(server));
server.sin_port = htons(1234);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
if (connect(c, (struct sockaddr *) &server, sizeof(server))< 0){
printf("Eroare la conectare.");
return 1;
}
printf("Give a number: ");
scanf("%hu", &n);
n = htons(n);
send(c,&n, sizeof(n),0);
recv(c, &array, sizeof(array), MSG_WAITALL);
int p=0;
p = htons(p);
for (p=0; p<10; p++){
array[p] = ntohl(arrayrec[p]);
printf("%hu", array[p]);
}
close(c);
}
When I'm running the server, then the client, it prints : 0000000000
Could somebody help me, please ?
enum recstate {
initial
};
int num_clients = 0;
static void addclient(int fd, struct in_addr addr){
struct client *p = (struct client *) malloc (sizeof(struct client));
if (!p) {
fprintf(stderr, "out of memory!\n");
exit(1);
}
printf("Adding client %s\n", inet_ntoa(addr));
p->fd = fd;
p->next = top;
p->state = initial;
top = p;
num_clients++;
}
struct client {
int fd; // socket descriptor for this client
enum recstate state; // current state of data transfer for this client
struct client *next; // a pointer to the next client in the list
struct in_addr ipaddr;
} *top = NULL;
int main(int argc, char* argv[]){
int listenfd, clientfd, maxfd, nready;
struct client *p;
struct sockaddr_in self, client;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&self, '\0', sizeof(self));
self.sin_family = AF_INET;
self.sin_addr.s_addr = INADDR_ANY;
self.sin_port = htons(PORT);
if (bind(listenfd, (struct sockaddr *) &self, sizeof(self))){
perror("bind");
exit(1);
}
if (listen(listenfd, 5) < 0){
perror("listen");
exit(1);
}
while (1){
fd_set allset, rset;
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
maxfd = listenfd;
rset = allset;
for (p = top; p; p = p->next){
FD_SET(p->fd, &allset);
if (p->fd > maxfd){
maxfd = p->fd;
}
}
if(FD_ISSET(listenfd, &rset)){
printf("Listenfd is ready\n");
len = sizeof(client);
if ((clientfd = accept(listenfd, (struct sockaddr *) &client, &len)) < 0){
perror("accept");
return(1);
}
else {
printf("Connection from %s\n", inet_ntoa(client.sin_addr));
addclient(clientfd, client.sin_addr);
FD_SET(clientfd, &rset);
printf("clientfd has been added to fdset\n");
if(p->state == initial){ //cannot get into this if statement
printf("now in initial state\n");
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
if(nready == 0){
printf("timeout happened\n");
continue;
}
else if(nready == -1){
perror("select");
continue;
}
else if (nready > 0){
printf("Data is now available.\n");
continue;
}
if (FD_ISSET(listenfd, &rset)){ //returns a value for fd in rset
//read data into file
}
}
}
}
}
}
This is part of my server code.
I'm trying to send files from the client to the server, but when I send the files from the client, the server will execute until just above the if(p->state == initial) statement, and hangs there. When I terminate the server, it'll give me a segmentation fault: 11 error.
Also, I'm using select() inside the initial state to allow multiple clients to connect simultaneously.
Don't know where I went wrong, any help would be greatly appreciated.
Thanks.
for (p = top; p; p = p->next){
Unless I'm mistaken, you loop until p is NULL
if(p->state == initial){
and then you dereference p.
KABOOM.
I've been trying to receive data on a server socket from a client with the following code,
server.c
int startServer(uint16_t myPort)
{
int listenFd = 0, connfd = 0;
struct sockaddr_in serv_addr;
listenFd = socket(AF_INET, SOCK_STREAM, 6);
if (listenFd == -1) {
perror("socket");
return EXIT_FAILURE;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(myPort);
if (-1 == bind(listenFd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) {
perror("bind");
return EXIT_FAILURE;
}
if (-1 == listen(listenFd, 10)) {
perror("listen");
return EXIT_FAILURE;
}
printf("Server listening on %d\n", myPort);
int n = 0, k;
char recvBuff[1024];
struct sockaddr_in conn_addr;
unsigned int len = sizeof(conn_addr);
while(1)
{
connfd = accept(listenFd, (struct sockaddr*)NULL, NULL);
n = recv(connfd, &recvBuff, 1023, 0);
printf("Recd: %d bytes\n",n);
for (k=0; k<16; ++k) { printf("%d: 0x%02X, ", k, recvBuff[k]); }
sleep(1);
}
}
and in client.c
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
uint32_t dataVal = 0xa0b0c0d0;
int res = write(sockfd, (void*)&dataVal, sizeof(dataVal));
printf("%d bytes sent\n", res);
close(sockfd);
return 0;
}
However with this I see the server saying it received the bytes but the line after that printing the bytes (in a for loop) doesn't ever seem to be executed. Does anyone know what I am doing wrong here?
Add printf("\n"); after the for loop, or "\n" to the printf inside the for loop.
printf writes to stdout, which is buffered. This means that output will not display until the buffer is filled, flushed, or a newline is sent. As such, it is easiest to ensure output by sending a newline.