libnids didn't capture xmpp packet - c++

this program can detect http flow and etc....
but it ignores XMPP flow ; i don't know why ?
(I guess this is a port problem , but i don't know where i should fix it )
Below are the relevant sections from main.cpp :
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include "nids.h"
#include <cstdlib>
#include <unistd.h>
#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x))
// struct tuple4 contains addresses and port numbers of the TCP connections
// the following auxiliary function produces a string looking like
// 10.0.0.1,1024,10.0.0.2,23
char *
adres (struct tuple4 addr)
{
static char buf[256];
strcpy (buf, int_ntoa (addr.saddr));
sprintf (buf + strlen (buf), ",%i,", addr.source);
strcat (buf, int_ntoa (addr.daddr));
sprintf (buf + strlen (buf), ",%i", addr.dest);
return buf;
}
void
tcp_callback (struct tcp_stream *a_tcp, void ** this_time_not_needed)
{
printf("packet captured !\n");
}
int
main ()
{
// here we can alter libnids params, for instance:
// nids_params.n_hosts=256;
struct nids_chksum_ctl nochksumchk;
nochksumchk.netaddr = 0;
nochksumchk.mask = 0;
nochksumchk.action = NIDS_DONT_CHKSUM;
//char fileName[] = "/home/test.pcap";
//nids_params.filename =fileName;
nids_register_chksum_ctl(&nochksumchk, 1);
char myDevice [] = "eth0";
nids_params.device =myDevice;
if (!nids_init ())
{
fprintf(stderr,"%s\n",nids_errbuf);
exit(1);
}
nids_register_tcp ( (void*)tcp_callback);
nids_run ();
return 0;
}

My pcap file has some problem about syncing in tcp connection .
So above snippet code of libnids is correct !

Related

How to create or manage Libuv TCP server in a c++ fuction?

I am trying to create a TCP server in a function int create_server(int port_number, char ip_addr_string[IPV4_ADDR_SIZE]) which is called in main.
When I run the c++ code given below: Assertion failed: (w->fd >= 0), function uv__io_poll, file kqueue.c, line 149.
#include <iostream>
#include <vector>
#include <algorithm>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <future>
#include <sys/types.h>
#include <uv.h>
#define IPV4_ADDR_SIZE 15
uv_loop_t* loop;
struct sockaddr_in addr;
std::map <int, uv_tcp_t * > pool;
int create_tunnel(int port_number, char ip_addr_string[IPV4_ADDR_SIZE]){
uv_tcp_t global_server;
uv_tcp_init(loop, &global_server);
uv_ip4_addr("0.0.0.0", port_number, &addr);
uv_tcp_bind(&global_server, (const struct sockaddr *)&addr, 0);
int r = uv_listen((uv_stream_t *)&global_server, 128, NULL);
if(r){
fprintf(stderr, "Listen error: %s \n", uv_strerror(r));
}
else{
fprintf(stdout, "Listening on: %d \n", port_number);
}
pool[rand()] = &global_server;
return r;
}
int main(int argc, const char *argv[]){
int status = 1;
loop = uv_default_loop();
uv_loop_init(loop);
loop->data = &pool;
status = create_tunnel(7011, (char*)"0.0.0.0");
std::cout<< "status: " << status << std::endl;
uv_run(loop, UV_RUN_DEFAULT);
return 0;
I think this error is because the servers created are not tracked by the event_loop when the create_server function ends, but I am not sure.
Any help, please?

Using getsockopt to check the initial value of SO_DEBUG option

I am trying to understand the nature of getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen).
I am trying to see the initial status of SO_DEBUG and I am referring to this link https://www.mkssoftware.com/docs/man3/getsockopt.3.asp , and I am not sure if I am doing this the correct way because I am getting random values.
//***********************************************Libraries****************************************************************
#include <iostream>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
using namespace std;
//************************************************************************************************************************
int main()
{
int * optval;
int optionDebug = 0;
socklen_t optlen;
int sockFD;
sockFD = socket(AF_INET, SOCK_STREAM ,0);
optlen =sizeof(optval);
int udpFD;
udpFD = socket(AF_INET, SOCK_DGRAM,0);
optionDebug = getsockopt(sockFD, SOL_SOCKET, SO_DEBUG, optval, &optlen) ;
cout<<"My value "<< *optval<<endl;
return 0;
}
To retrieve the value for optval you need to pass the address of a valid variable (not an uninitialized pointer):
ExpectedOptType optval;
// ^^^^^^^^^^^^^^^ Put whatever type (probably a enum) is expected for
// the specific option
optionDebug = getsockopt(sockFD, SOL_SOCKET, SO_DEBUG, &optval, &optlen);
// ^
Read more details about how it works here: getsockopt(2).

HTTPS with openssl on linux in C/C++

I have a project where I need to create a secure http server in C/C++ on Linux and I've chosen to use openssl, however, when I try to include the applinker.c from their github I see a lot of errors, mostly because the file seems to be written for Windows.I would like to know if there is an alternative for Linux or how should I deal with this.
Here is the applinker.c code:
/*
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#define APPLINK_STDIN 1
#define APPLINK_STDOUT 2
#define APPLINK_STDERR 3
#define APPLINK_FPRINTF 4
#define APPLINK_FGETS 5
#define APPLINK_FREAD 6
#define APPLINK_FWRITE 7
#define APPLINK_FSETMOD 8
#define APPLINK_FEOF 9
#define APPLINK_FCLOSE 10 /* should not be used */
#define APPLINK_FOPEN 11 /* solely for completeness */
#define APPLINK_FSEEK 12
#define APPLINK_FTELL 13
#define APPLINK_FFLUSH 14
#define APPLINK_FERROR 15
#define APPLINK_CLEARERR 16
#define APPLINK_FILENO 17 /* to be used with below */
#define APPLINK_OPEN 18 /* formally can't be used, as flags can vary */
#define APPLINK_READ 19
#define APPLINK_WRITE 20
#define APPLINK_LSEEK 21
#define APPLINK_CLOSE 22
#define APPLINK_MAX 22 /* always same as last macro */
#ifndef APPMACROS_ONLY
# include <stdio.h>
# include <io.h>
# include <fcntl.h>
static void *app_stdin(void)
{
return stdin;
}
static void *app_stdout(void)
{
return stdout;
}
static void *app_stderr(void)
{
return stderr;
}
static int app_feof(FILE *fp)
{
return feof(fp);
}
static int app_ferror(FILE *fp)
{
return ferror(fp);
}
static void app_clearerr(FILE *fp)
{
clearerr(fp);
}
static int app_fileno(FILE *fp)
{
return _fileno(fp);
}
static int app_fsetmod(FILE *fp, char mod)
{
return _setmode(_fileno(fp), mod == 'b' ? _O_BINARY : _O_TEXT);
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport)
void **
# if defined(__BORLANDC__)
/*
* __stdcall appears to be the only way to get the name
* decoration right with Borland C. Otherwise it works
* purely incidentally, as we pass no parameters.
*/
__stdcall
# else
__cdecl
# endif
OPENSSL_Applink(void)
{
static int once = 1;
static void *OPENSSL_ApplinkTable[APPLINK_MAX + 1] =
{ (void *)APPLINK_MAX };
if (once) {
OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout;
OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr;
OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf;
OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets;
OPENSSL_ApplinkTable[APPLINK_FREAD] = fread;
OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite;
OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod;
OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof;
OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose;
OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen;
OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek;
OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell;
OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush;
OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror;
OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr;
OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno;
OPENSSL_ApplinkTable[APPLINK_OPEN] = _open;
OPENSSL_ApplinkTable[APPLINK_READ] = _read;
OPENSSL_ApplinkTable[APPLINK_WRITE] = _write;
OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek;
OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close;
once = 0;
}
return OPENSSL_ApplinkTable;
}
#ifdef __cplusplus
}
#endif
#endif
And here is a little snippet I prepared for testing the connection:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>
#include <cerrno>
#include <arpa/inet.h>
#include <cstdio>
#include <sys/stat.h>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <fstream>
#include <thread>
#include "openssl-master/ms/applink.c"
#include "openssl-master/include/openssl/bio.h"
#include "openssl-master/include/openssl/ssl.h"
#include "openssl-master/include/openssl/err.h"
#define PORT 2024
void InitializeSSL()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void DestroySSL()
{
ERR_free_strings();
EVP_cleanup();
}
void ShutdownSSL(SSL *ssl)
{
SSL_shutdown(ssl);
SSL_free(ssl);
}
int main(int argc, const char * argv[]) {
int sockfd, newsockfd;
SSL_CTX *sslctx;
SSL *cSSL;
InitializeSSL();
struct sockaddr_in server;
struct sockaddr_in from;
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
int use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);
int use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);
int sd;
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket() error.\n");
return errno;
}
bzero (&server, sizeof (server));
bzero (&from, sizeof (from));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl (INADDR_ANY);
server.sin_port = htons (PORT);
if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1)
{
perror ("bind() error.\n");
return errno;
}
if (listen (sd, 5) == -1)
{
perror ("listen() error.\n");
return errno;
}
int client;
socklen_t length = sizeof (from);
printf ("Waiting on port %d...\n",PORT);
fflush (stdout);
client = accept (sd, (struct sockaddr *) &from, &length);
if (client < 0)
{
perror ("accept() error.\n");
return 0;
}
cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, client);
int ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0)
{
ShutdownSSL(cSSL);
}
return 0;
}
And I compile it like this: g++ withssl.cpp libssl.a libcrypto.a -lssl -lcrypto -o server.bin
Code looks good, I used Suse Leap 4.2.2 and performed these commands:
openssl version
OpenSSL 1.0.2j-fips 26 Sep 2016
sudo zypper in openssl-devel
g++ -std=c++11 main.cpp -lssl -lcrypto -o server
Because I am using the distro provided openssl I changed your code to include the standard headers like this:
#include <openssl/ssl.h>
#include <openssl/err.h>
// DONT NEED
// suggest instead of including C code, link to the libraries
// for example, /usr/lib64/libssl.so contains referenced functions
// observe the provided functions using a command like this
// readelf -a /usr/lib64/libssl.so | grep FUNC
// #include "openssl-master/ms/applink.c"
// WRONG PATH?
// suggest you use a distro provided openssl instead of building your own
// #include "openssl-master/include/openssl/bio.h"
// #include "openssl-master/include/openssl/ssl.h"
// #include "openssl-master/include/openssl/err.h"

How to create pty that is connectable by Screen app in Linux

I wanted to create C/C++ application, that creates new (virtual) device in /dev/xxx and will be able to connect with 'screen' application.
For example program running in loop, that creates new /dev/ttyABC. Then I'll use 'screen /dev/ttyABC', and when I send there some chars, then app send it back to the 'screen'.
I really don't know where start. I found some referencies on pty library but I don't even know, if I have right direction.
Could you help me? Where to look? Post example?
Thanks
You could use a Pseudoterminal via openpty to achieve this. openpty returns a pair of file descriptors (master and slave pty devices) that are connected to each other via their stdout / stdin. The output of one will appear at the input of another and vice-versa.
Using this (rough!) example...
#include <fcntl.h>
#include <cstdio>
#include <errno.h>
#include <pty.h>
#include <string.h>
#include <unistd.h>
int main(int, char const *[])
{
int master, slave;
char name[256];
auto e = openpty(&master, &slave, &name[0], nullptr, nullptr);
if(0 > e) {
std::printf("Error: %s\n", strerror(errno));
return -1;
}
std::printf("Slave PTY: %s\n", name);
int r;
while((r = read(master, &name[0], sizeof(name)-1)) > 0) {
name[r] = '\0';
std::printf("%s", &name[0]);
}
close(slave);
close(master);
return 0;
}
... Echoing some text (in another terminal session) to the slave pty sends it to master's input. E.g. echo "Hello" > /dev/pts/2
Based on the answer provided by #gmbeard , I was able to create an echo PTY device and connect to it with screen and minicom. What made the difference was using a raw PTY device by initializing a termios struct.
Here is the code
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <cstdio>
#include <pty.h>
#include <termios.h>
#define BUF_SIZE (256)
int main(int, char const *[])
{
int master, slave;
char buf[BUF_SIZE];
struct termios tty;
tty.c_iflag = (tcflag_t) 0;
tty.c_lflag = (tcflag_t) 0;
tty.c_cflag = CS8;
tty.c_oflag = (tcflag_t) 0;
auto e = openpty(&master, &slave, buf, &tty, nullptr);
if(0 > e) {
std::printf("Error: %s\n", strerror(errno));
return -1;
}
std::printf("Slave PTY: %s\n", buf);
int r;
while ( (r = read(master, buf, BUF_SIZE)) > 0 )
{
write(master, buf, r);
}
close(slave);
close(master);
return 0;
}

simple client/server program using named pipes in linux

I am trying to write a program that has two separate process that talk via named pipes. The client which sends a message to a server, and the server which needs to broadcast that message to all clients attached to it. So far, I can get a connection between the two, but I cannot get more than one message to work no matter what I have tried. Below is the code I have written that will allow a connection and transmission of a single message.
server.cpp:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#define FIFO_FILE_1 "/tmp/client_to_server_fifo"
#define FIFO_FILE_2 "/tmp/server_to_client_fifo"
int main()
{
int client_to_server;
int server_to_client;
char buf[BUFSIZ];
/* create the FIFO (named pipe) */
mkfifo(FIFO_FILE_1, 0666);
mkfifo(FIFO_FILE_2, 0666);
printf("Server ON.\n");
while (1)
{
/* open, read, and display the message from the FIFO */
client_to_server = open(FIFO_FILE_1, O_RDONLY);
server_to_client = open(FIFO_FILE_2, O_WRONLY);
read(client_to_server, buf, BUFSIZ);
if (strcmp("exit",buf)==0)
{
printf("Server OFF.\n");
break;
}
else if (strcmp("",buf)!=0)
{
printf("Received: %s\n", buf);
printf("Sending back...\n");
write(server_to_client,buf,BUFSIZ);
}
/* clean buf from any data */
memset(buf, 0, sizeof(buf));
close(client_to_server);
close(server_to_client);
}
close(client_to_server);
close(server_to_client);
unlink(FIFO_FILE_1);
unlink(FIFO_FILE_2);
return 0;
}
client.cpp:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <string.h>
#define FIFO_FILE_1 "/tmp/client_to_server_fifo"
#define FIFO_FILE_2 "/tmp/server_to_client_fifo"
int main()
{
system("clear");
int client_to_server;
int server_to_client;
char str[140];
printf("Input message to server: ");
scanf("%139[^\r\n]", str);
/* write str to the FIFO */
client_to_server = open(FIFO_FILE_1, O_WRONLY);
server_to_client = open(FIFO_FILE_2, O_RDONLY);
if(write(client_to_server, str, sizeof(str)) < 0){
perror("Write:");//print error
exit(-1);
}
if(read(server_to_client,str,sizeof(str)) < 0){
perror("Read:"); //error check
exit(-1);
}
printf("\n...received from the server: %s\n\n\n",str);
close(client_to_server);
close(server_to_client);
/* remove the FIFO */
return 0;
}
close(client_to_server);
close(server_to_client);
Remove these lines from while loop because when server has done its work for the first time it will close the pipe and you cant be able to proceed further in pipes.