EGong

git clone git://xatko.vsos.ethz.ch/EGong.git
Log | Files | Refs

Packet.c (5300B)


      1 #include <EGong/Util/Hash.h>
      2 #include <EGong/Packet.h>
      3 #include <EGong/Util/Socket.h>
      4 #include <EGong/Util/Log.h>
      5 #include <EGong/Util/Misc.h>
      6 
      7 #include <unistd.h>
      8 #include <stdlib.h>
      9 
     10 #include <string.h>
     11 #include <stddef.h>
     12 #ifdef _WIN32
     13 	#include <winsock2.h>
     14 #else
     15 	#include <arpa/inet.h>
     16 #endif
     17 
     18 unsigned char EGong_packet_last_hash[EGONG_PACKET_HASH_LENGTH];
     19 int EGong_calculate_package_hash(struct EGong_packet *packet, unsigned char *dest, String *cookie){
     20 	if(cookie==NULL)
     21 		cookie=(String *)&EGong_global_configuration.packet.cookie;
     22 	SHA256_CTX sha256;
     23 	SHA256_Init(&sha256);
     24 	
     25 	SHA256_Update(&sha256, packet->message.data, packet->message.length);
     26 	SHA256_Update(&sha256, packet->rand, EGONG_PACKET_RAND_LENGTH);
     27 	SHA256_Update(&sha256, cookie->data, cookie->length);
     28 	
     29 	SHA256_Final(dest, &sha256);
     30 	return 0;
     31 }
     32 
     33 int EGong_generate_packet(struct EGong_packet *packet, const String *msg){
     34 	EGong_misc_get_rand(packet->rand,EGONG_PACKET_RAND_LENGTH);
     35 	
     36 	packet->message.length=msg->length;
     37 	packet->message.data=(char *)msg->data;
     38 	
     39 	EGong_calculate_package_hash(packet,packet->hash, NULL);
     40 	
     41 	return 0;
     42 }
     43 void EGong_packetbuffer_advance(char **buf, const char *src, size_t length){
     44 	memcpy(*buf, src, length);
     45 	*buf+=length;
     46 }
     47 int EGong_send_packet(struct EGong_packet *packet, const char *dest){
     48 	if(packet->message.length==0){
     49 		do_log("Packetsize 0, not sending...", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
     50 		return -1;
     51 	}
     52 	SOCKET sock;
     53 	if(EGong_socket_open(&sock)<0){
     54 		do_log("Couldn't open socket",LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
     55 		return -1;
     56 	}
     57 	#ifdef _WIN32
     58 	char 
     59 	#else
     60 	int
     61 	#endif
     62 	broadcastEnable=1;
     63 	if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable))<0){
     64 		do_log("Couldn't set socket broadcasting",LOG_TYPE_SOCKET, LOG_LEVEL_WARNING);
     65 	}
     66 	
     67 	size_t bufsize=EGONG_PACKET_MSGLEN(packet->message.length);
     68 	char *buf=malloc(bufsize);
     69 	char *bufptr=buf;
     70 	if(buf==NULL){
     71 		do_log("Couldn't allocate buffer",LOG_TYPE_SIGNAL, LOG_LEVEL_ERROR);
     72 		return -2;
     73 	}
     74 	memset(bufptr, 0, bufsize);
     75 	memcpy(EGong_packet_last_hash, packet->hash, EGONG_PACKET_HASH_LENGTH);
     76 	
     77 	EGong_packetbuffer_advance(&bufptr, (const char *)packet->rand, EGONG_PACKET_RAND_LENGTH);
     78 	EGong_packetbuffer_advance(&bufptr, (const char *)packet->hash, EGONG_PACKET_HASH_LENGTH);
     79 	*(uint16_t *) bufptr=htons(packet->message.length);
     80 	bufptr+=EGONG_PACKET_LENGTH_LENGTH;
     81 	EGong_packetbuffer_advance(&bufptr, packet->message.data, packet->message.length);
     82 	
     83 	if(EGong_sendto(&sock, dest, buf, bufsize, NULL)<0){
     84 		do_log("Couldn't send packet body", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
     85 		return -3;
     86 	}
     87 	free(buf);
     88 	EGong_socket_close(&sock);
     89 	return 0;
     90 }
     91 
     92 void EGong_packet_free(struct EGong_packet *packet){
     93 	free(packet->message.data-(EGONG_PACKET_MSGHEADLEN));
     94 }
     95 int EGong_packetbuf_alloc(size_t size, char **dest, unsigned int additional){
     96 	if(size==0){
     97 		do_log("Tried to allocate message of size 0", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
     98 		return -1;
     99 	}
    100 	if(size>EGong_global_configuration.packet.packet_maxlen){
    101 		do_log("Messagesize larger than allowed!", LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
    102 		return -2;
    103 	}
    104 	*dest=malloc(EGONG_PACKET_MSGLEN(size)+additional);
    105 	if(*dest==NULL){
    106 		do_log("Couldn't allocate packet!", LOG_TYPE_SIGNAL, LOG_LEVEL_WARNING);
    107 		return -3;
    108 	}
    109 	return 0;
    110 }
    111 
    112 int EGong_packet_verify(struct EGong_packet *packet, String *cookie){
    113 	unsigned char hash[EGONG_PACKET_HASH_LENGTH];
    114 	EGong_calculate_package_hash(packet, hash, cookie);
    115 	return memcmp(packet->hash,hash,EGONG_PACKET_HASH_LENGTH)==0;
    116 }
    117 void EGong_packetbuffer_to_packet(const char *buf, struct EGong_packet *packet){
    118 	memcpy(packet->rand, buf, EGONG_PACKET_RAND_LENGTH);
    119 	buf+=EGONG_PACKET_RAND_LENGTH;
    120 	memcpy(packet->hash, buf, EGONG_PACKET_HASH_LENGTH);
    121 	buf+=EGONG_PACKET_HASH_LENGTH;
    122 	packet->message.length=ntohs(*(uint16_t *)buf);
    123 	buf+=EGONG_PACKET_LENGTH_LENGTH;
    124 	packet->message.data=(char *)buf;
    125 	packet->message.data[packet->message.length]='\0';
    126 }
    127 void EGong_drop_packet(SOCKET *sock){
    128 	do_log("Dropping packet.", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
    129 	EGong_listener_get(sock,NULL,0, NULL, MSG_DONTWAIT);
    130 }
    131 int EGong_get_packet(SOCKET *sock, struct EGong_packet *packet){
    132 	if(sock==NULL){
    133 		sock=&EGong_listen_sock;
    134 	}	struct sockaddr source;
    135 	char packetbuf[EGONG_PACKET_MSGHEADLEN];
    136 	int ret=EGong_listener_get(sock,(char *)packetbuf,EGONG_PACKET_MSGHEADLEN, &source, MSG_PEEK|MSG_DONTWAIT);
    137 	if(ret<0){
    138 		do_log("Couldn't receive packet!", LOG_TYPE_NORMAL, LOG_LEVEL_ERROR);
    139 		return -1;
    140 	}
    141 	else if(ret==0){
    142 		do_log("No packet available", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
    143 		return 1;
    144 	}
    145 	else if(0&&memcmp(EGong_packet_last_hash, packetbuf+EGONG_PACKET_RAND_LENGTH, EGONG_PACKET_HASH_LENGTH)==0){
    146 		do_log("Is own packet, dropping", LOG_TYPE_NORMAL, LOG_LEVEL_DEBUG);
    147 		EGong_drop_packet(sock);
    148 		return 2;
    149 	}
    150 	uint16_t rawsize=*(uint16_t*)(packetbuf+EGONG_PACKET_RAND_LENGTH+EGONG_PACKET_HASH_LENGTH);
    151 	size_t size=ntohs(rawsize);
    152 	char *dest;
    153 	if(EGong_packetbuf_alloc(size+EGONG_PACKET_MSGHEADLEN+1,&dest, 1)<0){
    154 		do_log("Couldn't allocate packetbuffer",LOG_TYPE_NORMAL, LOG_LEVEL_WARNING);
    155 		EGong_drop_packet(sock);
    156 		return -2;
    157 	}
    158 	ret=EGong_listener_get(sock, dest, EGONG_PACKET_MSGLEN(size), NULL, 0);
    159 	EGong_packetbuffer_to_packet(dest,packet);
    160 	return 0;
    161 }