I am trying to make a messenger program (that currently has a ton of bugs so please dismiss them) and for some reason, the server wont let the clients connect. I have tried changing the port, but nothing works. I get the following error (for my client, which is in python) (this is on a mac, but I have tried the client on a windows computer, still nothing):
Traceback (most recent call last):
File "msgclient.py", line 31, in <module>
Program()
File "msgclient.py", line 8, in __init__
self.s.connect((IP, PORT))
ConnectionRefusedError: [Errno 61] Connection refused
Here is the code for the server (written in c):
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#define MAXCLIENTS 256
#define MAXMSG 269
#define PORT 9989
void forward(int clientslist[MAXCLIENTS], char* msg) {
int x;
for (x=0; x < MAXCLIENTS; x++){
send(clientslist[x], msg, sizeof(msg), 0);
}
return;
}
int main(){
int s = socket(AF_INET, SOCK_STREAM, 0);
int clients[MAXCLIENTS];
int clientcounter = 0;
fd_set socketlist, readlist;
FD_ZERO(&socketlist);
FD_SET(s, &socketlist);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
bind(s, (struct sockaddr*) &server, sizeof(server));
listen(s, MAXCLIENTS);
int clientsocket;
int i;
int rc;
int max = s;
void* msg = (char *) malloc(MAXMSG+1);
void* usr = (char *) malloc(14);
while (1){
readlist = socketlist;
select(FD_SETSIZE, &readlist, NULL, NULL, NULL);
for (i=0; i<max+1; i++){
if(FD_ISSET(i, &readlist)){
if (i == s){
clientsocket = accept(s, NULL, NULL);
FD_SET(clientsocket, &socketlist);
clients[clientcounter] = clientsocket;
clientcounter++;
rc = recv(clientsocket, usr, 10, 0);
printf("Connection received from %s\n", usr);
usr = "\0";
if (clientsocket > max+1){
max = clientsocket;
}
} else {
rc = recv(i, msg, MAXMSG, 0);
if (rc > 0){
forward(clients, msg);
} else{
close(i);
msg = "\0";
}
}
}
}
}
return 0;
}
and the client (written in python):
import socket
class Program:
def __init__(self):
IP = socket.gethostbyname(socket.gethostname())
PORT = 9989
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.connect((IP, PORT))
self.user = self.username()
self.s.send(bytes(self.user, "utf-8"))
while True:
received = self.s.recv(269)
received = received.decode("utf-8")
print(received)
self.enter()
def username(self):
name = str(input("Enter a username (10 character max): "))
if len(name) > 10:
print("Username is larger than 10; try again")
self.username()
return name;
def enter(self):
msg = str(input("Enter a message>> "))
if msg != "":
self.s.send(bytes(f"{self.user}>> {msg}", "utf-8"))
if __name__ == "__main__":
Program()
regarding the function:
void forward(int clientslist[MAXCLIENTS], char* msg)
and
send(clientslist[x], msg, sizeof(msg), 0);
The expression: sizeof(msg) will return a value (depending on your underlying hardware and certain compiler parameters) of 4 or 8, Not what you want. Suggest passing the actual number of bytes to transmit.
regarding the function:
void forward(int clientslist[MAXCLIENTS], char* msg)
and the statement:
return;
The return; statement is completely unnecessary. Suggest removing that statement.
regarding:
int s = socket(AF_INET, SOCK_STREAM, 0);
This statement can fail. Always check (if socket < 0) then handle the error
regarding:
server.sin_addr.s_addr = INADDR_ANY;
INADDR_ANY has the value: "0.0.0.0" which cannot be directly assigned. Suggest:
server.sin_addr.s_addr = htonl(INADDR_ANY);
OT: regarding:
bind(s, (struct sockaddr*) &server, sizeof(server));
and
listen(s, MAXCLIENTS);
These functions can fail. Always check the returned value to assure the operation was successful.
OT: regarding:
void* msg = (char *) malloc(MAXMSG+1);
and similar statements. In C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code and is error prone. even this statement has an error in the cast. Suggest removing that cast.
regarding:
readlist = socketlist;
select(FD_SETSIZE, &readlist, NULL, NULL, NULL);
for (i=0; i<max+1; i++)
{
if(FD_ISSET(i, &readlist))
{
if (i == s)
{
This code sequence forces serial handling of the incoming sockets. Much better to generate a 'thread pool', then use accept() and pass the resulting client socket to an idle thread. The thread then performs all the communication with the client, then, when finishing with the client, closes the client socket.
regarding:
select(FD_SETSIZE, &readlist, NULL, NULL, NULL);
There must already be an open socket to the client, which there is none, so no communication occurs.
there may be other problems, but this should aim you in the right direction.
Related
I'm working on a project with a C++ client and a Python server.
int connecting(SOCKET s){
WSADATA wsa;
struct sockaddr_in server;
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
std::cout<<"WSA error";
return 1;
}
if((s=socket(AF_INET, SOCK_STREAM, 0))==INVALID_SOCKET){
std::cout<<"invalid socket";
return 1;
}
server.sin_addr.s_addr = inet_addr("192.168.1.10");
server.sin_family = AF_INET;
server.sin_port = htons(2424);
if(connect(s , (struct sockaddr *)&server , sizeof(server))!=0){
std::cout<<"error connecting";
return 1;
}
else{
return 0;
}
}
void recv_data(SOCKET socket){
char buf[buflen];
recv(socket, buf, buflen, 0);
std::cout<<buf;
}
int main(int argc, char* argv[]){
SOCKET s;
connecting(s);
recv_data(s);
}
Here's the very basic Python server.
import socket
import struct
s=socket.socket()
s.bind(("192.168.1.10", 2424))
s.listen(1)
c, a=s.accept()
print(f"{a}")
data="Hi from server"
c.send(data.encode())
After establishing the connection in the server, the a variable is printed. Nothing is received nor printed in the client-side. I tried putting in a loop the recv() function in the client but it does not work.
You misunderstood argument passing by value...
void f(int x) {
x = 5;
}
int main() {
int j = 7;
f(j);
printf("%d\n", j);
}
What is j? NOT 5! The number 7 was passed into f, where it was stored in the variable x, and then the number 5 was stored in the variable x, which is not the variable j, so j was not changed.
You have this in your program:
int main(int argc, char* argv[]){
SOCKET s;
connecting(s);
recv_data(s);
}
After the call connecting(s) what is s? NOT A SOCKET! Only the variable s inside the function connecting held a socket handle, and the variable s in main is not that variable, so it never got to hold a socket handle. You pass some uninitialized value to recv_data.
The function recv probably reads this random uninitialized value and returns an error code meaning "hey, that isn't a socket handle" but since your code never checked whether it returned an error code, you wouldn't know about this.
I have written code to set default gateway using ioctl in C. I have a function to set the gateway and the usual main function. When I compile and run the code it works fine, but when I turn it into a library and call the main function from python using ctypes the ioctl call fails. Why is this?
Note: Before using ctypes method, I tried to set gateway from python using fcntl, ioctl and socket but it failed with OSError saying invalid arguments.
gateway.c
int setDefaultGW( int sockfd, char* gatewatStr)
{
struct sockaddr_in *dst, *gw, *mask;
struct rtentry route;
in_addr_t gip;
fprintf( stderr,"socket %d\n", sockfd);
fprintf( stderr,"Address %s\n", gatewatStr);
gip = inet_addr(gatewatStr);
fprintf( stderr,"Address %d\n", gip);
memset(&route,0,sizeof(struct rtentry));
dst = (struct sockaddr_in *)(&(route.rt_dst));
gw = (struct sockaddr_in *)(&(route.rt_gateway));
mask = (struct sockaddr_in *)(&(route.rt_genmask));
/* Make sure we're talking about IP here */
dst->sin_family = AF_INET;
gw->sin_family = AF_INET;
mask->sin_family = AF_INET;
/* Set up the data for adding the default route */
dst->sin_addr.s_addr = inet_addr("0.0.0.0");
gw->sin_addr.s_addr = gip;
mask->sin_addr.s_addr = inet_addr("0.0.0.0");
route.rt_metric = 100;
route.rt_flags = RTF_UP | RTF_GATEWAY;
/* Remove this route if it already exists */
ioctl(sockfd,SIOCDELRT,&route);
/* Add the default route */
if( ioctl(sockfd,SIOCADDRT,&route) < 0 )
{
fprintf( stderr,"Adding default route: %d\n", errno);
return -1;
}
fprintf( stdout,"Added default route successfully.\n" );
return 0;
}
int main(){
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{
perror("socket creation failed\n");
return;
}
setDefaultGW(sockfd, "192.168.6.1");
return 0;
}
net.py
gatewayFun = ctypes.CDLL("./libgateway.so")
gatewayFun.main()
Running the C binary:
./gateway
socket 3
Address 192.168.6.1
Address 17213632
Added default route successfully.
Running the python script:
# python3 net.py
socket 4
Address 192.168.6.1
Address 17213632
Adding default route: 101
I have a multicast packet from a capture using tcpdump. I can replay the packet using tcpreplay -i eth0 on.pcap and I can receive it on another machine using tcpdump.
I have tried c code and python code to try and capture this packet without success. I've tried both on MacOS and Raspian (Rpi 3b).
https://mega.nz/#!ELAgBSDL!XZ3EXCkDBsLLwFn8J1ofWuMm4Z7sssOZPuZVEpmRqvs
here is a c code example:
/*
multicast.c
The following program sends or receives multicast packets. If invoked
with one argument, it sends a packet containing the current time to an
arbitrarily chosen multicast group and UDP port. If invoked with no
arguments, it receives and prints these packets. Start it as a sender on
just one host and as a receiver on all the other hosts
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#define EXAMPLE_PORT 2068
#define EXAMPLE_GROUP "226.2.2.2"
main(int argc)
{
struct sockaddr_in addr;
int addrlen, sock, cnt;
struct ip_mreq mreq;
char message[50];
/* set up socket */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
perror("socket");
exit(1);
}
bzero((char *)&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(EXAMPLE_PORT);
addrlen = sizeof(addr);
if (argc > 1)
{
/* send */
addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
while (1)
{
time_t t = time(0);
sprintf(message, "time is %-24.24s", ctime(&t));
printf("sending: %s\n", message);
cnt = sendto(sock, message, sizeof(message), 0,
(struct sockaddr *) &addr, addrlen);
if (cnt < 0)
{
perror("sendto");
exit(1);
}
sleep(5);
}
}
else
{
/* receive */
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
perror("bind");
exit(1);
}
mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof(mreq)) < 0)
{
perror("setsockopt mreq");
exit(1);
}
while (1)
{
cnt = recvfrom(sock, message, sizeof(message), 0,
(struct sockaddr *) &addr, &addrlen);
if (cnt < 0)
{
perror("recvfrom");
exit(1);
}
else if (cnt == 0)
{
break;
}
printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message);
}
}
}
Here is a python example:
#!/usr/bin/env python
import socket
import binascii
import sys
MCAST_GRP = '226.2.2.2'
MCAST_PORT = 2068
MCAST_IFACE = '192.168.168.200'
def joinMcast(mcast_addr,port,if_ip):
"""
Returns a live multicast socket
mcast_addr is a dotted string format of the multicast group
port is an integer of the UDP port you want to receive
if_ip is a dotted string format of the interface you will use
"""
#create a UDP socket
mcastsock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#allow other sockets to bind this port too
mcastsock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#explicitly join the multicast group on the interface specified
mcastsock.setsockopt(socket.SOL_IP,socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(mcast_addr)+socket.inet_aton(if_ip))
#finally bind the socket to start getting data into your socket
mcastsock.bind((mcast_addr,port))
return mcastsock
def main():
sock = joinMcast(MCAST_GRP, MCAST_PORT, MCAST_IFACE)
while True:
print >>sys.stderr, '\nwaiting to receive message'
print sock.recv(1024)
if __name__ == '__main__':
main()
I made a simple webserver using c. I can connect to it via a web browser and it works fine.
The goal of this webserver was to exploit it. So I wrote a simple python script that sends malicious data to the server. However, I only get an error message on the server saying: "Bad file descriptor".
C-Server Main:
int main(void) {
int sockfd, new_sockfd, yes=1;
struct sockaddr_in host_addr, client_addr;
socklen_t sin_size;
printf("Accepting web requests on port %d\n", PORT);
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
error_and_exit("in socket");
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
error_and_exit("setting socket option SO_REUSEADDR");
host_addr.sin_family = AF_INET;
host_addr.sin_port = htons(PORT);
host_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(host_addr.sin_zero), '\0', 8);
if (bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)) == -1)
error_and_exit("binding to socket");
if (listen(sockfd, 20) == -1)
error_and_exit("listening on socket");
while(1) { // Accept loop
sin_size = sizeof(struct sockaddr_in);
new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
if(new_sockfd == -1)
error_and_exit("accepting connection");
handle_connection(new_sockfd, &client_addr);
}
return 0;
}
python code:
import socket
import struct
import sys
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('127.0.0.1', 8000)
sock.connect(server_address)
shellcode =(....)
values = ....
try:
sock.sendall(values)
finally:
sock.close()
Notes:
1.
the accept function (from <sys/socket.h>) in the while(1) loop returns -1, calling error_and_exit("accepting connection"). So the Server never executes handle_connection for my python client.
2.
Code for error_and_exit function:
void error_and_exit(char *message) {
char error_message[100];
strcpy(error_message, " Error ");
strncat(error_message, message, 83);
perror(error_message);
exit(-1);
}
I am trying to implement a UDP communication protocol between a C program and a python program. The C program has a structure that it sends through the UDP port (tx_port) as binary data. This program also listens on another port (rx_port) for any received data, and then prints the received binary output to the screen.
The python program listens on tx_port and unpacks the received data and prints it to the screen. Then it repacks the data and sends it back through UDP port (rx_port).
Here are the C and Python programs that I used.
C program
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <pthread.h>
#define BUFLEN 4096
#define RX_PORT 8888
#define TX_PORT 8889
// Structure data
struct data {
long frame_number;
double time;
} tx_data, rx_data;
int dlen = sizeof(tx_data);
struct sockaddr_in si_me, si_other;
int tx_soc;
int slen = sizeof(si_other);
int recv_len;
char* buf;
pthread_t rx_thread;
void* receiver_thread(void *arg)
{
int i =0;
while (1) {
recv_len = recvfrom(tx_soc, buf, sizeof(rx_data), 0, (struct sockaddr *) &si_other, &slen);
printf("\nReceived data : %d\n", recv_len);
for (i = 0; i < recv_len; i++) {
printf("%x ", buf[i]);
}
printf("\n");
fflush(stdout);
};
}
void data_init(void) {
tx_data.frame_number = 0;
tx_data.time = 0;
};
int main(void)
{
// Initialize data
data_init();
//create a UDP socket
if ((tx_soc=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("Socket error!");
exit(0);
}
// zero out the structure
memset((char *) &si_me, 0, sizeof(si_other));
memset((char *) &si_other, 0, sizeof(si_other));
// Host socket address
si_me.sin_family = AF_INET;
si_me.sin_port = htons(RX_PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
// Remote socket address
si_other.sin_family = AF_INET;
si_other.sin_port = htons(TX_PORT);
si_other.sin_addr.s_addr = htonl(INADDR_ANY);
//bind sockets to the ports
if( bind(tx_soc, (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
{
printf("Binding error!");
}
// Start reader thread.
if (pthread_create(&rx_thread, NULL, &receiver_thread, NULL) != 0) {
printf("\ncan't create thread");
}
//keep listening for data
while(1)
{
// Allocate memory for receive buffer.
buf = (char*) malloc(sizeof(rx_data));
// Update data value.
tx_data.frame_number++;
printf("\nFrame numner: %ld", tx_data.frame_number);
fflush(stdout);
// Send data.
if (sendto(tx_soc, (char*)&tx_data, dlen, 0, (struct sockaddr*) &si_other, slen) == -1)
{
printf("Sending error!");
}
sleep(1);
}
close(tx_soc);
return 0;
}
Python program
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import struct
# Packet format string
packet_fmt = ''.join(['i', # Frame number
'd', # Frame time stamp
])
s = struct.Struct(packet_fmt)
class Echo(DatagramProtocol):
def datagramReceived(self, data, (host, port)):
new_data = s.unpack(data)
print new_data
echo_data = s.pack(*new_data)
self.transport.write(echo_data, (host, port))
reactor.listenUDP(8889, Echo())
reactor.run()
When I execute the two programs, I am able to receive data on both sides. I am able to unpack data in python, print it, repack and send it.
But on the C side, the received data does not match the sent data. I have checked on the python side to make sure the repacked data matches the original data.
Here is a sample output from the C and Python programs. I started the python programs first, and then the C program.
What is the mistake I might be making?