This is client code by using libwebsocket version 1.5
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <syslog.h>
#include <sys/time.h>
#include <unistd.h>
#include <libwebsockets.h>
static volatile int force_exit = 0;
static int state, command_received = 0, forked = 0;
#define MAX_ECHO_PAYLOAD 1400
#define LOCAL_RESOURCE_PATH "./"
struct per_session_data {
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_ECHO_PAYLOAD + LWS_SEND_BUFFER_POST_PADDING];
unsigned int len;
};
//for temporary storing data from tcpdump
struct per_session_data data1;
static int callback_echo(struct libwebsocket_context *context, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len)
{
struct per_session_data *pss = (struct per_session_data *)user;
int n;
switch (reason) {
/* when the callback is used for client operations --> */
case LWS_CALLBACK_CLOSED:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
printf("Closed\n");
state = 0;
break;
case LWS_CALLBACK_ESTABLISHED:
case LWS_CALLBACK_CLIENT_ESTABLISHED:
printf("Client connected\n");
state = 2;
break;
/* we will receive our packet here*/
case LWS_CALLBACK_RECEIVE:
case LWS_CALLBACK_CLIENT_RECEIVE:
printf("Rx from server: %s\n", (char *)in);
if (!strcmp((char *)in, "tcpdump"))
{
command_received = 1;
}
break;
/* we will send our packet here */
case LWS_CALLBACK_CLIENT_WRITEABLE:
printf("client writing to server\n");
pss->len = sprintf((char *)&pss->buf[LWS_SEND_BUFFER_PRE_PADDING], "%s", data1.buf + LWS_SEND_BUFFER_PRE_PADDING);
n = libwebsocket_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT);
printf("Data: %s\n\n\n\n\n\n\n", &pss->buf[LWS_SEND_BUFFER_PRE_PADDING]);
//error handling for write fail and partial writes
if (n < 0) {
printf("ERROR %d writing to socket, hanging up\n", n);
return -1;
}
if (n < (int)pss->len) {
printf("Partial write\n");
return -1;
}
break;
default:
printf("default...\n");
break;
}
return 0;
}
/* List of available protocols */
static struct libwebsocket_protocols protocols[] = {
{
"default", /* name */
callback_echo, /* callback */
sizeof(struct per_session_data) /* per_session_data_size */
},
{
NULL, NULL, 0 /* End of list */
}
};
void sighandler(int sig)
{
force_exit = 1;
}
int main(int argc, char **argv)
{
//pipe stuff
int pipe_fd[2];
if (pipe(pipe_fd) < 0)
{
perror("PIPE:");
exit(-1);
}
//for libwebsocket_service
int n = 0;
//test port can be overidden
int port = 9000;
struct libwebsocket_context *context;
int opts = 0;
char interface_name[128] = "";
const char *interface = NULL;
int use_ssl = 0;
char ssl_cert[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
char ssl_key[256] = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
int listen_port = 80;
struct lws_context_creation_info info;
char passphrase[256];
char uri[256] = "/";
char address[256], ads_port[256 + 30];
//lws servicing time intervals
int rate_us = 250000;
unsigned int oldus = 0;
struct libwebsocket *wsi;
//should check this
int debug_level = 2;
memset(&info, 0, sizeof info);
lwsl_notice("Built to support client operations\n");
//re-configuring server ip and port here
if (argc == 3)
{
strncpy(address, argv[1], sizeof(address) - 1);
address[sizeof(address) - 1] = '\0';
port = atoi(argv[2]);
}
else if (argc == 1)
{
strncpy(address, "localhost", sizeof(address) - 1);
address[sizeof(address) - 1] = '\0';
port = 9000;
}
else
{
printf("Try: ./client.exec <ip> <port>\n");
exit(-1);
}
/* we will only try to log things according to our debug_level */
setlogmask(LOG_UPTO (LOG_DEBUG));
openlog("lwsts", 0, LOG_DAEMON);
/* tell the library what debug level to emit and to send it to syslog */
lws_set_log_level(debug_level, lwsl_emit_syslog);
lwsl_notice("libwebsockets echo test - "
"(C) Copyright 2010-2015 Andy Green <andy#warmcat.com> - "
"licensed under LGPL2.1\n");
lwsl_notice("Running in client mode\n");
listen_port = CONTEXT_PORT_NO_LISTEN;
lwsl_info("requiring server cert validation againts %s\n", ssl_cert);
info.ssl_ca_filepath = ssl_cert;
info.port = listen_port;
info.iface = interface;
info.protocols = protocols;
#ifndef LWS_NO_EXTENSIONS
info.extensions = libwebsocket_get_internal_extensions();
#endif
info.gid = -1;
info.uid = -1;
info.options = opts;
context = libwebsocket_create_context(&info);
if (context == NULL) {
lwsl_err("libwebsocket init failed\n");
return -1;
}
signal(SIGINT, sighandler);
n = 0;
while (n >= 0 && !force_exit)
{
//do connect only once
if (!state) {
state = 1;
printf("Client connecting to %s:%u....\n", address, port);
address[sizeof(address) - 1] = '\0';
sprintf(ads_port, "%s:%u", address, port & 65535);
wsi = libwebsocket_client_connect(context, address, port, use_ssl, uri, ads_port, ads_port, NULL, -1);
if (!wsi) {
printf("Client failed to connect to %s:%u\n", address, port);
goto bail;
}
}
if (command_received == 1 && !forked)
{
printf("Going to fork\n");
forked = 1;
pid_t child_pid = fork();
if (child_pid == -1)
{
perror("FORK:");
exit(-1);
}
else if (child_pid == 0)
{
close(pipe_fd[0]);
printf("Starting tcpdump\n");
if (dup2(pipe_fd[1], 1) < 0)
{
perror("DUP2:");
exit(-1);
}
//closing the connection to server for child
libwebsocket_context_destroy(context);
closelog();
char *cmd[] = {"tcpdump", "-i", "any", NULL};
if (execv("/usr/sbin/tcpdump", cmd) < 0)
{
perror("EXECV:");
exit(-1);
}
}
}
/* if (forked == 1)
{
close(pipe_fd[1]);
}
*/
if (command_received == 1)
{
//stay here if the pipe is empty else try to read max 1400 bytes of data
while ((data1.len = read(pipe_fd[0], data1.buf + LWS_SEND_BUFFER_PRE_PADDING, 1400)) <= 0);
//check if server wants any service
//printf("%s\n\n\n\n\n\n\n", data1.buf + LWS_SEND_BUFFER_PRE_PADDING);
libwebsocket_callback_on_writable(context, wsi);
}
//This fn times out every 10usec
n = libwebsocket_service(context, 10);
}
//bail: jump from while loop also if connect fails
bail:
libwebsocket_context_destroy(context);
printf("libwebsockets-test-echo exited cleanly\n");
closelog();
return 0;
}
This is my server code by using socket.io
var io = require('socket.io')();
var middleware = require('socketio-wildcard')();
io.use(middleware);
io.on('connection', function(socket) {
console.log('On socket connection')
socket.on('*', function(event, data){
console.log("---- Event ----- : " + JSON.stringify(event));
console.log("---- Data ----- : " + JSON.stringify(data))
});
});
io.listen(9000, 'localhost');
The client is unable to connect with server. when i tested client with strace it infinitely does receive as below
recv(8, "", 1, 0) = 0
recv(8, "", 1, 0) = 0
recv(8, "", 1, 0) = 0
.
.
.
.
Please point out my mistake. Any help is appreciated.
Thanks
Related
This is the example code given for Electric UI's ESP32 websockets intergration.
// This example was written with the ESP8266 and ESP32 as the target hardware.
// Connects to a wifi access point and runs a websockets server as a transport for eUI.
// The ws path is hinted to the UI over the serial connection which ruggedises connection discovery.
// Base wifi libraries from the ESP library pack
#include "WiFi.h"
#include "WiFiMulti.h"
#include "WiFiClientSecure.h"
// Websockets library https://github.com/Links2004/arduinoWebSockets
#include "WebSocketsServer.h"
#include "electricui.h"
#define LED_PIN LED_BUILTIN
// Define default network credentials
char * wifi_ssid = "ssid";
char * wifi_pass = "password";
uint8_t ws_connected = 0; //state indication
uint8_t ws_port = 80;
char ws_path[] = "ws(s)://255.255.255.255:81";
// Simple variables to modify the LED behaviour
uint8_t blink_enable = 1; //if the blinker should be running
uint8_t led_state = 0; //track if the LED is illuminated
uint16_t glow_time = 200; //in milliseconds
// Keep track of when the light turns on or off
uint32_t led_timer = 0;
//example variables
uint8_t example_uint8 = 21;
uint16_t example_uint16 = 321;
uint32_t example_uint32 = 654321;
float example_float = 3.141592;
char demo_string[] = "ESP32 Test Board";
eui_message_t dev_msg_store[] = {
EUI_UINT8( "wsc", ws_connected),
EUI_CHAR_ARRAY( "ws", ws_path ),
EUI_UINT8( "led_blink", blink_enable ),
EUI_UINT8( "led_state", led_state ),
EUI_UINT16( "lit_time", glow_time ),
EUI_UINT8( "ui8", example_uint8 ),
EUI_UINT16( "i16", example_uint16 ),
EUI_UINT32( "i32", example_uint32 ),
EUI_FLOAT( "fPI", example_float ),
EUI_CHAR_ARRAY_RO( "name", demo_string ),
};
WiFiMulti WiFiMulti;
WebSocketsServer webSocket = WebSocketsServer(ws_port);
void tx_putc(uint8_t *data, uint16_t len);
void ws_tx_putc(uint8_t *data, uint16_t len);
eui_interface_t comm_links[] = {
EUI_INTERFACE(&tx_putc),
EUI_INTERFACE(&ws_tx_putc),
};
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
uint8_t * iter = payload;
uint8_t * end = payload + length;
switch(type)
{
case WStype_DISCONNECTED:
ws_connected = 2;
break;
case WStype_CONNECTED:
ws_connected = 3;
break;
case WStype_TEXT:
// send data to all connected clients
// webSocket.broadcastTXT("message here");
break;
case WStype_BIN:
while( iter < end )
{
eui_parse(*iter++, &comm_links[1]);
}
break;
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
ws_connected = 4;
break;
}
}
void wifi_handle()
{
if( WiFiMulti.run() == WL_CONNECTED )
{
//we have a wifi connection
if(!ws_connected)
{
webSocket.begin();
webSocket.onEvent(webSocketEvent);
ws_connected = 1;
// The hint is formatted like ws://255.255.255.255:81
memset( ws_path, 0, sizeof(ws_path) ); //clear the string first
snprintf(ws_path, sizeof(ws_path), "ws://%s:%d", WiFi.localIP().toString().c_str(), ws_port);
glow_time = 200;
// Using Arduino Strings
// String ws_path_string = "ws://" + WiFi.localIP().toString().c_str() + ":" + String(ws_port);
// ws_path_string.toCharArray(ws_path, sizeof(ws_path));
}
else
{
webSocket.loop();
}
}
else
{
//no connection, try again later
ws_connected = 0;
}
}
void eui_callback( uint8_t message )
{
switch(message)
{
case EUI_CB_TRACKED:
// UI recieved a tracked message ID and has completed processing
break;
case EUI_CB_UNTRACKED:
{
// UI passed in an untracked message ID
// Grab parts of the inbound packet which are are useful
eui_header_t header = comm_links[0].packet.header;
uint8_t *name_rx = comm_links[0].packet.id_in;
void *payload = comm_links[0].packet.data_in;
// See if the inbound packet name matches our intended variable
if( strcmp( (char *)name_rx, "talk" ) == 0 )
{
webSocket.broadcastTXT("hello over websockets");
glow_time = 50;
}
}
break;
case EUI_CB_PARSE_FAIL:
break;
}
}
void setup()
{
Serial.begin(115200);
pinMode( LED_BUILTIN, OUTPUT );
//eUI setup
comm_links[0].interface_cb = &eui_callback;
eui_setup_interfaces(comm_links, 2);
EUI_TRACK(dev_msg_store);
eui_setup_identifier("esp32", 5);
WiFiMulti.addAP(wifi_ssid, wifi_pass);
led_timer = millis();
}
void loop()
{
wifi_handle();
while(Serial.available() > 0)
{
eui_parse(Serial.read(), &comm_links[0]);
}
if( blink_enable )
{
// Check if the LED has been on for the configured duration
if( millis() - led_timer >= glow_time )
{
led_state = !led_state; //invert led state
led_timer = millis();
}
}
digitalWrite( LED_PIN, led_state ); //update the LED to match the intended state
}
void tx_putc( uint8_t *data, uint16_t len )
{
Serial.write( data, len );
}
void ws_tx_putc( uint8_t *data, uint16_t len )
{
webSocket.broadcastBIN( data, len);
}
When I enter my SSID and Password the serial monitor just displays:
E (2462) wifi:Association refused temporarily, comeback time 200 mSec
However the LED is blinking as it should.... The Electric UI shows no devices found....
Hello every one i m trying to develop web filter and i found Win Divert Samples
here the code is i m trying to run in visual Studio 12 and got this error
IntelliSense: argument of type "PVOID" is incompatible with parameter of type "char *"
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "windivert.h"
#define MAXBUF 0xFFFF
#define MAXURL 4096
/*
* URL and blacklist representation.
*/
typedef struct
{
char *domain;
char *uri;
} URL, *PURL;
typedef struct
{
UINT size;
UINT length;
PURL *urls;
} BLACKLIST, *PBLACKLIST;
/*
* Pre-fabricated packets.
*/
typedef struct
{
WINDIVERT_IPHDR ip;
WINDIVERT_TCPHDR tcp;
} PACKET, *PPACKET;
typedef struct
{
PACKET header;
UINT8 data[];
} DATAPACKET, *PDATAPACKET;
/*
* THe block page contents.
*/
const char block_data[] =
"HTTP/1.1 200 OK\r\n"
"Connection: close\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<!doctype html>\n"
"<html>\n"
"\t<head>\n"
"\t\t<title>BLOCKED!</title>\n"
"\t</head>\n"
"\t<body>\n"
"\t\t<h1>BLOCKED!</h1>\n"
"\t\t<hr>\n"
"\t\t<p>This URL has been blocked!</p>\n"
"\t</body>\n"
"</html>\n";
/*
* Prototypes
*/
static void PacketInit(PPACKET packet);
static int __cdecl UrlCompare(const void *a, const void *b);
static int UrlMatch(PURL urla, PURL urlb);
static PBLACKLIST BlackListInit(void);
static void BlackListInsert(PBLACKLIST blacklist, PURL url);
static void BlackListSort(PBLACKLIST blacklist);
static BOOL BlackListMatch(PBLACKLIST blacklist, PURL url);
static void BlackListRead(PBLACKLIST blacklist, const char *filename);
static BOOL BlackListPayloadMatch(PBLACKLIST blacklist, char *data,
UINT16 len);
/*
* Entry.
*/
int __cdecl main(int argc, char **argv)
{
HANDLE handle;
WINDIVERT_ADDRESS addr;
UINT8 packet[MAXBUF];
UINT packet_len;
PWINDIVERT_IPHDR ip_header;
PWINDIVERT_TCPHDR tcp_header;
PVOID payload;
UINT payload_len;
PACKET reset0;
PPACKET reset = &reset0;
PACKET finish0;
PPACKET finish = &finish0;
PDATAPACKET blockpage;
UINT16 blockpage_len;
PBLACKLIST blacklist;
unsigned i;
INT16 priority = 404; // Arbitrary.
// Read the blacklists.
if (argc <= 1)
{
fprintf(stderr, "usage: %s blacklist.txt [blacklist2.txt ...]\n",
argv[0]);
exit(EXIT_FAILURE);
}
blacklist = BlackListInit();
for (i = 1; i < (UINT)argc; i++)
{
BlackListRead(blacklist, argv[i]);
}
BlackListSort(blacklist);
// Initialize the pre-frabricated packets:
blockpage_len = sizeof(DATAPACKET)+sizeof(block_data)-1;
blockpage = (PDATAPACKET)malloc(blockpage_len);
if (blockpage == NULL)
{
fprintf(stderr, "error: memory allocation failed\n");
exit(EXIT_FAILURE);
}
PacketInit(&blockpage->header);
blockpage->header.ip.Length = htons(blockpage_len);
blockpage->header.tcp.SrcPort = htons(80);
blockpage->header.tcp.Psh = 1;
blockpage->header.tcp.Ack = 1;
memcpy(blockpage->data, block_data, sizeof(block_data)-1);
PacketInit(reset);
reset->tcp.Rst = 1;
reset->tcp.Ack = 1;
PacketInit(finish);
finish->tcp.Fin = 1;
finish->tcp.Ack = 1;
// Open the Divert device:
handle = WinDivertOpen(
"outbound && " // Outbound traffic only
"ip && " // Only IPv4 supported
"tcp.DstPort == 80 && " // HTTP (port 80) only
"tcp.PayloadLength > 0", // TCP data packets only
WINDIVERT_LAYER_NETWORK, priority, 0
);
if (handle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}
printf("OPENED WinDivert\n");
// Main loop:
while (TRUE)
{
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
GetLastError());
continue;
}
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, &payload, &payload_len) ||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
{
// Packet does not match the blacklist; simply reinject it.
if (!WinDivertSend(handle, packet, packet_len, &addr, NULL))
{
fprintf(stderr, "warning: failed to reinject packet (%d)\n",
GetLastError());
}
continue;
}
// The URL matched the blacklist; we block it by hijacking the TCP
// connection.
// (1) Send a TCP RST to the server; immediately closing the
// connection at the server's end.
reset->ip.SrcAddr = ip_header->SrcAddr;
reset->ip.DstAddr = ip_header->DstAddr;
reset->tcp.SrcPort = tcp_header->SrcPort;
reset->tcp.DstPort = htons(80);
reset->tcp.SeqNum = tcp_header->SeqNum;
reset->tcp.AckNum = tcp_header->AckNum;
WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), 0);
if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL))
{
fprintf(stderr, "warning: failed to send reset packet (%d)\n",
GetLastError());
}
// (2) Send the blockpage to the browser:
blockpage->header.ip.SrcAddr = ip_header->DstAddr;
blockpage->header.ip.DstAddr = ip_header->SrcAddr;
blockpage->header.tcp.DstPort = tcp_header->SrcPort;
blockpage->header.tcp.SeqNum = tcp_header->AckNum;
blockpage->header.tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, 0);
addr.Direction = !addr.Direction; // Reverse direction.
if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr,
NULL))
{
fprintf(stderr, "warning: failed to send block page packet (%d)\n",
GetLastError());
}
// (3) Send a TCP FIN to the browser; closing the connection at the
// browser's end.
finish->ip.SrcAddr = ip_header->DstAddr;
finish->ip.DstAddr = ip_header->SrcAddr;
finish->tcp.SrcPort = htons(80);
finish->tcp.DstPort = tcp_header->SrcPort;
finish->tcp.SeqNum =
htonl(ntohl(tcp_header->AckNum) + sizeof(block_data) - 1);
finish->tcp.AckNum =
htonl(ntohl(tcp_header->SeqNum) + payload_len);
WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), 0);
if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL))
{
fprintf(stderr, "warning: failed to send finish packet (%d)\n",
GetLastError());
}
}
}
/*
* Initialize a PACKET.
*/
static void PacketInit(PPACKET packet)
{
memset(packet, 0, sizeof(PACKET));
packet->ip.Version = 4;
packet->ip.HdrLength = sizeof(WINDIVERT_IPHDR) / sizeof(UINT32);
packet->ip.Length = htons(sizeof(PACKET));
packet->ip.TTL = 64;
packet->ip.Protocol = IPPROTO_TCP;
packet->tcp.HdrLength = sizeof(WINDIVERT_TCPHDR) / sizeof(UINT32);
}
/*
* Initialize an empty blacklist.
*/
static PBLACKLIST BlackListInit(void)
{
PBLACKLIST blacklist = (PBLACKLIST)malloc(sizeof(BLACKLIST));
UINT size;
if (blacklist == NULL)
{
goto memory_error;
}
size = 1024;
blacklist->urls = (PURL *)malloc(size*sizeof(PURL));
if (blacklist->urls == NULL)
{
goto memory_error;
}
blacklist->size = size;
blacklist->length = 0;
return blacklist;
memory_error:
fprintf(stderr, "error: failed to allocate memory\n");
exit(EXIT_FAILURE);
}
/*
* Insert a URL into a blacklist.
*/
static void BlackListInsert(PBLACKLIST blacklist, PURL url)
{
if (blacklist->length >= blacklist->size)
{
blacklist->size = (blacklist->size*3) / 2;
printf("GROW blacklist to %u\n", blacklist->size);
blacklist->urls = (PURL *)realloc(blacklist->urls,
blacklist->size*sizeof(PURL));
if (blacklist->urls == NULL)
{
fprintf(stderr, "error: failed to reallocate memory\n");
exit(EXIT_FAILURE);
}
}
blacklist->urls[blacklist->length++] = url;
}
/*
* Sort the blacklist (for searching).
*/
static void BlackListSort(PBLACKLIST blacklist)
{
qsort(blacklist->urls, blacklist->length, sizeof(PURL), UrlCompare);
}
/*
* Match a URL against the blacklist.
*/
static BOOL BlackListMatch(PBLACKLIST blacklist, PURL url)
{
int lo = 0, hi = ((int)blacklist->length)-1;
while (lo <= hi)
{
INT mid = (lo + hi) / 2;
int cmp = UrlMatch(url, blacklist->urls[mid]);
if (cmp > 0)
{
hi = mid-1;
}
else if (cmp < 0)
{
lo = mid+1;
}
else
{
return TRUE;
}
}
return FALSE;
}
/*
* Read URLs from a file.
*/
static void BlackListRead(PBLACKLIST blacklist, const char *filename)
{
char domain[MAXURL+1];
char uri[MAXURL+1];
int c;
UINT16 i, j;
PURL url;
FILE *file = fopen(filename, "r");
if (file == NULL)
{
fprintf(stderr, "error: could not open blacklist file %s\n",
filename);
exit(EXIT_FAILURE);
}
// Read URLs from the file and add them to the blacklist:
while (TRUE)
{
while (isspace(c = getc(file)))
;
if (c == EOF)
{
break;
}
if (c != '-' && !isalnum(c))
{
while (!isspace(c = getc(file)) && c != EOF)
;
if (c == EOF)
{
break;
}
continue;
}
i = 0;
domain[i++] = (char)c;
while ((isalnum(c = getc(file)) || c == '-' || c == '.') && i < MAXURL)
{
domain[i++] = (char)c;
}
domain[i] = '\0';
j = 0;
if (c == '/')
{
while (!isspace(c = getc(file)) && c != EOF && j < MAXURL)
{
uri[j++] = (char)c;
}
uri[j] = '\0';
}
else if (isspace(c))
{
uri[j] = '\0';
}
else
{
while (!isspace(c = getc(file)) && c != EOF)
;
continue;
}
printf("ADD %s/%s\n", domain, uri);
url = (PURL)malloc(sizeof(URL));
if (url == NULL)
{
goto memory_error;
}
url->domain = (char *)malloc((i+1)*sizeof(char));
url->uri = (char *)malloc((j+1)*sizeof(char));
if (url->domain == NULL || url->uri == NULL)
{
goto memory_error;
}
strcpy(url->uri, uri);
for (j = 0; j < i; j++)
{
url->domain[j] = domain[i-j-1];
}
url->domain[j] = '\0';
BlackListInsert(blacklist, url);
}
fclose(file);
return;
memory_error:
fprintf(stderr, "error: memory allocation failed\n");
exit(EXIT_FAILURE);
}
/*
* Attempt to parse a URL and match it with the blacklist.
*
* BUG:
* - This function makes several assumptions about HTTP requests, such as:
* 1) The URL will be contained within one packet;
* 2) The HTTP request begins at a packet boundary;
* 3) The Host header immediately follows the GET/POST line.
* Some browsers, such as Internet Explorer, violate these assumptions
* and therefore matching will not work.
*/
static BOOL BlackListPayloadMatch(PBLACKLIST blacklist, char *data, UINT16 len)
{
static const char get_str[] = "GET /";
static const char post_str[] = "POST /";
static const char http_host_str[] = " HTTP/1.1\r\nHost: ";
char domain[MAXURL];
char uri[MAXURL];
URL url = {domain, uri};
UINT16 i = 0, j;
BOOL result;
HANDLE console;
if (len <= sizeof(post_str) + sizeof(http_host_str))
{
return FALSE;
}
if (strncmp(data, get_str, sizeof(get_str)-1) == 0)
{
i += sizeof(get_str)-1;
}
else if (strncmp(data, post_str, sizeof(post_str)-1) == 0)
{
i += sizeof(post_str)-1;
}
else
{
return FALSE;
}
for (j = 0; i < len && data[i] != ' '; j++, i++)
{
uri[j] = data[i];
}
uri[j] = '\0';
if (i + sizeof(http_host_str)-1 >= len)
{
return FALSE;
}
if (strncmp(data+i, http_host_str, sizeof(http_host_str)-1) != 0)
{
return FALSE;
}
i += sizeof(http_host_str)-1;
for (j = 0; i < len && data[i] != '\r'; j++, i++)
{
domain[j] = data[i];
}
if (i >= len)
{
return FALSE;
}
if (j == 0)
{
return FALSE;
}
if (domain[j-1] == '.')
{
// Nice try...
j--;
if (j == 0)
{
return FALSE;
}
}
domain[j] = '\0';
printf("URL %s/%s: ", domain, uri);
// Reverse the domain:
for (i = 0; i < j / 2; i++)
{
char t = domain[i];
domain[i] = domain[j-i-1];
domain[j-i-1] = t;
}
// Search the blacklist:
result = BlackListMatch(blacklist, &url);
// Print the verdict:
console = GetStdHandle(STD_OUTPUT_HANDLE);
if (result)
{
SetConsoleTextAttribute(console, FOREGROUND_RED);
puts("BLOCKED!");
}
else
{
SetConsoleTextAttribute(console, FOREGROUND_GREEN);
puts("allowed");
}
SetConsoleTextAttribute(console,
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
return result;
}
/*
* URL comparison.
*/
static int __cdecl UrlCompare(const void *a, const void *b)
{
PURL urla = *(PURL *)a;
PURL urlb = *(PURL *)b;
int cmp = strcmp(urla->domain, urlb->domain);
if (cmp != 0)
{
return cmp;
}
return strcmp(urla->uri, urlb->uri);
}
/*
* URL matching
*/
static int UrlMatch(PURL urla, PURL urlb)
{
UINT16 i;
for (i = 0; urla->domain[i] && urlb->domain[i]; i++)
{
int cmp = (int)urlb->domain[i] - (int)urla->domain[i];
if (cmp != 0)
{
return cmp;
}
}
if (urla->domain[i] == '\0' && urlb->domain[i] != '\0')
{
return 1;
}
for (i = 0; urla->uri[i] && urlb->uri[i]; i++)
{
int cmp = (int)urlb->uri[i] - (int)urla->uri[i];
if (cmp != 0)
{
return cmp;
}
}
if (urla->uri[i] == '\0' && urlb->uri[i] != '\0')
{
return 1;
}
return 0;
}
This file compiles without errors as C code, so be sure that you compile it as C. If you need to compile it as C++, then add explicit cast to char* at payload parameter in this line:
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, &payload, &payload_len) ||
!BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len))
Like this:
if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
NULL, NULL, &tcp_header, NULL, &payload, &payload_len) ||
!BlackListPayloadMatch(blacklist, (char*)payload, (UINT16)payload_len))
I have a broadcast program on my mac, everything is working fine, but if i have more then one network interface, he didn't recieve anything.
So what i now want to do is:
Check which network interfaces are activ on the mac
send to every activ interface a broadcast ( so i have to select which interface i want to use)
recieve the answer (if there is one :) )
Interesting:
the broadcast client is on my WLAN (with a router beetween the devices) and a normal internet connection is on my LAN. If i deactivate the LAN in the system configs, he also didn't find my other device, but if i pull the cable he found the other device... So maybe i didn't have to look which interface is activ and have a look to which interface is connected.
Do u have some tipps or good google keywords for me to do that?
Long time ago, but if someone find my post, here is my solution:
#include <stdint.h>
static uint32 Inet_AtoN(const char * buf)
{
// net_server inexplicably doesn't have this function; so I'll just fake it
uint32 ret = 0;
int shift = 24; // fill out the MSB first
bool startQuad = true;
while ((shift >= 0) && (*buf))
{
if (startQuad)
{
unsigned char quad = (unsigned char)atoi(buf);
ret |= (((uint32)quad) << shift);
shift -= 8;
}
startQuad = (*buf == '.');
buf++;
}
return ret;
}
int Broadcast::BroadcastToAllInterfaces()
{
DEBUG_LOG(1,"Start Broadcast To All Interfaces", "DEv1");
globalDatabase->SetInBroadcast();
moreThenOne = 0;
#if defined(USE_GETIFADDRS)
struct ifaddrs * ifap;
if (getifaddrs(&ifap) == 0)
{
struct ifaddrs * p = ifap;
while (p)
{
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
if (ifaAddr > 0)
{
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
addr << dstAddrStr;
descss << p->ifa_name;
descss >> descs;
addr >> addrs;
DoABroadcast(dstAddr);
}
p = p->ifa_next;
}
freeifaddrs(ifap);
}
#elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
{
free(ipTable); // in case we had previously allocated it STILL_RUN
ipTable = (MIB_IPADDRTABLE *)malloc(bufLen);
}
else if (ipRet == NO_ERROR) break;
else
{
free(ipTable);
ipTable = NULL;
break;
}
}
}
if (ipTable)
{
IP_ADAPTER_INFO * pAdapterInfo = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
if (apRet == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo); // in case we had previously allocated it
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(bufLen);
}
else if (apRet == ERROR_SUCCESS) break;
else
{
free(pAdapterInfo);
pAdapterInfo = NULL;
break;
}
}
}
for (DWORD i = 0; i<ipTable->dwNumEntries; i++)
{
const MIB_IPADDRROW & row = ipTable->table[i];
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL;
const char * desc = NULL;
if (pAdapterInfo)
{
IP_ADAPTER_INFO * next = pAdapterInfo;
while ((next) && (name == NULL))
{
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
while (ipAddr)
{
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
{
name = next->AdapterName;
desc = next->Description;
break;
}
ipAddr = ipAddr->Next;
}
next = next->Next;
}
}
char buf[128];
int setUnnamed = 0;
if (name == NULL)
{
sprintf(buf, "unnamed");
name = buf;
setUnnamed = 1;
}
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
if (setUnnamed == 0)
{
addr << dstAddrStr;
descss << desc;
descss >> descs;
addr >> addrs;
DoABroadcast(baddr);
}
}
free(pAdapterInfo);
free(ipTable);
}
#else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
#endif
globalDatabase->SetLeaveBroadcast();
return 1;
}
int Broadcast::DoABroadcast(uint32 broadAddr)
{
int askSinlen = sizeof(struct sockaddr_in);
int askBuflen = MAXBUF;
int message;
char buf[512];
int status;
char askBuffer[MAXBUF];
struct sockaddr_in sock_in, client_adress, client_adress2;
#ifdef __APPLE__
socklen_t clientLength;
int askYes = 1;
#else
char askYes = 1;
int clientLength;
WSADATA w;
int result = WSAStartup(MAKEWORD(2, 2), &w);
#endif
int recSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (recSocket <0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
sock_in.sin_port = htons(4028);
sock_in.sin_family = PF_INET;
client_adress.sin_family = PF_INET;
client_adress.sin_port = htons(4029);
client_adress.sin_addr.s_addr = htonl(broadAddr);
askSinlen = sizeof(sock_in);
client_adress2.sin_family = AF_INET;
client_adress2.sin_port = htons(4028);
client_adress2.sin_addr.s_addr = htonl(0xc0a8b2ff);
status = setsockopt(recSocket, SOL_SOCKET, SO_BROADCAST, &askYes, sizeof(askYes));
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
status = bind(recSocket, (struct sockaddr *)&sock_in, askSinlen);
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
askBuflen = sprintf(askBuffer, "Ciao Mac ist hier");
status = sendto(recSocket, askBuffer, askBuflen, 0, (struct sockaddr *)&client_adress, sizeof(client_adress));
fd_set fds;
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(recSocket, &fds);
int ret;
if ((ret = select(recSocket +1, &fds, NULL, NULL, &tv)) > 0)
{
int e = 0;
while ((ret = select(recSocket + 1, &fds, NULL, NULL, &tv)) > 0)
{
clientLength = sizeof(client_adress2);
message = recvfrom(recSocket, buf, sizeof(buf), 0, (struct sockaddr*) &client_adress2, &clientLength);
if (message == -1)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -5;
}
else
{
std::string hereisyourbroadcast(buf);
}
}
}
else
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -6;
}
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 1;
}
I have a problem with an ATmega8 and Mifare RC-522 based NFC/RFID controller.
I'm using this library and I've managed to read the UID of a card.
However, I'd like to also read and write other parts of the card but whenever I try to use the MFRC522_Auth function I don't get the idle interrupt which I should, instead it gives me LoAlertIrq saying that FIFObuffer is almost empty.
Here are the docs for the reader and the card, and below are relevant parts of my code.
main.c :
byte = mfrc522_request(PICC_REQALL,str);
if(byte == CARD_FOUND)
{
byte = mfrc522_get_card_serial(str);
if(byte == CARD_FOUND)
{
byte = mfrc522_auth(PICC_AUTHENT1A, 7, sectorKeyA, str);
if( (byte == CARD_FOUND) )
{
byte = MFRC522_Read1(4, str);
if(byte == CARD_FOUND)
{
//write content of that block
}
}
}
Relevant functions from the library :
void mfrc522_write(uint8_t reg, uint8_t data)
{
ENABLE_CHIP();
spi_transmit((reg<<1)&0x7E);
spi_transmit(data);
DISABLE_CHIP();
}
uint8_t mfrc522_read(uint8_t reg)
{
uint8_t data;
ENABLE_CHIP();
spi_transmit(((reg<<1)&0x7E)|0x80);
data = spi_transmit(0x00);
DISABLE_CHIP();
return data;
}
uint8_t mfrc522_to_card(uint8_t cmd, uint8_t *send_data, uint8_t send_data_len, uint8_t *back_data, uint32_t *back_data_len)
{
uint8_t status = 0;
uint8_t irqEn = 0x00;
uint8_t waitIRq = 0x00;
uint8_t lastBits;
uint8_t n;
uint8_t tmp;
uint32_t i;
switch (cmd)
{
case MFAuthent_CMD: //Certification cards close
{
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case Transceive_CMD: //Transmit FIFO data
{
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
}
mfrc522_write(ComIEnReg, irqEn|0x80); //Interrupt request
n=mfrc522_read(ComIrqReg);
mfrc522_write(ComIrqReg,n&(~0x80));//clear all interrupt bits
n=mfrc522_read(FIFOLevelReg);
mfrc522_write(FIFOLevelReg,n|0x80);//flush FIFO data
// mfrc522_write(CommandReg, Idle_CMD); //NO action; Cancel the current cmd???
n=mfrc522_read(CommandReg);
mfrc522_write(CommandReg,n|0x00);
//Writing data to the FIFO
for (i=0; i<send_data_len; i++)
{
mfrc522_write(FIFODataReg, send_data[i]);
}
//Execute the cmd
mfrc522_write(CommandReg, cmd);
if (cmd == Transceive_CMD)
{
n=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,n|0x80);
}
//Waiting to receive data to complete
i = 2000; //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
while (1) {
n = mfrc522_read(ComIrqReg); // ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq HiAlertIRq LoAlertIRq ErrIRq TimerIRq
if (n & waitIRq) { // One of the interrupts that signal success has been set.
break;
}
if (n & 0x01) { // Timer interrupt - nothing received in 25ms
// return 6; //debug purpose
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
if (--i == 0) { // The emergency break. If all other condions fail we will eventually terminate on this one after 35.7ms. Communication with the MFRC522 might be down.
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
}
tmp=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,tmp&(~0x80));
if (i != 0)
{
if(!(mfrc522_read(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
{
status = CARD_FOUND;
if (n & irqEn & 0x01)
{
status = CARD_NOT_FOUND; //??
}
if (cmd == Transceive_CMD)
{
n = mfrc522_read(FIFOLevelReg);
lastBits = mfrc522_read(ControlReg) & 0x07;
if (lastBits)
{
*back_data_len = (n-1)*8 + lastBits;
}
else
{
*back_data_len = n*8;
}
if (n == 0)
{
n = 1;
}
if (n > MAX_LEN)
{
n = MAX_LEN;
}
//Reading the received data in FIFO
for (i=0; i<n; i++)
{
back_data[i] = mfrc522_read(FIFODataReg);
}
}
}
if (cmd == MFAuthent_CMD) {
LCD_WriteTextXY(1, 10, LCD_itoa16( mfrc522_read(Status2Reg) ) );
_delay_ms(2500);
}
} else status = 9;
return status;
}
uint8_t mfrc522_get_card_serial(uint8_t * serial_out)
{
uint8_t status;
uint8_t i;
uint8_t serNumCheck=0;
uint32_t unLen;
mfrc522_write(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
serial_out[0] = PICC_ANTICOLL;
serial_out[1] = 0x20;
status = mfrc522_to_card(Transceive_CMD, serial_out, 2, serial_out, &unLen);
if (status == CARD_FOUND)
{
//Check card serial number
for (i=0; i<4; i++)
{
serNumCheck ^= serial_out[i];
}
if (serNumCheck != serial_out[i])
{
status = ERROR;
}
}
return status;
}
uint8_t mfrc522_auth(uint8_t authMode, uint8_t BlockAddr, uint8_t *Sectorkey, uint8_t *serNum)
{
uint8_t status;
uint32_t recvBits;
uint8_t i;
uint8_t buff[12];
// Validate instruction block address + sector + password + card serial number
buff[0] = authMode;
buff[1] = BlockAddr;
for (i=0; i<6; i++)
{
buff[i+2] = 0xFF /**(Sectorkey+i)*/;
}
for (i=0; i<4; i++)
{
buff[i+8] = *(serNum+i);
}
status = mfrc522_to_card(MFAuthent_CMD, buff, 12, buff, &recvBits);
return status;
}
uint8_t MFRC522_Read1(uint8_t blockAddr, uint8_t *recvData)
{
uint8_t status = 0;
uint8_t unLen, efa;
recvData[0] = PICC_READ;
recvData[1] = blockAddr;
CalculateCRC(recvData, 2, &recvData);
status = mfrc522_to_card(Transceive_CMD, recvData, 4, recvData, &unLen);
if ((status != CARD_FOUND)|| (unLen != 0x90))
{
status = ERROR;
}
return status;
}
uint8_t CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
{
uint8_t i, n;
uint8_t status = 0;
n = mfrc522_read(DivIrqReg);
mfrc522_write(DivIrqReg,n&(~0x04)); //CRCIrq = 0
n = mfrc522_read(FIFOLevelReg); //FIFO
mfrc522_write(FIFOLevelReg, n|0x80);
//Write_MFRC522(CommandReg, PCD_IDLE);
// Write data to the FIFO
for (i=0; i<len; i++)
{
mfrc522_write(FIFODataReg, *(pIndata+i));
}
mfrc522_write(CommandReg, CalcCRC_CMD);
// Read the CRC calculation result
i = 0xFF;
while(1){
n = mfrc522_read(DivIrqReg);
if (n & 0x04) {
break;
}
if (--i != 0) {
return 7;
}
}
// Read the CRC calculation result
pOutData[3] = mfrc522_read(CRCResultReg_2);
pOutData[4] = mfrc522_read(CRCResultReg_1);
return status = 0;
}
Hey there wonderful community!
I'm back with a question regarding a console server application I've made with winsock. It's finally reaching a stage where I would need a to add a GUI, and to do so, I need it to be using the Windows subsystem.
And so I started the migration.
Yet I'm hitting a stack overflow somewhere in my application, and for the life of me I can't figure out where. Perhaps it has to do with WIN being a non-blocking subsystem (hope I used my vocab correctly).
Anyway, I hope to enlist you all as helpers. Many thanks :)
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <conio.h>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
int minitialize();
int msend(char msendbuf[512]);
char* mrecv(bool show);
int mshutdown();
void GoToXY(int column, int line);
int scroll(void);
int printm(char *inp);
int printm(char *inp, DWORD color);
int mexit();
char *vir = "true";
int clientnumber=0;
int currentclient=0;
int lastclient=0;
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "10150"
struct _client
{
bool con;
sockaddr_in addr; //Client info like ip address
SOCKET cs; //Client socket
fd_set set; //used to check if there is data in the socket
std::string ip;
std::string name;
int i; //any piece of additional info
} client[100];
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
DWORD WINAPI recvfunc(LPVOID randparam)
{
while (true) {
ClientSocket=client[currentclient].cs;
if (mrecv(true)=="1") {
client[currentclient].con=false;
ClientSocket=client[lastclient].cs;
break;
}
}
return 0;
}
DWORD WINAPI headerfunc(LPVOID randparam)
{
Sleep(500);
while (true) {
CONSOLE_SCREEN_BUFFER_INFO SBInfo;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hOut, &SBInfo);
int xx = SBInfo.dwCursorPosition.X;
int yy = SBInfo.dwCursorPosition.Y;
GoToXY(0,0);
HANDLE hHeaderColor;
hHeaderColor = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hHeaderColor, FOREGROUND_GREEN);
std::cout<<"Server Started. Current Client:"<<currentclient<<" Clients connected: "<<clientnumber<<" ("<<xx<<","<<yy<<") "<<lastclient;
SetConsoleTextAttribute(hHeaderColor, 0 |
FOREGROUND_RED |
FOREGROUND_GREEN |
FOREGROUND_BLUE);
GoToXY(xx,yy);
Sleep(2000);
}
return 0;
}
DWORD WINAPI sendfunc(LPVOID randparam)
{
while (true) {
char mmessage[512];
std::cin.getline(mmessage, 512);
if (strlen(mmessage)<2) {
GoToXY(0,23);
sendfunc("1");
}
char msendbuf[512]="Server> ";
strcat(msendbuf,mmessage);
if (msend(msendbuf)==1) {
"Client must have disconnected. Please select a new client.";
sendfunc("1");
}
if ((strncmp(msendbuf,"Server> /",9)) != 0) {
printm(msendbuf,FOREGROUND_INTENSITY);
}
GoToXY(0,23);
for (int sp=0; sp<72; sp++) {
std::cout<<" ";
}
GoToXY(0,23);
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
minitialize();
HANDLE hRecvThread;
HANDLE hSendThread;
HANDLE hHeaderThread;
DWORD dwRecvThreadId;
DWORD dwSendThreadId;
DWORD dwHeaderThreadId;
hHeaderThread = CreateThread(NULL,0,headerfunc,"1",0,&dwHeaderThreadId);
for (int mf=2; mf<25; mf++) {
std::cout<<"\n";
}
hSendThread = CreateThread(NULL,0,sendfunc,"1",0,&dwSendThreadId);
// Accept a client socket
for (int sock=1; sock<100; sock++) {
ClientSocket = accept(ListenSocket, NULL, NULL);
char sockprint[80];
char sockchar[4];
itoa(sock,sockchar,10);
strcpy(sockprint,"Client ");
strcat(sockprint,sockchar);
strcat(sockprint," connected.");
printm(sockprint);
GoToXY(0,23);
if (ClientSocket == INVALID_SOCKET) {
printm("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
client[sock].cs=ClientSocket;
client[sock].con=true;
lastclient=clientnumber;
clientnumber++;
currentclient=clientnumber;
hRecvThread = CreateThread(NULL,0,recvfunc,"1",0,&dwRecvThreadId);
}
// shutdown the connection since we're done
mshutdown();
std::cin.ignore();
return 0;
}
int printm(char *inp, DWORD color) {
HANDLE hOut;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hOut,
color);
printm(inp);
SetConsoleTextAttribute(hOut, 0 |
FOREGROUND_RED |
FOREGROUND_GREEN |
FOREGROUND_BLUE);
return 0;
}
int printm(char *inp) {
CONSOLE_SCREEN_BUFFER_INFO SBInfo;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hOut, &SBInfo);
int xx = SBInfo.dwCursorPosition.X;
int yy = SBInfo.dwCursorPosition.Y;
GoToXY(0,22);
std::cout<<inp<<"\n";
scroll();
GoToXY(xx,yy);
return 1;
}
int msend(char msendbuf[512]) // Send a message
{
if (strncmp(msendbuf,"Server> /exit",(strlen(msendbuf))) == 0) {
mexit();
}
if (strncmp(msendbuf,"Server> /set_client",19) == 0) {
int nm=atoi(&msendbuf[20]);
currentclient=nm;
ClientSocket=client[nm].cs;
char sockchar[4];
itoa(ClientSocket,sockchar,10);
char sockprint[80];
strcpy(sockprint,"New Socket: ");
strcat(sockprint,sockchar);
printm(sockprint);
char clientprint[80];
strcpy(clientprint,"Client: ");
strcat(clientprint,&msendbuf[20]);
printm(clientprint);
}
if (strncmp(msendbuf,"Server> /list_clients",(strlen(msendbuf))) == 0) {
printm("Clients:",FOREGROUND_RED);
for (int cm=1; cm < 100; cm++) {
int cn=client[cm].cs;
if (cn>0) {
char cli[80];
char cmchar[4];
char cnchar[80];
itoa(cn,cnchar,10);
itoa(cm,cmchar,10);
strcpy(cli,cmchar);
strcat(cli," ");
strcat(cli,cnchar);
strcat(cli," ");
strcat(cli,client[cm].ip.c_str());
strcat(cli," ");
strcat(cli,client[cm].name.c_str());
printm(cli,FOREGROUND_RED);
}
else {
break;
}
}
}
if (strncmp(msendbuf,"Server> /test",(strlen(msendbuf))) == 0) {
char ipcon[500];
*ipcon=(system("ipconfig"));
}
if (strncmp(msendbuf,"Server> /help",(strlen(msendbuf))) == 0) {
printm("Type /help for help or:");
printm("/set_client [client number]");
printm("/list_clients");
}
int iResult3 = send( ClientSocket, msendbuf, 512, 0 );
if (iResult3 == SOCKET_ERROR) {
printm("send failed with error: %d\n", WSAGetLastError());
return 1;
}
}
char* mrecv(bool show) //Recieve a message
{
int iResult2 = recv(ClientSocket, recvbuf, 512, 0);
if (iResult2 > 0) {
if ((strncmp(recvbuf,"/",1)) != 0) {
printm(recvbuf);
}
if (strncmp(recvbuf,"/ip",3) == 0) {
client[clientnumber].ip=&recvbuf[4];
char prin[80];
strcpy(prin,"client[clientnumber].ip: ");
strcat(prin,client[clientnumber].ip.c_str());
printm(prin,FOREGROUND_BLUE);
}
if (strncmp(recvbuf,"/name",5) == 0) {
client[clientnumber].name=&recvbuf[6];
char prin2[80];
strcpy(prin2,"client[clientnumber].name: ");
strcat(prin2,client[clientnumber].name.c_str());
printm(prin2,FOREGROUND_GREEN | FOREGROUND_BLUE);
}
if (strncmp(recvbuf,"/alert",5) == 0) {
char *message=&recvbuf[7];
char prin2[80];
strcpy(prin2,client[clientnumber].name.c_str());
strcat(prin2,": ");
strcat(prin2, message);
printm(prin2,FOREGROUND_RED);
}
if (strncmp(recvbuf,"Client> /alert",14) == 0) {
char *message=&recvbuf[15];
char prin2[80];
strcpy(prin2,client[clientnumber].name.c_str());
strcat(prin2,": ");
strcat(prin2, message);
printm(prin2,FOREGROUND_RED);
}
}
else if (iResult2 == 0) {
printf("Connection closing...\n");
closesocket(ClientSocket);
WSACleanup();
return "1";
}
else {
printm("recv failed with error: %d\n", WSAGetLastError());
printm("Client must have disconnected. Please select a new client.");
return "1";
}
return recvbuf;
}
int minitialize() //initialize the winsock server
{
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printm("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printm("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printm("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printm("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printm("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
unsigned long b=1;
ioctlsocket(ClientSocket,FIONBIO,&b);
}
int mshutdown() //shutdown the server
{
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printm("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
void GoToXY(int column, int line)
{
// Create a COORD structure and fill in its members.
// This specifies the new position of the cursor that we will set.
COORD coord;
coord.X = column;
coord.Y = line;
// Obtain a handle to the console screen buffer.
// (You're just using the standard console, so you can use STD_OUTPUT_HANDLE
// in conjunction with the GetStdHandle() to retrieve the handle.)
// Note that because it is a standard handle, we don't need to close it.
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// Finally, call the SetConsoleCursorPosition function.
if (!SetConsoleCursorPosition(hConsole, coord))
{
// Uh-oh! The function call failed, so you need to handle the error.
// You can call GetLastError() to get a more specific error code.
// ...
return;
}
}
int scroll( void )
{
HANDLE hStdout;
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
SMALL_RECT srctScrollRect, srctClipRect;
CHAR_INFO chiFill;
COORD coordDest;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdout == INVALID_HANDLE_VALUE)
{
printf("GetStdHandle failed with %d\n", GetLastError());
return 1;
}
// Get the screen buffer size.
if (!GetConsoleScreenBufferInfo(hStdout, &csbiInfo))
{
printf("GetConsoleScreenBufferInfo failed %d\n", GetLastError());
return 1;
}
// The scrolling rectangle
srctScrollRect.Top = 1;
srctScrollRect.Bottom = 22;
srctScrollRect.Left = 0;
srctScrollRect.Right = csbiInfo.dwSize.X - 1;
// The destination for the scroll rectangle is one row up.
coordDest.X = 0;
coordDest.Y = 0;
// The clipping rectangle
srctClipRect.Top = 2;
srctClipRect.Bottom = 22;
srctClipRect.Left = 0;
srctClipRect.Right = csbiInfo.dwSize.X - 1;
// Fill the bottom row with blanks.
chiFill.Attributes = FOREGROUND_RED;
chiFill.Char.AsciiChar = (char)' ';
// Scroll up one line.
if(!ScrollConsoleScreenBuffer(
hStdout, // screen buffer handle
&srctScrollRect, // scrolling rectangle
&srctClipRect, // clipping rectangle
coordDest, // top left destination cell
&chiFill)) // fill character and color
{
printf("ScrollConsoleScreenBuffer failed %d\n", GetLastError());
return 1;
}
return 0;
}
int mexit()
{
msend("/server_closed");
mshutdown();
exit(0);
}
Turns out it was the recursive calling in my "sendfunc" thread that tripped me up.
Specifically,
if (msend(msendbuf)==1) {
"Client must have disconnected. Please select a new client.";
sendfunc("1");
}
Because I continued to call "sendfunc" from itself, it caused the stack overflow.
So, for anyone else having these problems, watch for overkill recursive function calls.
I simply removed my sending function and I was good to go.