./ MultiCS.r82 / msg-newcamd.c
#include "common.h" #include <stdio.h> #include <string.h> #include <stdarg.h> #include <unistd.h> #ifdef WIN32 #include <windows.h> #include <sys/types.h> #include <sys/_default_fcntl.h> #include <sys/poll.h> #include <cygwin/types.h> #include <cygwin/socket.h> #include <sys/errno.h> #include <cygwin/in.h> #include <sched.h> #include <netdb.h> #include <netinet/tcp.h> #else #include <sys/types.h> #include <sys/socket.h> #include <signal.h> #include <netdb.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <pthread.h> #include <poll.h> #endif #include "des.h" #include "debug.h" #include "sockets.h" #include "msg-newcamd.h" int cs_message_send(int sock,struct cs_custom_data *cd, unsigned char *buffer, int len, unsigned char *deskey) { unsigned char netbuf[CWS_NETMSGSIZE]; if (sock==INVALID_SOCKET) return 0; if (!len) len = 0x0fff & ( (buffer[1]<<8)|buffer[2] ); else { buffer[1] = (buffer[1] & 0xf0) | (((len - 3) >> 8) & 0x0f); buffer[2] = (len - 3) & 0xff; } if (len < 3 || len + 12 > CWS_NETMSGSIZE) return -1; //NetBuf Header memset(netbuf, 0, 12); if (cd) { netbuf[2] = (cd->msgid >> 8) & 0xff; netbuf[3] = cd->msgid & 0xff; netbuf[4] = (cd->sid >> 8) & 0xff; netbuf[5] = cd->sid & 0xff; netbuf[6] = (cd->caid >> 8) & 0xff; netbuf[7] = cd->caid & 0xff; netbuf[8] = (cd->provid >> 16) & 0xff; netbuf[9] = (cd->provid >> 8) & 0xff; netbuf[10] = cd->provid & 0xff; netbuf[11] = (cd->provid >> 24) & 0xff; // used for mgcamd } memcpy(netbuf+12, buffer, len); // adding packet header size len += 12; //debugdump(netbuf,len,"SEND BUF "); #ifdef DEBUG_NETWORK if (flag_debugnet) { debugf(0," newcamd: send data %d\n",len); debughex(netbuf,len); } #endif len=des_encrypt(netbuf, len, deskey); if (len < 0) return -1; netbuf[0] = (len - 2) >> 8; netbuf[1] = (len - 2) & 0xff; return send_nonb(sock, netbuf, len,100); } // -2: timeout // -1: Error // =0: disconnect // >0: ok int cs_message_receive(int sock,struct cs_custom_data *cd, unsigned char *buffer, unsigned char *deskey, int timeout) { int len; unsigned char netbuf[CWS_NETMSGSIZE]; int returnLen; if (sock<=0) { //printf("newcamd: Invalid Socket\n"); return -1; } len = recv_nonb(sock, netbuf, 2, timeout); if (len<=0) { //printf("newcamd: first recive error (%d)\n",errno); return len; // disconnected } if (len != 2) { //printf("newcamd: header length error (%d)\n",len); return -1; } if (((netbuf[0] << 8) | netbuf[1]) > CWS_NETMSGSIZE - 2) { //printf("newcamd: big message size (%d)\n", (netbuf[0] << 8) | netbuf[1] ); return -1; } int netlen = (netbuf[0] << 8) | netbuf[1]; // TEST LENGTH if (netlen>(CWS_NETMSGSIZE-2)) return -1; len = recv_nonb(sock, netbuf+2, netlen, timeout); if (len<=0) { //printf("newcamd: recive error\n"); return len; // disconnected } if (len!=netlen) { //printf("newcamd: data length error\n"); return -1; } len += 2; len= des_decrypt(netbuf, len, deskey); if (len < 15) { //printf("newcamd: Error des_decrypt length %d\n",len); //debug_dump(netbuf, len, "netbuf:"); return -2; } if ( (returnLen = (((netbuf[13] & 0x0f) << 8) | netbuf[14]) + 3) > len-12) { //printf("newcamd: wrong data length\n"); return -1; } //debugdump(netbuf,returnLen+12,"RECV BUF "); #ifdef DEBUG_NETWORK if (flag_debugnet) { debugf(0," newcamd: receive data %d\n",returnLen+12); debughex(netbuf,returnLen+12); } #endif // Setup Custom Data if (cd) { cd->msgid = (netbuf[2] << 8) | netbuf[3]; cd->sid = (netbuf[4] << 8) | netbuf[5]; cd->caid = (netbuf[6] << 8) | netbuf[7]; cd->provid = (netbuf[8] << 16) | (netbuf[9] << 8) | netbuf[10]; } memcpy(buffer, netbuf+12, returnLen); return returnLen; } // -1: not yet // 0: disconnect // >0: ok int cs_msg_chkrecv(int sock) { int len; unsigned char netbuf[CWS_NETMSGSIZE]; len = recv(sock, netbuf, 2, MSG_PEEK|MSG_NOSIGNAL|MSG_DONTWAIT); if (len==0) return 0; if (len!=2) return -1; int datasize = (netbuf[0] << 8) | netbuf[1]; if ( datasize > CWS_NETMSGSIZE-2) return 0; len = recv(sock, netbuf, 2+datasize, MSG_PEEK|MSG_NOSIGNAL|MSG_DONTWAIT); if (len!=2+datasize) return -1; return len; } // -1: not yet // 0: disconnect // >0: ok int cs_peekmsg( int handle, struct message_data *msg, uint8_t *sessionkey,struct cs_custom_data *cd, unsigned char *buffer) { int len; if (msg->len<=0) { len = recv( handle, msg->data, 2, MSG_NOSIGNAL|MSG_DONTWAIT); if (len==0) return 0; if (len==-1) { if ( (errno==EINTR)||(errno==EWOULDBLOCK)||(errno==EAGAIN) ) return -1; else return 0; } if (len>0) msg->len = len; } else if (msg->len==1) { len = recv( handle, msg->data+1, 1, MSG_NOSIGNAL|MSG_DONTWAIT); if (len==0) return 0; if (len==-1) { if ( (errno == EINTR)||(errno==EWOULDBLOCK)||(errno==EAGAIN) ) return -1; else return 0; } if (len>0) msg->len +=len; } if (msg->len<2) return -1; // GOOD int datasize = 2 + ( (msg->data[0] << 8) | msg->data[1] ); if ( datasize > CWS_NETMSGSIZE ) return 0; // if (datasize > msg->len) { len = recv( handle, msg->data+msg->len, datasize-msg->len, MSG_NOSIGNAL|MSG_DONTWAIT); //printf(" lennn = %d\n", len); if (len==0) return 0; if (len==-1) { if ( (errno==EINTR)||(errno==EWOULDBLOCK)||(errno==EAGAIN) ) return -1; else return 0; } if (len>0) msg->len +=len; } //printf(" chk msg '%s' (%d) datasize:%d\n", cli->user, msg->len, datasize); if (datasize == msg->len) { len = des_decrypt( msg->data, msg->len, sessionkey); msg->len = 0; if (len < 15) return 0; int returnLen = (((msg->data[13] & 0x0f) << 8 ) | msg->data[14]) + 3; if ( returnLen > (len-12) ) return 0; // Setup Custom Data if (cd) { cd->msgid = (msg->data[2] << 8) | msg->data[3]; cd->sid = (msg->data[4] << 8) | msg->data[5]; cd->caid = (msg->data[6] << 8) | msg->data[7]; cd->provid = (msg->data[8] << 16) | (msg->data[9] << 8) | msg->data[10]; } memcpy(buffer, msg->data+12, returnLen); return returnLen; } return -1; }