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 }