I am trying to create a simple c++ program that hides the differences between Linux and Windows when making sockets and connecting to servers
The Linux part of this code compiles without any warnings or errors but times out after resolving the host IP and does not connect to the server running (nc -lvnp 7777)
Using tcpdump -i eth0 -v port 7777 to capture all the traffic to and from the machine running the program shows nothing
class Socket
{
public:
int initsoc(void);
int connectsoc(int sock, const char * host, int port);
};
int Socket::connectsoc(int sock, const char * host, int port)
#ifdef _WIN32
/* windows part */
#else
struct hostent *server;
struct sockaddr_in server_addr;
struct in_addr *address;
server_addr.sin_family = AF_INET;
server_addr.sin_port = port;
/* resolve host */
server = gethostbyname(host);
if (server == NULL)
{
printf("Error : %s \nFailed to resolve %s:%d", strerror(errno), host, port);
return -1;
}
address = (struct in_addr *) (server->h_addr);
printf("Resolved: [%s] ===> [%s]\n", host, inet_ntoa(*address));
server_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*address));
iResult = connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
printf("Connect returned : %d\n",iResult);
if (iResult < 0)
{
printf("Error: %s\nFailed to connect\n",strerror(errno));
return -1;
}
printf("Connected to [%s:%d]\n",host,port);
return 0;
I tried to open a netcat listener on a machine on the same network as the computer running the program without any NATs but it still times out
this is how i compiled and what it outputs
g++ -Wall -ggdb3 -pedantic -g main.cpp -o app
Resolved: [10.0.0.100] ===> [10.0.0.100]
Connect returned : -1
Error: Connection timed out
Failed to connect
the ip of the machine running the code is 10.0.0.2
the ip of the machine running the netcat server is 10.0.0.100
As commented by #user253751, this line:
server_addr.sin_port = port;
should be changed to:
server_addr.sin_port = htons(port);
Related
I have been trying to get a simple SFTP program working with code from this website, but I have not been able to get it to even send out data without it returning error code 10061 (WSAECONNREFUSED). I have tried using Wireshark on the active interface with all firewalls disabled, but it didn't say anything was being sent to the address I gave (ex: 72.196.212.127). However, when I give it a local address like 192.168.1.101, it gives error code 10060 (WSAETIMEDOUT), still not sending out any data on the network. I am able to connect to the target machine on both address with software like Putty and WinSCP and ping it on the command prompt.
Here is the relevant part of my connection method:
// Open socket
WSADATA data;
int err = WSAStartup(MAKEWORD(2, 0), &data);
if (err != 0) return "ERROR: Failed to initialize WSA";
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = to_uint32_t(ip);
if (net::connect(sock, (struct sockaddr*) &sin, sizeof(struct sockaddr_in)) != 0) return "ERROR: Could not connect to host. Code: " + std::to_string(WSAGetLastError());
The variable port is an integer (value = 22), with ip being a string (192.168.1.101 or 72.196.212.127). This function returns the "Could not connect to host" error. No other errors occur.
Here is the to_uint32_t method:
std::uint32_t to_uint32_t(const std::string& ip_address)
{
const unsigned bits_per_term = 8;
const unsigned num_terms = 4;
std::istringstream ip(ip_address);
uint32_t packed = 0;
for (unsigned i = 0; i < num_terms; ++i)
{
unsigned term;
ip >> term;
ip.ignore();
packed += term << (bits_per_term * (num_terms - i - 1));
}
return packed;
}
#selbie pointed out that I was not using the correct function for resolving the IP. To fix my code, I just switched sin.sin_addr.s_addr = to_uint32_t(ip); to inet_pton(AF_INET, ip, &sin.sin_addr);.
i am working on a chat.
i can start my server and client on the same computer using the 127.0.0.1 ip address and can talk fine, but if I try using my own IP address in the client to connect to the server, it does not connect. If someone else also tries to do it, it doesn't work
i have portforwarded in my router like this:
external host: my ip
internal host: my internal ip i got with ipconfig (192.168.1.4)
internal port: 54444
external port: 54444
even then, I think I should still be able to connect to my IP address without a portforward since the server is hosted on 127.0.0.1/localhost, right?
this is my client code:
WSADATA wsa;
if (!WSAStartup(MAKEWORD(2, 2), &wsa))
{
printf("started server\n");
SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if (listen_sock)
{
printf("created listen socket\n");
sockaddr_in addr;
addr.sin_family = AF_INET;
inet_pton(AF_INET, "92.83.235.216", &addr.sin_addr);
addr.sin_port = htons(54444);
if (!connect(listen_sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))
{
printf("connected to server\n");
char buffer[2048];
char input[2048];
for(;;)
{
printf("message: ");
scanf_s("%s", input);
if (send(listen_sock, input, strlen(input) + 1, 0))
{
printf("\nsent message \"%s\"", input);
}
memset(input, 0, sizeof(input));
printf("\n");
}
}
}
}
printf("%d\n", WSAGetLastError());
WSACleanup();
it stops after it shows "creating listen socket", right at the connect() call
Any ideas?
EDIT: server code is very jumbled because of me making it into a class to make it easier to use + adding a thread to handle multiple connections, but like I said it does work internall
only thing different in the server code besides the listen and accept calls is these rules i added:
char opt_val = 1;
setsockopt(this->m_listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val));
setsockopt(this->m_listen_sock, IPPROTO_TCP, TCP_NODELAY, &opt_val, sizeof(opt_val));
What you're describing sounds like your SYN packets are being dropped (SYN... no SYN/ACK or RST). You can use wireshark to see what is happening with the actual tcp connection (filter on port).
You might want to eliminate the server as a source of error by listening on localhost and connecting that way. You can verify it is listening on the correct address and port using netstat.
Otherwise, it would help if you posted your server code.
Running a Linux system on a PowerPC Architecture which is connected via Ethernet to another Device obtaining a UDP connection (Package Based),
I try to setup a socket and bind it to my Port 8813. But whenever I enter a Port different from 0, Binding fails.
Here is the code:
int connector::initUDPSocket(){
struct hostent *server;
//Construct Socket
struct sockaddr_in {
__uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
}
;
sockaddr_in socketaddress;
socklen_t addrlen = sizeof(struct sockaddr_in); /* length of addresses */
udpsocket=socket(AF_INET,SOCK_DGRAM ,0);
if(udpsocket<=0)
{
printf("No Socket opened!");
return 1;
}
else
{
printf("ONE Socket opened!");
memset((char *) &socketaddress,0, sizeof(socketaddress));
socketaddress.sin_family = AF_INET;
socketaddress.sin_addr.s_addr=htonl(inet_addr("192.168.0.10"));//<=That's the external devices address;// htonl(inet_addr("192.168.0.1"));//<=That's my devices address;//htonl(INADDR_ANY);//INADDR_ANY;//
socketaddress.sin_port = htons(8813);//8813;//htonl(8813);//htons(0); //<=Only the last one works
int bind_result=bind(udpsocket,(struct sockaddr *)&socketaddress,sizeof(socketaddress));
if( bind_result == SOCKET_ERROR)
{
printf(LFL_CRI,"BIND failed! Error: %s",strerror(errno)); //Returns "BIND failed! Error: Address family not supported by protocol"
}
else
{
printf(LFL_CRI,"BIND worked!");
//Nun den Listener für den DatenStream aufsetzen.
char SockAddrBuffer[sizeof(struct sockaddr_storage)];
socklen_t SockAddrBufferSize = sizeof(SockAddrBuffer);
int numofbytes=recvfrom(udpsocket, udp_buffer, UDP_BUFFERSIZE, 0, (struct sockaddr *)SockAddrBuffer, &SockAddrBufferSize);
if (numofbytes >0)
{
printf("%i bytes received",numofbytes);
}
}
}
return 0;
}
}
What I found out so far:
Ping 192.168.0.10 is possible
Data seem not to be blocked by the firewall; iptables -nvL mentioned no dropped packages. I added a new rule for that, before this rule was applied, the number or dropped packages increased when the external device was connected.
Using a test tool on my Windows PC (simply debugging, if there's incoming traffic on a port; connecting the external device to it), I receive data; so, the external device definitely sends data
Binding to Port 0 works; the netstat -au mentions a tool listening on port 2, while the program is running
Error Message: BIND failed! Error: Address family not supported by protocol
So, 2 questions are open here:
What am I doing wrong?
What am I understanding wrong about "bind". What sense does it make to listen to "some random port assigned to my program by the system"? I mean, if I setup an http-Server, I want to listen to Port 80 and not to port "RANDOM". What is this good for?
You've redefined struct sockaddr_in in your code. If is in any way different from how the system defines it, any code that attempts to use this struct will not work properly.
You need to #include <netinet/in.h> to get the proper definition of this struct.
I am working on a server client project on Qt. The server is running in a machine with more than one network interface. The design is such that the client will discover the server automatically. ie the client will broadcast its IP to a network the server get that message and sends back the server's IP. The problem now is that when I try to get the IP in the server, There are more than 1 IP. How to get the IP of the interface through which server have received the message?
This might be a solution for you
IPAddress FindLocalIPAddressOfIncomingPacket( senderAddr )
{
foreach( adapter in EnumAllNetworkAdapters() )
{
adapterSubnet = adapter.subnetmask & adapter.ipaddress;
senderSubnet = adapter.subnetmask & senderAddr;
if( adapterSubnet == senderSubnet )
{
return adapter.ipaddress;
}
}
}
How to get your own (local) IP-Address from an udp-socket (C/C++)
In order to get the incoming peer IP address you can use following solution in C
socklen_t len;
struct sockaddr_storage addr;
char ipstr[INET6_ADDRSTRLEN];
int port;
len = sizeof addr;
getpeername(s, (struct sockaddr*)&addr, &len);
// deal with both IPv4 and IPv6:
if (addr.ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
port = ntohs(s->sin_port);
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
} else { // AF_INET6
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
port = ntohs(s->sin6_port);
inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
}
printf("Peer IP address: %s\n", ipstr);
Getting the source address of an incoming socket connection
I have the following configuration for my experiment.
Wifi(Belkin) router connected to Internet.
Laptop with Windows 7 OS
Laptop with Ubuntu OS.
Experiment: When I connect both of my laptop to Wifi router it assigns DHCP IPs 192.168.2.2 to Linux & 192.168.2.3 to Win 7. Both of them can browse internet.
I start a UDP server on my Linux machine with the following code.
int main(int argc, char *argv[]) {
int sd, rc, n, cliLen, flags;
struct sockaddr_in cliAddr, servAddr;
char msg[MAX_MSG];
//Create a socket
sd=socket(AF_INET, SOCK_DGRAM, 0);
if(sd<0){ printf("%s: cannot open socket \n",argv[0]); exit(1); }
//Bind now to a port
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("192.168.2.2");
servAddr.sin_port = htons(9999);
rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
if(rc<0) {printf("%s: cannot bind port number %d \n", argv[0], 9999);exit(1);}
//We are done ... Notify User
printf("%s: waiting for data on port UDP %u\n",argv[0],LOCAL_SERVER_PORT);
//Server's Infinite Loop
while(1)
{
memset(msg,0x0,MAX_MSG);//Sanity
/* receive message */
cliLen = sizeof(cliAddr);
n = recvfrom(sd, msg, MAX_MSG, flags,(struct sockaddr *) &cliAddr, (socklen_t * )&cliLen);
if(n<0){printf("%s: cannot receive data \n",argv[0]);continue;}
//Received message
printf("%s: from %s:UDP%u : %s \n", argv[0],inet_ntoa(cliAddr.sin_addr),ntohs(cliAddr.sin_port),msg);
sleep(1);
//Sending back the data thus received
sendto(sd,msg,n,flags,(struct sockaddr *)&cliAddr,cliLen);
}//while
return 0;
}
This code work well & I can receive the packet to the server when some local client on the Linux machine tries to contact my server.
PROBLEM : When I make the same client in Android AVD present in my windows 7 system I am unable to reach my server.
I thought may be that's firewall issue, so I removed the firewall & added by pass custom rules to the IP "192.168.2.2" as given in the following link. http://www.brighthub.com/computing/windows-platform/articles/40014.aspx#
But it did not work. I thought that first I should try with raw java first then with AVD.
Hence, I created a UDP client with Java code still I was not able to connect to server.
Then I thought let's try with raw C++ so that I would come to know exactly what is the problem. Following is the Visual Studio code which I implemented for the same.
#define PORT_NUM 9999 // Port number used
#define IP_ADDR "192.168.2.2" // IP address of server1
#define BUFFER_SIZE 4096
void main(void){
WORD wVersionRequested = MAKEWORD(2,2); // Stuff for WSA functions
WSADATA wsaData; // Stuff for WSA functions
int client_s; // Client socket descriptor
struct sockaddr_in server_addr; // Server Internet address
int addr_len; // Internet address length
char out_buf[BUFFER_SIZE]; // Output buffer for data
char in_buf[BUFFER_SIZE]; // Input buffer for data
int retcode; // Return code
// This stuff initializes winsock
WSAStartup(wVersionRequested, &wsaData);
client_s = socket(AF_INET, SOCK_DGRAM, 0);
if (client_s < 0){ printf("*** ERROR - socket() failed \n"); exit(-1);}
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(PORT_NUM); // Port num to use
server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); // IP address to use
strcpy(out_buf, "Test message from CLIENT to SERVER");
retcode = sendto(client_s, out_buf, (strlen(out_buf) + 1), 0,(struct sockaddr *)&server_addr, sizeof(server_addr));
if (retcode < 0){printf("*** ERROR - sendto() failed \n");exit(-1);}
addr_len = sizeof(server_addr);
retcode = recvfrom(client_s, in_buf, sizeof(in_buf), 0,(struct sockaddr *)&server_addr, &addr_len);
if (retcode < 0){printf("*** ERROR - recvfrom() failed \n");exit(-1);}
printf("Received from server: %s \n", in_buf);
retcode = closesocket(client_s);
if (retcode < 0){ printf("*** ERROR - closesocket() failed \n");exit(-1);}
WSACleanup();
}
But it gives me error of destination unreachable.
To find out exactly what is going on at the packet level, I installed "Wireshark", on my ubuntu machine.
My observation is... whenever my windows client executes I get a ICMP message 3 times on the Wireshark having the type 3 message. The detailed analysis of the packet showed that the port is unreachable.
Kindly help me to find out what I am missing here :(.
Have you tried disabling the firewall on the linux machine, or adding an exception for the port you are using?
sudo ufw disable
or use the following to show your iptables firewall rules:
sudo iptables -L
Check the connection between the two machines
ICMP: ping win->lin and back
TCP: connect SSH, Samba, or even browser if you can run some web server
UDP: use nc (netcat) utility to test UDP/TCP connection between two machines
If one of these does not work, look for the problem :
Shut down the firewalls on both computers and on the wireless AP, run sniffers on Win and on Lin machines.
If the connection is ok, the you know you have a bug in your program. Start debugging each end against something working - i.e. nc.