WinSock2 cant connect to simple server - c

I'm learning networking on windows using C and I get this weird 10038 error
WSADATA wsa;
SOCKET connect_socket;
printf("Initialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}printf("Initialised.\n");
if (connect_socket = socket(AF_INET, SOCK_STREAM, 0) == INVALID_SOCKET) {
printf("Could not create socket : %d\n", WSAGetLastError());
return -1;
}
printf("Socket created.\n");
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(80);
server.sin_addr.s_addr = inet_addr("142.250.184.196");
if (connect(connect_socket, (struct sockaddr*)&server, sizeof(server)) != 0)
{
printf("connect error : %d\n", WSAGetLastError());
return 1;
}
printf("Connected\n");
return 0;
nslookup www.google.com -> "142.250.184.196"
when trying to run program prints: "
Initialising Winsock...Initialised.
Socket created.
connect error : 10038"

if (connect_socket = socket(AF_INET, SOCK_STREAM, 0) == INVALID_SOCKET) {
Based on the operator precedence in C this means
connect_socket = (socket(AF_INET, SOCK_STREAM, 0) == INVALID_SOCKET)
Thus connect_socket is not the actual socket but the result of the check if the socket is valid. Assuming that socket creation worked then connect_socket will thus be false, i.e. 0.
Since 0 is not a valid TCP socket connect will fail with error 10038:
WSAENOTSOCK
10038
Socket operation on nonsocket.
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.
To fix this, first assign to connect_socket, then compare with INVALID_SOCKET.

Related

Winsock only accepts connection from the same computer, but not from the same network

So I have been following this guide
http://www.binarytides.com/winsock-socket-programming-tutorial/
To create a simple tcp server in c, this is the code I came up with :
https://pastebin.com/CDxiLv3b
int c;
char client_message[2000];
int recv_size;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Server Socket created.\n");
memset(&server_addr, 0, sizeof(server_addr));
//Prepare the sockaddr_in structure
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
//Bind
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
}
printf("Bind to port %d done.\n", port);
//Listen to incoming connections
listen(server_socket, 3);
//Accept and incoming connection
puts("Waiting for incoming reverse shell...");
c = sizeof(struct sockaddr_in);
while ((client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &c)) != INVALID_SOCKET)
{
puts("Connection accepted");
if ((recv_size = recv(client_socket, client_message, 2000, 0)) == SOCKET_ERROR)
{
puts("recv failed");
break;
}
client_message[recv_size] = '\0';
strcpy_s(path, MAX_PATH_LEN, client_message);
break;
}
if (client_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d", WSAGetLastError());
return 1;
}
return 0;
(Yes I basicly copied and changed stuff)
Now the problem is that I can only connect to this server using the same connection I cant connect to it using diffrent computers in the network and even if I open port (which shouldn't actually matter) it wont accept the connection from the diffrent computers on my network (only from the same computer)
I just needed to open ports on the firewall

Socket fails to bind (C with WinSock)

This is supposed to bind a socket to a port on the local host and accept TCP connections. When I run it, I get my "Bind error" message. I used this tutorial (see the "Accept connection" section), and the only significant difference I can see between that and my code is the position of the server address and port member initializations, which shouldn't matter, as long as they come before the bind() call?
I added a new rule in Windows Firewall (on Windows 7) to allow TCP connections from this executable, on port 8888, but that doesn't seem to help.
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
struct sockaddr_in server, client;
int c;
printf("\nInitializing WinSock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error code: %d\n\n", WSAGetLastError());
exit(1);
}
printf("\nInitialized.");
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
server.sin_family = AF_INET;
if (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET)
{
printf("\nCould not create socket: %d", WSAGetLastError());
exit(1);
}
printf("\nSocket created.\n");
if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("\nBind error.\n\n");
exit(1);
}
printf("\nSocket bound to port 8888.\n\n");
listen(s, 3);
printf("\nWaiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(s, (struct sockaddr *)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("\nAccept failed.\n\n");
exit(1);
}
printf("\nConnection accepted.");
closesocket(s);
WSACleanup();
return 0;
}
This statement:
if (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET)
Needs an additional set of parenthesis around the assignment:
if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
The == operator has a higher precedence then the = operator (see Operator Precedence), so your original statement implicitly acts as if you had written it like this instead:
if (s = (socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET))
If socket() succeeds, the comparison would evaluate to false, which then assigns 0 to s (since SOCKET is just an alias for UINT_PTR, assigning a boolean value to a SOCKET variable is allowed), and then bind() would fail with the WSAENOTSOCK error (if socket() fails, the comparison would evaluate to true, which would assign 1 to s, then the if would evaluate as true and your process would exit).
Personally, I dislike code that does assignments and comparisons in the same statement. This would be clearer and safer:
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
Also, don't forget to call closesocket() on new_socket after accept() succeeds.

Multiple servers with single client

Scenerio: several servers are listening, and a single client will send a UDP broadcast to all machines on the network and the servers will reply back. (goal: get all the ip addresses of the servers)
Here is the client code:
int main()
{
struct sockaddr_in connectedSocket;
int length=sizeof(connectedSocket);
int iResult = 0, iOptVal = 0, nOptiontValue = 1;
SOCKET Socket;
char receiveBuffer[1000];
char message[1000];
//Clear the buffer by filling null, it might have previously received data
memset(receiveBuffer,'\0', 1000);
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...\n");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("\nFailed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("\n.........Initialised.\n");
//Create socket
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if (Socket == SOCKET_ERROR)
{
printf("Create a UDP socket failed with error = %d\n" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//Set socket options to broadcast
iResult = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST,(char *) &iOptVal, sizeof (iOptVal));
if(iResult == SOCKET_ERROR)
{
printf("Set socket options failed with error = %d\n" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//Setup address structure
memset((char *) &connectedSocket, 0, sizeof(connectedSocket));
connectedSocket.sin_family = AF_INET;
connectedSocket.sin_port = htons(PORT);
connectedSocket.sin_addr.s_addr = INADDR_BROADCAST;
while(1)
{
printf("\n\n\nEnter message : ");
gets(message);
//send the message
if (sendto(Socket, message,sizeof(message) , 0 , (struct sockaddr *) &connectedSocket, sizeof(connectedSocket)) == SOCKET_ERROR)
{
printf("\nsendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("\nMessage Successfully sent to Server");
// fflush(stdout);
if (recvfrom(Socket, receiveBuffer, 1000, 0, (struct sockaddr *) &connectedSocket,&length) == SOCKET_ERROR)
{
printf("\nrecvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("\nServer Says : ");
printf(receiveBuffer,sizeof(receiveBuffer));
}
closesocket(Socket);
WSACleanup();
return 0;
}
When I run this, I get
sendto() failed with error code : 10013
I look up the winsock error and it says
An attempt was made to access a socket in a way forbidden by its access permissions. An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO_BROADCAST).
But I am setting the sockopt to SO_BROADCAST. Can anyone tell me why this is happening?
The relevant parts of the code you posted are here:
int iResult = 0, iOptVal = 0, nOptiontValue = 1;
...
//Set socket options to broadcast
iResult = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST,(char *) &iOptVal, sizeof (iOptVal));
if(iResult == SOCKET_ERROR)
{
printf("Set socket options failed with error = %d\n" , WSAGetLastError());
exit(EXIT_FAILURE);
}
Note that the variable iOptVal has been initialized 0. It's not modified anywhere else. Then you pass that variable to the setsockopt() function.
This sets the SO_BROADCAST option to FALSE. (Which is the default value, so actually it doesn't change the value).
It's not sufficient to set it. You have to set it to the correct value. Which would be TRUE.
You can do this by initializing the variable to 1 instead of 0.

how to check whether data is available on socket?

SOCKET s; // Create a SOCKET for listening for
// incoming connection requests.
SOCKET new_socket; // create a socket for accepting incoming connection
uint16 port =18001;
void CreateSocket()
{
int sin_size;
WSADATA wsa;
struct sockaddr_in server, master; // creating a socket address structure: structure contains ip address and port number
printf("Initializing Winsock\n");
if(WSAStartup(MAKEWORD(2,2), &wsa)!=0)
{
printf("Failed Error Code: %d", WSAGetLastError());
return -1;
}
printf("Initialised\n");
//CREATING a SOCKET
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Could not Create Socket\n");
//return 0;
}
printf("Socket Created\n");
server.sin_addr.s_addr = inet_addr("192.168.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
//Binding between the socket and ip address
if(bind (s, (struct sockaddr *) &server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code: %d", WSAGetLastError());
}
puts("Bind Done");
//Listen to incoming connections
listen(s, 3);
//Accepting the incoming connection
sin_size = sizeof(struct sockaddr_in);
new_socket = accept(s, (struct sockaddr *)&master, &sin_size);
printf("\n I got a connection from (%s , %d)",
inet_ntoa(master.sin_addr),ntohs(master.sin_port));
closesocket(new_socket);
/*new_socket = accept(s, NULL, NULL);
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error: %ld\n", WSAGetLastError());
closesocket(new_socket);
WSACleanup();
return 1;
}
else
printf("Client connected.\n");*/
}
I have created the socket and accepting the connection from the master but anyone tell me the condition for checking if there is any data available on the specified port number ?? I am using windows operating system. The above code is for creating socket for windows operating system.
how to make the above code to accept port number as an argument for sending and receiving data ??
You can easily find this online.
Assuming you are using winsock API, you just need to call recvfrom() - it will either return an error if there is some problem, or it will block until there is available incoming data.
See the documentation here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740120%28v=vs.85%29.aspx

how to check that socket is active on TCP layer?

typedef unsigned int uint16;
SOCKET s, new_socket;
uint16 port =18001;
void CreateSocket()
{
WSADATA wsa;
struct sockaddr_in server; // creating a socket address structure: structure contains ip address and port number
printf("Initializing Winsock\n");
if(WSAStartup(MAKEWORD(2,2), &wsa)!=0)
{
printf("Failed Error Code: %d", WSAGetLastError());
return -1;
}
printf("Initialised\n");
//CREATING a SOCKET
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Could not Create Socket\n");
//return 0;
}
printf("Socket Created\n");
server.sin_addr.s_addr = inet_addr("192.168.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
//Binding between the socket and ip address
if(bind (s, (struct sockaddr *) &server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code: %d", WSAGetLastError());
}
puts("Bind Done");
//Listen to incoming connections
listen(s, 3);
//Accepting the incoming connection
new_socket = accept(s, NULL, NULL);
if (new_socket == INVALID_SOCKET)
{
printf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(new_socket);
WSACleanup();
return 1;
}
else
printf("Client connected.\n");
closesocket(s);
}
int main()
{
CreateSocket();
return 0;
}
this is for TCP.
I am receiving a connection from the MASTER via the above ip address and port number, So I created a socket with port number and ip address for it. But how to check that the socket is active ?? how to check that the above socket code is valid (it's not showing any error). I am getting an error on the MASTER side saying that :
CONNECT EVENT CHECK FAILED (WSAGetLastError())
Could anyone help me in this ??
There is no connection between your socket and the address, you never bind() the address in server to the socket s.
Which, of course, is why your client fails to connect since the socket will not be using the expected port. I assume that you elsewhere call accept() and so on, to actually make the socket accept incoming connections, too.

Resources