Trouble Setting Up Ad-hoc Network From Terminal - c

I'm trying to connect to a server I'm running in C on a computer on a wireless ad-hoc network. The problem is when I'm to connect from another computer on the network using telnet it doesn't work. I can ping the IP address (192.168.0.1) but using:
telnet 192.168.0.1 8889
results in the error "Connection Refused" (The server is listening on port 8889 which I've verified).
I've investigated further and found that setting up my ad-hoc network using network manager solves this problem. Currently I'm setting up my ad-hoc network via terminal and I would like to keep it this way. The ad-hoc network is being setup with the following commands:
sudo service network-manager stop
sudo iwconfig wlan0 mode ad-hoc essid 'rgd' channel AUTO key OFF
Where wlan0 is my wireless device.
I'm not sure why this error is occurring. Can anybody help me with this?
Edit: #Huygens netstat -tlpen displays the following
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:48727 0.0.0.0:* LISTEN 1000 302920 13098/socket
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 0 273220 933/cupsd
tcp 0 0 0.0.0.0:54880 0.0.0.0:* LISTEN 1000 304089 13148/socket
tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN 0 12886 1606/dnsmasq
tcp6 0 0 ::1:631 :::* LISTEN 0 273219 933/cupsd
tcp6 0 0 ::1:54822 :::* LISTEN 1000 46736 3297/java
I don't see my server here for some reason :(
I've added the server code I'm running here for further reference:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c;
struct sockaddr_in server , client;
char *message;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8889 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (new_socket<0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Reply to the client
message = "Hello Client , I have received your connection. But I have to go now, bye\n";
write(new_socket , message , strlen(message));
return 0;
}

You have to do things in the proper order I think.
First you should set-up your network interfaces. Once done, you should check that you can ping your network interfaces and that if you have a firewall that it would allow incoming connection on port 8889. To see of you have a firewall activated: iptables -L if there are any rule, then you have a firewall. In addition, make sure that each network interface has the expected IP address: ifconfig.
For testing purpose and if you are on a safe network, you can temporarily disable the firewall: iptables -F (precede it by sudo if you require super user privilege).
Then, you can start your server. Check that it is up and running (via ps wux) and check that it is in listening mode via netstat -tlpen.
Now try to telnet to it via telnet 192.168.0.1 8889.
PS: Of course your ad-hoc network should be on a different subnet than your local network. So if you are using both your ethernet (cable) network and an ad-hoc wifi network, each should be on a different subnet: e.g. 192.168.0.1/24 and 192.168.1.1/24.

Related

How to connect a TCP server to another TCP server

I'm working with TCP servers. Let's say I have a server running with a specific port, but then I want to connect a client to it, I would simply go through the typical procedure of socket, bind, listen, accept for the server and then socket, connect for the client. So let's say our server port is 4000, and our client port 4001. Now, I want to create a new client that will connect to my client on port 4001, but to my limited understanding, I cannot do this as a client. Port 4001 would have to pertain to a server and not a client (i.e. it would have to be listening). The issue arises because I don't think you can use the same port for both the server and client.
I've decided to attempt this through the sample code I've provided below. I call the program on the command line as follows:
If this is the first call of the server, then I simply call the program without any arguments and it will automatically run on port 3000. i.e. ./serverprogram
If I would like to connect a client on port 3001 to our server on port 3000. Then I would call the command line with two arguments, the first being 3001 and the second being 3000. i.e. ./serverprogram 3001 3000
#define PORT 3000
int main (int argc, char * argv[]){
int sfd = socket(AF_INET, SOCK_STREAM, 0);
int my_port = (argc == 3) ? atoi(argv[1]) : PORT;
if (argc > 2){
struct sockaddr_in c_addr;
c_addr.sin_family = AF_INET;
memset(&c_addr.sin_zero, 0, 8);
c_addr.sin_port = htons(atoi(argv[2]));
struct addrinfo *result = NULL;
getaddrinfo("AcaciaLinux", NULL, NULL, &result);
struct sockaddr_in *x = (struct sockaddr_in*) result->ai_addr;
c_addr.sin_addr = x->sin_addr;
freeaddrinfo(result);
if(connect(sfd, (struct sockaddr *) &c_addr, sizeof(struct sockaddr_in)) == -1){
perror("connect");
exit(1);
}
printf("We have connected to a server.");
}
if (sfd == -1){
perror("socket");
exit(1);
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(my_port);
saddr.sin_addr.s_addr = INADDR_ANY;
memset(&(saddr.sin_zero), 0, 8);
if(bind(sfd, (struct sockaddr*) &saddr, sizeof(struct sockaddr_in)) == -1){
perror("bind");
close(sfd);
exit(1);
}
if (listen(sfd, 5) < 0){
perror("listen");
exit(1);
}
struct sockaddr_in caddr;
saddr.sin_family = AF_INET;
int cfd;
unsigned int c_len = sizeof(struct sockaddr_in);
if ((cfd = accept(sfd, (struct sockaddr*) &caddr, &c_len)) == -1){
perror("accept");
exit(1);
}
printf("Alas, we have finally connected to a client.");
return 0;
}
Upon running the second instance of the program I receive the error "bind: Invalid argument". I am assuming that this is due to the fact that the port is already in use. Is there any way to bypass this, or is there any way to connect a server to a client, and allow the client to also act as a server using the same port
You cannot open a socket which can do the both listen and connect.
A TCP connection is identified by its two endpoints. Each of those, in turn, is identified by an (IP address, port) pair. Therefore, you cannot simultaneously have two distinct connections between the same two IP addresses with the same ports on each end -- if all of those properties are the same, then they are the same connection.
From the perspective of system interfaces, you cannot create that situation because the system will not allow you to bind an address / port pair that is already in use to any socket (a stronger constraint than is strictly required). This means that one machine cannot use the same port simultaneously for both a client socket and a server socket, even for different remote endpoints.
You can, however, have any number of simultaneous TCP connections that each differ from all the others in at least one of those parameters. In particular, you can have any number of connections between the same two machines, with the same port on one side, and different ports on the other. This is extremely common, in fact, as web browsers often open multiple simultaneous connections to a web server to download multiple resources concurrently. All of those connections have the same server address, server port, and client address, but different client port.
If you want to have multiple simultaneous connections that are associated with one another in some way that goes beyond IP addresses, then you'll need to develop a protocol for it that involves multiple ports at at least one end. If the machines make reciprocal connections, with A connecting to B and then B connecting, separately, to A, then you'll need different ports on both sides. The port numbers to use might be fixed by the protocol or negotiated in some way, at your discretion, but the specifics described in the question are not an option.

TCP server takes wrong port number on ubuntu 14.04

I am doing socket programming in C, and when i am starting my tcpserver on address INADDR_ANY and port no 2000, it starts well. But using command 'netstat -tulpn' , it shows the server is assigned port number 53255. Clients are able to connect to this server when they connect using server port number 53255, but get connection refusals when they try connect to port number '2000'.
Can somebody pls explain why the system is assigning the wrong port no to my tcpserver instead of one i am want to use which is 2000.
vm#vm:~/Documents/csepracticals/webserver/TCPWebserver$ netstat -tulpn
...
...
tcp 0 0 0.0.0.0:53255 0.0.0.0:* LISTEN 16291/webserver`
server_addr.sin_family = AF_INET;
server_addr.sin_port = SERVER_PORT; /*#defined to 2000*/
server_addr.sin_addr.s_addr = INADDR_ANY;
bind(master_sock_tcp_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
You should use htons(SERVER_PORT) instead of SERVER_PORT

Destination port unreachable in my udp client socket

int udp_sock() {
//Create socket
sock = socket(AF_INET , SOCK_DGRAM , 0);
if (sock == -1) {
printf("Could not create socket\n");
}
puts("Socket created.......\n");
server1.sin_addr.s_addr = inet_addr("172.210.110.10");
server1.sin_family = AF_INET;
server1.sin_port = htons(PORT);
//Connect to remote server
con= connect(sock , (struct sockaddr *)&server1 , sizeof(server1));
if(con<0) {
perror("connect failed. Error\n");
return con;
}
puts("Connected\n");
return 0;
}
The packet is reaching server mentioned, but the error "destination port unreachable" comes up in Wireshark.
How to assign a UDP port on my client to receive data on a particular port?
How to assign two different ports - 1024 and 1025 to receive data?
Any suggestions will be helpful.
There needs to be a server waiting on the other end. A simple way for testing is to use netcat.
nc -lu 8053
Alternatively set up a utility that is designed for udp testing, such as echo server. This is normally built into an inetd or xinetd server
If you want to intercept incoming udp packets you will need to use bind() select()/poll()/epoll() and recvfrom()

Talking to C socket with Scapy

I have a UDP connection up and listening on a port (localhost) and I am trying to send a Scapy packet from localhost as well. For some reason, my C code never actually captures the packet, however I can see the packet show up in Wireshark just fine. It's been awhile since I've used sockets, but is there some special socket options I have to set or why would I be able to see the packet in Wireshark just fine but not by the C socket?
Note: I was able to successfully catch a packet when I wrote corresponding socket code to send out packets (from localhost) however I am still unable to get the listening code to catch the packet when sent from another computer.
I have found a similar question but when I tried their approach (using UDP instead of TCP), I still couldn't get netcat to catch the Scapy packet.
C Code (condensed for clarity sake)
int main() {
int sock, dataLen, inLen;
struct sockaddr_in inAddr;
short listen_port = 8080;
char buffer[2048];
if (sock = socket(AF_INET,SOCK_DGRAM,0) < 0) {
printf("ERROR: unable to establish socket\n");
return -1;
}
// zero out address structure
memset(&inAddr, 0, sizeof(inAddr));
inAddr.sin_family = AF_INET;
inAddr.sin_addr.s_addr = htonl(INADDR_ANY);
inAddr.sin_port = htons(listen_port);
if (bind(sock, (struct sockaddr*)&inAddr, sizeof(inAddr)) < 0) {
printf("ERROR: unable to bind\n");
return -1;
}
inLen = sizeof(inAddr);
printf("Now listening on port %d\n", listen_port);
while(1) {
dataLen = recvfrom(sock, buffer, 1500, 0, (struct sockaddr*)&inAddr, &inLen);
if (dataLen < 0)
printf("Error receiving datagram\n");
else
printf("Received packet of length %d\n", dataLen);
}
return 0;
}
Scapy Script
# set interface
conf.iface="lo0"
# create IP packet
ip_pkt = IP()/UDP()
ip_pkt.payload = "payload test message"
ip_pkt.dport = 8080
ip_pkt.dst = "127.0.0.1"
ip_pkt.src = "127.0.0.1"
# send out packet
send(ip_pkt)
Scapy needs to be configured slightly differently to work on the Loopback interface, see http://www.secdev.org/projects/scapy/doc/troubleshooting.html under the heading "I can’t ping 127.0.0.1. Scapy does not work with 127.0.0.1 or on the loopback interface"
I used the code given there and sent a scapy packet which was received by a C Socket, this was specifically:
from scapy.all import *
conf.L3socket=L3RawSocket
packet=IP()/UDP(dport=32000)/"HELLO WORLD"
send(packet)
This was then received on a UDP C Socket bound to lo on port 32000 (Scapy defaults to sending IP packets over the loopback interface).
I have the same problem, udp socket does not receive scapy packet.
I suppose there might be something related to this post: Raw Socket Help: Why UDP packets created by raw sockets are not being received by kernel UDP?
And what works for me is the socket.IP_HDRINCL option. Here is the working code for both and sender.
sender:
import socket
from scapy.all import *
rawudp=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
rawudp.bind(('0.0.0.0',56789))
rawudp.setsockopt(socket.SOL_IP, socket.IP_HDRINCL,1)
pkt = IP()/UDP(sport=56789, dport=7890)/'hello'
rawudp.sendto(pkt.build(), ('127.0.0.1',7890))
receiver:
import socket
so = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
so.bind(('0.0.0.0',7890))
while True:
print so.recv(1024)
Verified on Fedora 14, although doesn't work on my MBP...
I think the problem is in setting incompatible set of interface, src and dst address.
When destination is loopback (127.0.0.1), interface should be lo and addresses (assuming both client and server run on the same host):
ip_pkt.dst = "127.0.0.1"
ip_pkt.src = "127.0.0.1"
Another way is to send to the ethernet address (assuming 192.168.1.1 is configured on eth0 and both client and server run on the same host):
ip_pkt.dst = "192.168.1.1"
ip_pkt.src = "192.168.1.1"
If you try different hosts, then using 127.0.0.1 and lo is not possible. Set src to client machine's ip and dst to server machine's ip.

Basic C Server: Connection Refused Error

I have a program that should accept a connection at port 62085 and sends back a test message. The code hangs at accept() and never returns even if the client tries to connect. Why does the server refuse the connections? Could it be a firewall problem?
This code works for me when compiled under OS X 10.8.3, but refuses connections when running on Oracle Enterprise Linux. accept() will never accept a connection, and telnet to the port from another device gives a Connection Refused error. The below is output from netstat that proves the program is in fact listening on the port I want. I have tried other ports, 62084, 666 and 8080 to see if there was something blocking that particular port. (The netstat outputs were from two different commands).
tcp 0 0 0.0.0.0:62085 0.0.0.0:* LISTEN 11815/del-chef
tcp 0 0 129.133.124.83:62085 0.0.0.0:* LISTEN 15101/del-chef
iptables shows that it is allowing connections on all ports as well.
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:https
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:yo-main
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:terabase
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination`
And the output of sudo iptables -t mangle -L is
the output of that command is
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
Both the OS X device and Enterprise Linux Server are running on the same network, so I am befuddled as to why when I execute telnet XXX.XXX.XXX.XXX 62085 I receive a Connection Refused error.
The relevant code is below:
#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 <netdb.h>
#include <fcntl.h>
#include <syslog.h>
#include <signal.h>
#define BACKLOG 10
#define PORT "62085"
void main() {
struct sockaddr_in cli_addr;
socklen_t addr_size;
struct addrinfo hints, *res, *p;
int sockfd, new_fd;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // use IPv4
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
if (getaddrinfo(NULL, PORT, &hints, &res) != 0){
syslog(LOG_ERR, "getaddrinfo() error");
exit(1);
}
for (p = res; p != NULL; p = p->ai_next){
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
syslog(LOG_ERR, "Error creating socket");
continue;
}
int yes = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
syslog(LOG_ERR, "Error settings socket options");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
close(sockfd);
syslog(LOG_ERR, "Error binding socket");
continue;
}
break;
}
if (p == NULL){
close(sockfd);
syslog(LOG_ERR, "Error binding socket");
exit(1);
}
freeaddrinfo(res); // free memory now that it is no longer in use
if (listen(sockfd, BACKLOG) == -1){
close(sockfd);
syslog(LOG_ERR, "Error listening");
exit(1);
}
syslog(LOG_INFO, "Waiting for connections");
addr_size = sizeof(cli_addr);
if (new_fd = accept(sockfd, (struct sockaddr *)&cli_addr, &addr_size) == -1){
syslog(LOG_ERR, "Error accepting connection");
}
}
There is nothing wrong with the code you have shown, so the problem is external to your app. Since your socket is clearly listening and bas not exhausted its backlog yet, then the connection refused error has to mean that the OS itself, or possibly/likely a firewall/router, is refusing the connection before it reaches your app.
Turns out it was iptables, issuing service stop iptables allowed the code to work. I ended up adding the following rule to iptables:
sudo iptables -I INPUT 5 -m state --state NEW -m tcp -p tcp --dport 62085 -j ACCEPT

Resources