Socket programming C - bind error - c

I try to create a function to open a socket (i will have multiple socket in the future) called libf_build_udp_socket. But when it comes to bind i got the error cannot assign requested address and if i bypass this bind i got an error when sending a cmd.
If i don't use my function and integrate directly the code in my main, it works perfectly.
For the explanation i have a computer under linux that have to send cmd and received log from different equipment such as signal receiver...
Here is my full code, so maybe you will better understand my goals.
/* Standard Linux headers */
#include <stdio.h> //printf
#include <string.h> //memset
#include <stdlib.h> //exit(0);
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/times.h>
#include <unistd.h>
#include <errno.h>
/* DEFINE */
#define IP_RX "192.168.0.10" //notre IP=192.168.0.5
#define BUFFLEN 1024 //Max length of buffer
#define PORT_RX 3000 //The port on which to send data
unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port);
int main (void)
{
/*
** Definition of the local variables.
*/
//SOCKET
struct sockaddr_in addr_rx;
int serv_len_rx=sizeof(addr_rx);
int socket_fd_rx;
unsigned short int socketStatus; /* Socket return status */
//FD
fd_set readfds;
//BUFFER & CMD
char recepbuff[BUFFLEN];
char cmd[BUFFLEN], cmd_final[BUFFLEN];
//OTHER
int i, recv;
char choice;
int loop=1;
//TIMEOUT STRUCT
struct timeval tv;
tv.tv_sec=0; /*timeout de 0sec*/
tv.tv_usec=1000; //NE MARCHE PAS SI =0
/*
** Initialisation of the local variables.
*/
memset(recepbuff, '0' ,sizeof(recepbuff)); /*pareil que bzero*/
i=0;
/*
** Creating the socket
** call socket (it creates an endpoint for communication and
** returns the socket descriptor.
** To create an UDP socket here are the param
** The protocol family should be AF_INET
** The protocol type is SOCK_DGRAM
** The protocol should beset to default ie
** DEF_PROTOCOL wich is default so 0. );
*/
//OPENING AND SETTING SOCKET RX
socketStatus = libf_build_udp_socket(&socket_fd_rx, IP_RX, PORT_RX);
if (socketStatus>0)
{
printf("Could not create the socket, code error %d\n", socketStatus);
return 0;
}
/* Messaging*/
while(1)
{
printf ("\n//Boucle %d\n", i);
//clear the buffer by filling null, it might have previously received data
memset(recepbuff, '\0' ,sizeof(recepbuff));
loop=1;
//preparing cmd
printf("Enter command :");
fgets(cmd, sizeof(cmd) , stdin);
snprintf(cmd_final, sizeof (cmd_final), cmd, "\r\n"); /*adding 0d 0a to the cmd*/
//send cmd
if ( (sendto(socket_fd_rx , cmd_final, BUFFLEN , 0 , (struct sockaddr *)&addr_rx, serv_len_rx) ) < 0 )
{
perror("ERROR > send cmd failed to wass : ");
return 0;
}
else
{
printf( "cmd send to %s:%d\n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
}
//printf("\n... waiting answer from %s:%d ... \n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
//strcpy(recepbuff, "whileloop");
//try to receive some data, this is a blocking call
while(loop)
{
memset(recepbuff, '\0' ,sizeof(recepbuff)); //empty buffer
FD_ZERO(&readfds);
FD_SET(socket_fd_rx, &readfds); //set testing for rx
select(socket_fd_rx+1, &readfds, NULL, NULL, &tv); //block until cmd becomes available
if(FD_ISSET(socket_fd_rx, &readfds)) //input rx available
{
//printf("Data to be read \n");
recvfrom( socket_fd_rx, recepbuff , BUFFLEN, 0, (struct sockaddr *)&addr_rx, &serv_len_rx); //recep
printf("[=> RĂ©ponse : %s\n", recepbuff);
}
else
{
loop=0;
}
}
printf(".... RĂ©ponse done from %s:%d .... \n",inet_ntoa(addr_rx.sin_addr),ntohs(addr_rx.sin_port) );
i++;
}
close(socket_fd_rx);
return 0;
}
//FONCTIONS
//OPENING 1 SETTING A SOCKET
/** libf_build_udp_socket
*
* This function creates an UDP socket.
*
* \param udp_socket socket identifier
* \param server_address IP destination address
* \param udp_port Destination UDP port
* \param server_flag TRUE to bind socket on UDP port
*
* \return 0 if successful; error code otherwise
*/
unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port)
{
/*
** Defining of the local variables.
*/
struct sockaddr_in serv_addr; /* Server Socket address structure*/
short int status = 0; /* internal status return*/
unsigned short int return_status = 0; /* the returnes status value */
/*
** creating the socket ;
** call socket (it creates an endpoint for communication and
** returns the socket
** descriptor. To create an UDP socket
** the parameter family is set
** to AF_INET, the type to SOCK_DGRAM, and
** the protocol to
** DEF_PROTOCOL. The socket is a global variable.);
*/
*udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (*udp_socket < 0)
{
return_status = 1;
}
else
{
status = 1; //for future check
if (status >= 0)
{
/*
** reset the serv_addr variable
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
/*
** set the sockname.sin_addr.s_addr to server address;
** sockname.sin_addr.s_addr = htonl(server address);
** set the sockname field sockname.sin_port to the used port number;
** sockname.sin_port = htons (udp port);
*/
serv_addr.sin_addr.s_addr = inet_addr(server_address);
serv_addr.sin_port = htons(udp_port);
/*
** Bind this socket to a name;
** call bind (it assigns a name or address to an unnamed socket.
** When a socket is created with socket it exists in
** a name space (address family) but has no name assigned.
** The bind requests the name, be assigned to the socket);
** If (return status signal an error)
** {
** set to return variable to error
** }
*/
status = bind(*udp_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (status < 0)
{
printf("bind failed with %s", strerror(errno));
return_status = 2;
}
}
else
{
return_status = 3;
}
}
/*
** return status;
*/
return return_status;
}
Maybe i'm missing something essential in socket programming, i made a lot of research and try different things but it still doesn't want to work ! I would appreciate some help ! Thank you !

Related

Socket Creation Error in Linux but not MacOS

I have the following program where I am attempting to re-create ping. This works great when run in my macOS dev environment, but when running in my prod Linux environment the socket fails to get created. I can't figure out why. In addition, any way to resolve this so it works on Linux would be great.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* Calculate ICMP checksum */
uint16_t ip_checksum(void *icmp_header, int size_of_header){
unsigned short *buffer = icmp_header;
unsigned int sum = 0;
uint16_t result;
for(sum=0;size_of_header > 1; size_of_header -=2){
sum += *buffer++;
}
if(size_of_header == 1){
sum += *(unsigned char*)buffer;
}
sum = (sum >> 16) + (sum & 0xffff);
result = ~sum;
return result;
}
int main(int argc, char const *argv[]){
char ip[20]; /* Define variable to hold user entered IP address*/
const int icmp_size=8; /* Size of icmp header */
struct sockaddr_in toSendTo; /* Set sockaddr_in struct */
/* Create ICMP header */
struct icmp_header{
unsigned char icmph_type;
unsigned char icmph_code;
uint16_t icmph_checksum;
unsigned short int icmph_ident;
unsigned short int icmph_seqnum;
} icmp_header;
/* Get user to input IP address */
printf("Please enter an IP address: ");
fgets(ip, sizeof(ip), stdin);
/* Loop to send 3 pings requests */
for(int i = 0; i < 3; i++){
icmp_header.icmph_type = 8; /* Set ICMP type to 8 for sending ICMP request */
icmp_header.icmph_code = 0; /* Set ICMP code to 0 for sending ICMP request */
icmp_header.icmph_checksum = 0; /* Initializee checksum to 0 */
icmp_header.icmph_seqnum = i*20; /* Arbitrary sequence number */
icmp_header.icmph_ident = i+50; /* Arbitrary id */
icmp_header.icmph_checksum = ip_checksum(&icmp_header,icmp_size); /* Calculate checksum */
/* Set transport IP in sockaddr struct */
if (inet_addr(ip) == -1){
printf("Error, invalid IP address\n");
exit(1);
}else{
toSendTo.sin_addr.s_addr = inet_addr(ip);
}
/* Create socket */
int soc = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
/* Check if creation of socket throws an error */
if(soc == -1){
printf("Error creating socket\n");
exit(1);
}
/* Send ICMP ping request */
int send = sendto(soc, &icmp_header, icmp_size, 0, (struct sockaddr *)&toSendTo, sizeof(toSendTo));
/* Check if sending ICMP request throws an error */
if (send < 0){
printf("Error sending ping(%d).\n", i+1);
exit(1);
}else{
printf("\nICMP Echo Request(%d) sent to %s", i+1,ip);
}
unsigned int response_address_size; /* Variable for size of response packet */
char response_buffer[50]; /* Buffer for content of response */
struct sockaddr response_address; /* Struct to hold response address */
/* Struct to hold ICMP response header information */
typedef struct icmp_resp{
unsigned char icmph_type;
unsigned char icmph_code;
uint16_t icmph_checksum;
unsigned short int icmph_ident;
unsigned short int icmph_seqnum;
} icmp_r;
/* Receive ICMP response */
int resp = recvfrom(soc, response_buffer, sizeof(response_buffer), 0, &response_address, &response_address_size);
/* Check if receiving response throws an error */
if (resp < 0){
printf("Error receiving response (%d)\n",i+1);
exit(1);
}
icmp_r* echo_response;
echo_response = (icmp_r *)&response_buffer[20];
/* Determine if Destination Unreachable is response */
if(echo_response->icmph_type == 3 && echo_response->icmph_code == 0){
printf("Destination Unreachable...\n");
}else{
/* Print ICMP response information */
printf("ICMP Response(%d) : type=%d,code=%d,checksum=%x, ident=%d, seq=%d\n\n", i+1,
echo_response->icmph_type,
echo_response->icmph_code,
ntohs(echo_response->icmph_checksum),
echo_response->icmph_ident,
echo_response->icmph_seqnum);
}
/* Close Socket */
close(soc);
}
}
Here is my output when run in Linux:
Please enter an IP address: 8.8.8.8
Error creating socket
You have to set ping_group_range with sysctl like in the example below for specifying the groups who can create IPPROTO_ICMP sockets.
sysctl -w net.ipv4.ping_group_range="gid gid"
From the documentation:
ping_group_range (two integers; default: see below; since Linux
2.6.39)
Range of the group IDs (minimum and maximum group IDs,
inclusive) that are allowed to create ICMP Echo sockets.
The default is "1 0", which means no group is allowed to
create ICMP Echo sockets.
Edit
The socket type has to be SOCK_DGRAM instead of SOCK_RAW in int soc = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); and you also need to define toSendTo.sin_family = AF_INET;.

Checking return address in recvfrom() (C UDP Sockets)

This pertains to attempting to validate the return address in recvfrom() (the fifth argument to the function) in this UDP echo client:
While I can send data to the server and receive return communications correctly, I'm having trouble validating the return IP address when comparing the fromAddr.sin_addr and echoServAddr.sin_addr.
The goal here is to compare the address in the structure that was used in sendto() and the address in the structure returned from recvfrom() to validate the echo reply from the server indeed came from where the initial transmission from the client was sent (A rudimentary POC that there wasn't a Man In The Middle).
What should I be looking at in order to appropriately validate the return address as it is returned from recvfrom() matches the address transmitted to as referenced in the sendto() call?
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), sendto(), and recvfrom() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#define ECHOMAX 255 /* Longest string to echo */
void DieWithError(char *errorMessage); /* External error handling function */
int main(int argc, char *argv[])
{
int sock; /* Socket descriptor */
struct sockaddr_in echoServAddr; /* Echo server address */
struct sockaddr_in fromAddr; /* Source address of echo */
unsigned short echoServPort; /* Echo server port */
unsigned int fromSize; /* In-out of address size for recvfrom() */
char *servIP; /* IP address of server */
char *echoString; /* String to send to echo server */
char echoBuffer[ECHOMAX+1]; /* Buffer for receiving echoed string */
int echoStringLen; /* Length of string to echo */
int respStringLen; /* Length of received response */
// manage the command line arguments and errors
if ((argc < 3) || (argc > 4)) {
fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n",
argv[0]);
exit(1);
}
// load servIP
servIP = argv[1];
// load echoString
echoString = argv[2];
// check echoString and error if too long
echoStringLen = strlen(echoString);
if (!(echoStringLen <= 255)) {
DieWithError("BUFFER EXCEEDED ERROR");
}
// load port
if (argc == 4)
echoServPort = atoi(argv[3]);
else
echoServPort = 7;
// create the socket
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
DieWithError("SOCKET CREATION ERROR");
}
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet addr family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
echoServAddr.sin_port = htons(echoServPort); /* Server port */
// send the string
inet_pton(AF_INET, servIP, &echoServAddr.sin_addr);
if ((sendto(sock, echoString, strlen(echoString), 0, (struct sockaddr *)
&echoServAddr, sizeof(echoServAddr))) < 0) {
DieWithError("SEND ERROR");
}
// recieve a response
respStringLen = recvfrom(sock, echoBuffer, sizeof(echoBuffer), 0,
(struct sockaddr *) &fromAddr, &fromSize);
if (respStringLen < 0) {
DieWithError("RECV ERROR");
}
// print the message sent
printf("SENT FROM CLIENT: '%s'\n", echoString);
// print the message recieved
echoBuffer[respStringLen] = '\0';
printf("RECEIVED FROM SERVER: '%s'\n", echoBuffer);
// check if from the correct server
if ((struct sockaddr *) &echoServAddr.sin_addr != (struct sockaddr *) &fromAddr.sin_addr) {
DieWithError("INVALID RETURN ADDRESS");
}
// close the socket
close(sock);
// exit the program
exit(0);
}
If the source IP/port of the incoming packet is the same as the destation IP/port of the packet you sent, then the sin_addr and sin_port fields of echoServAddr and fromAddr should match.
This line of code however doesn't do that:
if ((struct sockaddr *) &echoServAddr.sin_addr != (struct sockaddr *) &fromAddr.sin_addr) {
This is comparing the address of echoServAddr.sin_addr against the address of fromAddr.sin_addr. Because these are two separate variables, this will always be false. You instead want:
if ((echoServAddr.sin_addr.s_addr != fromAddr.sin_addr.s_addr) ||
(echoServAddr.sin_port != fromAddr.sin_port))

C Socket sendto Invalid argument error

My router.c file creates 2 sockets
the first is to bind to a port and answer clients
the second is to connect to an already bound port (by the server.c file)
and send messages to.
for some reason the sendto line return an Invalid argument error.
please help.
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
/* The Rounter represents through the server file(recv_udp.c).It transmitting from/to A(client) and C(another client)
by specific criteria (given in the assignment). */
int main(int argc, char *argv[])
{
/* Adding values that`ll be used for Q5*/
char serMsg [] = "Nice to hear from you,I am the server\n";
// char serMsg [] = "Good morning sun shine\n";
int serMsgLeng = strlen(serMsg)+1;
int error = -1;
char buff_A[200] = {'\0'};
char buff_C[200] = {'\0'};
// A value we get from the command prompt
float x;
float random, rand_num;
struct timeval tv;
tv.tv_sec = 3; /* 3 Seconds Time-out */
tv.tv_usec = 0;
/* Values that`ll receive for the socket I`ll open (as socket descriptor(an int) etc.) */
int socket_fd1,socket_fd2, cc, addrLenA, s_in2Size;
/* Randome number Raffled between the range of[0,1] */
double randNum;
/* Defining Structures for decleration of the server s_in= as serverAddr(local ip,and local port),
from_A = the address that the datagram was received from client A,
from_C-the address that the datagram was received from client C . */
struct sockaddr_in s_in1, s_in2;
// Defining Structures for handling the clients address(client A and client C)
// Client A address structure
struct sockaddr_in client_A_addr;
//Client C address structure
struct sockaddr_in client_C_addr;
x = atof(argv[1]);
// Creating UDPsocket-(it`s a system call)-the socket()function opens a local socket and saves it`s number in socket_fd value. */
socket_fd1 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
socket_fd2 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
/*set the socket options*/
setsockopt(socket_fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
setsockopt(socket_fd2, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
// Binary cleaning /
bzero((char *) &s_in1, sizeof(s_in1)); /* They say you must do this */
bzero((char *) &s_in2, sizeof(s_in2));
/* Configure settings in address struct
"s_in.sin_family"-set the address family to be "AF_INET
"s_in.sin_addr.s_addr"- the htonl function converts host's to network's long
"s_in.sin_port" -the htons function converts regular form port to binary form.*/
s_in1.sin_family = (short)AF_INET;//host byte order
s_in1.sin_addr.s_addr = htonl(INADDR_ANY); // WILDCARD //
s_in1.sin_port = htons(1337);
s_in2.sin_family = (short)AF_INET;//host byte order
s_in2.sin_addr.s_addr = inet_addr("172.17.0.15"); // WILDCARD //
s_in2.sin_port = htons(1338);
// printsin( &s_in, "RECV_UDP", "Local socket is:");
fflush(stdout);
/* The bind function assigns a local protocol address to a socket(and another system call).
The purpose of sin here is to tell bind which local address to assign.
bind method input:the sock_fd and the stuctur that handels the address and it`s length*/
bind(socket_fd1, (struct sockaddr *)&s_in1, sizeof(s_in1));
printf("After binding,waiting to hear from clients!\n");
addrLenA = sizeof(client_A_addr);
s_in2Size = sizeof(s_in2);
connect(socket_fd2, (struct sockaddr *) &s_in2, s_in2Size);
printf("After connect to server!\n");
// Keep listenning
for(;;) {
// Check from who we recive the message - if from cilent A
// Check for errors
//recfrom() returns the length of the message that it receives,so if the client message length that the method returns is
//equal to the message length of client A - we raffel a number between[0,1].
if( (cc = recvfrom(socket_fd1,&buff_A,sizeof(buff_A),0,(struct sockaddr*)&client_A_addr,&addrLenA))== error){
printf("No message for now, waiting...\n");
}
// For self-check ,no error occured
if (strlen(buff_A) > 0) {
printf("Client A says: %s\n", buff_A);
// Than raffel a randNum and decide what to do with it(send or delete it)
srand(time(NULL));
random = rand();
rand_num = random / RAND_MAX;
printf("rand_num: %f\n", rand_num);
printf("x: %f\n", x);
// Greater than X send it
if(rand_num > x) {
printf("Sending message From A to C\n");
// Pass the message to C
if(sendto(socket_fd2, &buff_A, sizeof(buff_A),0,(struct sockaddr*)&client_C_addr,sizeof(client_C_addr))== error){
printf("sendto()- Client C failes to send message\n");
printf("%s\n", strerror(errno));
exit(1);
}
} else {
// Drop the message
}
// Clearing the message buffer
memset(buff_A, '\0', sizeof buff_A);
}
} //end for
return 0;
}
You never fill in client_C_addr. You must tell sendto where to send the data, like:
client_C_addr.sin_family = AF_INET;
client_C_addr.sin_port = htons(port);
client_C_addr.sin_addr.s_addr = inet_addr("192.168.1.1");

UDP connection - Socket programming in C

I have a specific equipement (IP : 192.168.0.10 port 3000 - it's a signal receiver) that must be controlled through UDP. I should be able to send this equipement basic commands such as 'reset'; 'log' ; 'run' ...
After some struggle and the gentle help of stackoverflow i managed to communicate with my equipment using netcat. It now works perfectly. I used the command nc -u 192.168.0.10 3000 after changing the computer eth IP. (i'm under linux).
Now, and that's the goal, i need to do the same as netcat, but, using C language. Since i'm a beginner i tried myself using internet and wrote this :
/* Standard Linux headers */
#include <stdio.h> //printf
#include <string.h> //memset
#include <stdlib.h> //exit(0);
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
/* DEFINE */
#define SERVER "192.168.0.10"
#define BUFFLEN 1024 //Max length of buffer
#define PORT 3000 //The port on which to send data
int main (void)
{
/*
** Definition of the local variables.
*/
struct sockaddr_in serv_addr; /* Server Socket address structure*/
/* short int status = 0; /* internal status return*/
/* unsigned short int return_status = 0; /* the returnes status value */
char recepbuff[BUFFLEN];
char cmd[BUFFLEN];
int socket_fd;
/*
** Initialisation of the local variables.
*/
memset(recepbuff, '0' ,sizeof(recepbuff)); /*pareil que bzero*/
/*
** Creating the socket
** call socket (it creates an endpoint for communication and
** returns the socket descriptor.
** To create an UDP socket here are the param
** The protocol family should be AF_INET
** The protocol type is SOCK_DGRAM
** The protocol should beset to default ie
** DEF_PROTOCOL wich is default so 0. );
*/
if ( (socket_fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0 ) /* return 1 if okay */
{
printf("ERROR opening socket");
}
serv_addr.sin_family = AF_INET; /*Define the domain used*/
serv_addr.sin_port = htons(PORT); /*Declare port #PORT to be used*/
/*serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); /*Permit any incoming IP address by declaring INADDR_ANY*/
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, SERVER, &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(socket_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
else
{
printf("\n Connected \n");
}
/* Messaging*/
while(1)
{
printf("Enter command : ");
gets(cmd);
//send the message
if ( (sendto(socket_fd , cmd , strlen(cmd) , 0 , (struct sockaddr *)&serv_addr, sizeof(serv_addr)) ) < 0 )
{
printf("DEBUG_CMD: Failed sending cmd\n");
}
else
{
printf("DEBUG_CMD : CMD * %s * SENT\n", cmd);
puts(cmd);
}
//receive a reply and print it
//clear the buffer by filling null, it might have previously received data
memset(recepbuff, '0' ,sizeof(recepbuff));
printf("mini-debug memset done\n");
//try to receive some data, this is a blocking call
if ((recvfrom( socket_fd, recepbuff, strlen(recepbuff), 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) ) < 0)
{
printf("DEBUG_RECEP: Failed received cmd\n");
}
else
{
printf("DEBUG_RECEP : CMD RECEIVED\n");
}
puts(recepbuff);
}
close(socket_fd);
return 0;
}
So, i launch my program, and it seems to be correctly connected. I type my command, a simple reset and then nothing happens. Like if it's blocked at the recvfrom (because the "mini debug memset done" is printed). And i can't find any clue about what I am doing wrong.
EDIT : Corrected the strlen in the recvfrom => same thing
In fact, i'm not even sure that i'm using the right method and even if i'm really "connected" ...

Program doesn't enter the main function?

I'm tyring to create a server client connection but for some reason when I run the server code, it'll just give me the prompt, nothing happens. I put a printf as the first thing in the main function but even that doesn't happen. What could be executed before the main? I don't think I have anything that could cause a problem.
#include "md5.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
void *handle_connection (void *); //gets a connection identifier and handles that incoming connection
int verify_password (char s[]); // verifies if the input password is correct
int main(int argc, char *argv[])
{
pthread_t connected;
pthread_attr_t attributes;
int listenfd = 0, conn_id = 0; // the listening socket identifier and current connection identifier
//A: Creates the master socket
listenfd = socket (PF_INET, SOCK_STREAM, 0);
//B: the struct variable that keeps the socket address
struct sockaddr_in sad; /* structure to hold an IP address */
struct sockaddr_in cad;
struct hostent *ptrh; /* pointer to a host table entry */
socklen_t alen;
//B: initialization of socket address variable
memset ((char *)&sad, 0, sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
sad.sin_port = htons((u_short) 5000); /* set the port number */
//C: binds the socket to its address
bind (listenfd, (struct sockaddr *)&sad, sizeof(sad));
//D: starts listening on that socket
listen (listenfd, 100000);
while (1) // listens for incoming connections until program exits manually
{
int conn_id = 0;
//E: Wait for a connection request and accept it
conn_id = accept (listenfd, (struct sockaddr *)&cad, &alen);
//F: if the connection has been established it creates a thread that handles the connection
if (conn_id != -1)
{
pthread_attr_init (&attributes);
pthread_attr_setdetachstate (&attributes, PTHREAD_CREATE_DETACHED);
pthread_create (&connected, &attributes, (void *) handle_connection, &conn_id);
}
}
}
void *handle_connection(void *arg)
{
int conn_id = *(int *) arg;
char recv_buff[1024]; // the buffer that is used for keeping the data read from the socket
int n = 0; // number of characters read from socket
//G: read from connection into the buffer and checks if recieving data was successful
if (n = recv (conn_id, recv_buff, 1024, 0) <= 0)
{
printf ("Error Reading");
}
//H: verifies if the password is correct and sends T if the password is correct and F otherwise
if (verify_password (recv_buff) == 1)
{
if (send (conn_id, "T", 1, 0) < 1) {
printf ("Error Sending");
}
} else {
if (send (conn_id, "F", 1, 0) < 1) {
printf ("Error Sending");
}
}
//I: closes the connection
close (conn_id);
}
int verify_password(char s[])
{
char md5_hashed_password[33] ="24af484e92082ad450a63a69f924f10a"; // The password of server hashed by MD5
char md5_hashed_text[33]; // Keeps the MD5 hashed text of input text
size_t len = strlen(s);
md5 ((uint8_t*)s, len, md5_hashed_text); //Finds the MD5 hashed of input text
if (strncmp (md5_hashed_text, md5_hashed_password, 32) == 0) //If the hashed value of the input value and the
return 1; // password is same the password is accepted
return 0;
}

Resources