source: admin/Sources/Includes/ogAdmLib.c @ 044d306

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacionwebconsole3
Last change on this file since 044d306 was 396232e, checked in by ramon <ramongomez@…>, 11 years ago

#621: Alonso corrige la función recibeTrama del servicio ogAdmServer para detectar tramas inválidas, evitando entrar en bucle infinito.

git-svn-id: https://opengnsys.es/svn/branches/version1.0@4211 a21b9725-9963-47de-94b9-378ad31fedc9

  • Property mode set to 100644
File size: 35.5 KB
Line 
1// **************************************************************************************************************************************************
2// Libreria: ogAdmLib
3// Autor: José Manuel Alonso (E.T.S.I.I.) Universidad de Sevilla
4// Fecha Creación: Marzo-2010
5// Fecha Última modificación: Marzo-2010
6// Nombre del fichero: ogAdmLib.c
7// Descripción: Este fichero implementa una libreria de funciones para uso común de los servicios
8// **************************************************************************************************************************************************
9// ________________________________________________________________________________________________________
10// Función: encriptar
11//
12//      Descripción:
13//              Encripta una cadena
14//      Parametros:
15//              - cadena : Cadena a encriptar
16//              - ret : Longitud de la caden cadena encriptada
17// ________________________________________________________________________________________________________
18char * encriptar(char *cadena,int*ret)
19{
20        /*
21        int i,lon;
22        char clave;
23       
24        clave = 12 & 0xFFU; // La clave elegida entre 0-255, en este caso 12
25        lon=strlen(cadena);
26        for(i=0;i<lon;i++)
27      cadena[i]=((char)cadena[i] ^ clave) & 0xFF;
28        *ret=lon;
29        */
30        return(cadena);
31}
32// ________________________________________________________________________________________________________
33// Función: desencriptar
34//
35//      Descripción:
36//              Desencripta una cadena
37//      Parametros:
38//              - cadena : Cadena a desencriptar
39//              - ret : Longitud de la caden cadena encriptada
40// ________________________________________________________________________________________________________
41char * desencriptar(char *cadena,int* ret)
42{
43        /*
44        int i,lon;
45        char clave;
46       
47        clave = 12 & 0xFFU; // La clave elegida entre 0-255, en este caso 12
48        lon=strlen(cadena);
49        for(i=0;i<lon;i++)
50                cadena[i]=((char)cadena[i] ^ clave) & 0xFF;
51        *ret=lon;
52        */
53        return(cadena);
54
55}
56// ________________________________________________________________________________________________________
57// Función: tomaHora
58//
59//      Descripción:
60//              Devuelve la hora del sistema
61//      Parametros:
62//              Ninguno
63// ________________________________________________________________________________________________________
64struct tm * tomaHora()
65{
66        time_t rawtime;
67        time ( &rawtime );
68        return(localtime(&rawtime));
69}
70// ________________________________________________________________________________________________________
71// Función: registraLog
72//
73//      Descripción:
74//              Registra los eventos en un fichero log ya sean errores o información
75//      Parametros:
76//              - fileLog : Ruta completa del archivo de log
77//              - msg : Descripción del error
78//              - swe: Switch que indica si se debe recuperar además el literal de error del propio sistema operativo
79// ________________________________________________________________________________________________________
80void registraLog(const char* filelog,const char *msg,int swe)
81{
82        FILE *flog;
83        struct tm * t;
84
85        t = tomaHora();
86        flog=fopen(filelog,"at");
87        if(swe)
88                fprintf (flog,"%02d/%02d/%d %02d:%02d %s: %s\n",t->tm_mday,t->tm_mon+1,t->tm_year+1900,t->tm_hour,t->tm_min,msg,strerror(errno));
89        else
90                fprintf (flog,"%02d/%02d/%d %02d:%02d %s\n",t->tm_mday,t->tm_mon+1,t->tm_year+1900,t->tm_hour,t->tm_min,msg);
91        fclose(flog);
92}
93// ________________________________________________________________________________________________________
94// Función: errorLog
95//
96//      Descripción:
97//              Registra los sucesos de errores preestablecidos en el fichero de log
98//      Parametros:
99//              - coderr : Código del mensaje de error
100//              - swe: Switch que indica si se debe recuperar además el literal de error del propio sistema operativo
101// ________________________________________________________________________________________________________
102void errorLog(const char *modulo, int coderr, int swe) {
103        char msglog[LONSUC];
104
105        sprintf(msglog, "*** Error: %s. Módulo %s", tbErrores[coderr], modulo);
106        registraLog(szPathFileLog, msglog, swe);
107}
108// ________________________________________________________________________________________________________
109// Función: errorInfo
110//
111//      Descripción:
112//              Registra los sucesos de errores dinámicos en el fichero de log
113//      Parametros:
114//              - msgerr : Descripción del error
115//              - swe: Switch que indica si se debe recuperar además el literal de error del propio sistema operativo
116// ________________________________________________________________________________________________________
117void errorInfo(const char *modulo, char *msgerr) {
118        char msglog[LONSUC];
119
120        sprintf(msglog, "*** Error: %s. Módulo %s", msgerr, modulo);
121        registraLog(szPathFileLog, msglog, FALSE);
122}
123// ________________________________________________________________________________________________________
124// Función: infoLog
125//
126//      Descripción:
127//              Registra los sucesos de información en el fichero de log
128//      Parametros:
129//              - coderr : Código del mensaje de información
130// ________________________________________________________________________________________________________
131void infoLog(int codinf) {
132        char msglog[LONSUC];
133
134        sprintf(msglog, "*** Info: %s", tbMensajes[codinf]);
135        registraLog(szPathFileLog, msglog, FALSE);
136}
137// ________________________________________________________________________________________________________
138// Función: infoDebug
139//
140//      Descripción:
141//              Registra los mensajes de debugs en el fichero de log
142//      Parametros:
143//              - msgdeb : Descripción del mensaje de información
144// ________________________________________________________________________________________________________
145void infoDebug(char* msgdeb) {
146        char msglog[LONSUC+15]; // Cadena de registro (reserva caracteres para el prefijo).
147
148        sprintf(msglog, "*** Debug: %d-%s", ndebug, msgdeb);
149        registraLog(szPathFileLog, msglog, FALSE);
150}
151//______________________________________________________________________________________________________
152// Función: ValidacionParametros
153//
154//       Descripción:
155//              Valida que los parametros de ejecución del programa sean correctos
156//      Parámetros:
157//              - argc: Número de argumentos
158//              - argv: Puntero a cada argumento
159//              - eje:  Tipo de ejecutable (1=Servicio,2=Repositorio o 3=Cliente)
160//      Devuelve:
161//              - TRUE si los argumentos pasados son correctos
162//              - FALSE en caso contrario
163//      Especificaciones:
164//              La sintaxis de los argumentos es la siguiente
165//                      -f      Archivo de configuración del servicio
166//                      -l      Archivo de logs
167//                      -d      Nivel de debuger (mensages que se escribirán en el archivo de logs)
168//      Devuelve:
169//              TRUE: Si el proceso es correcto
170//              FALSE: En caso de ocurrir algún error
171//______________________________________________________________________________________________________
172BOOLEAN validacionParametros(int argc, char*argv[],int eje) {
173        int i;
174        char modulo[] = "validacionParametros()";
175
176        switch(eje){
177                case 1: // Administrador
178                        strcpy(szPathFileCfg, "ogAdmServer.cfg"); // Valores por defecto de archivos
179                        strcpy(szPathFileLog, "ogAdmServer.log"); // de configuración y de logs
180                        break;
181                case 2: // Repositorio
182                        strcpy(szPathFileCfg, "ogAdmRepo.cfg"); // Valores por defecto de archivos
183                        strcpy(szPathFileLog, "ogAdmRepo.log"); // de configuración y de logs
184                        break;
185                case 3: // Cliente OpenGnsys
186                        strcpy(szPathFileCfg, "ogAdmClient.cfg"); // Valores por defecto de archivos
187                        strcpy(szPathFileLog, "ogAdmClient.log"); // de configuración y de logs
188                        break;
189                case 4: // Servicios DHCP,BOOTP Y TFTP
190                        strcpy(szPathFileCfg, "ogAdmBoot.cfg"); // Valores por defecto de archivos
191                        strcpy(szPathFileLog, "ogAdmBoot.log"); // de configuración y de logs
192                        break;
193                case 5: // Agente
194                        strcpy(szPathFileCfg, "ogAdmAgent.cfg"); // Valores por defecto de archivos
195                        strcpy(szPathFileLog, "ogAdmAgent.log"); // de configuración y de logs
196                        break;
197                case 6: // Agente
198                        strcpy(szPathFileCfg, "ogAdmWinClient.cfg"); // Valores por defecto de archivos
199                        strcpy(szPathFileLog, "ogAdmWinClient.log"); // de configuración y de logs
200                        break; 
201                case 7: // Agente
202                        strcpy(szPathFileCfg, "ogAdmnxClient.cfg"); // Valores por defecto de archivos
203                        strcpy(szPathFileLog, "ogAdmLnxClient.log"); // de configuración y de logs
204                        break;                 
205        }
206
207        ndebug = 1; // Nivel de debuger por defecto
208
209        for (i = 1; (i + 1) < argc; i += 2) {
210                if (argv[i][0] == '-') {
211                        switch (tolower(argv[i][1])) {
212                        case 'f':
213                                if (argv[i + 1] != NULL)
214                                        strcpy(szPathFileCfg, argv[i + 1]);
215                                else {
216                                        errorLog(modulo, 10, FALSE);
217                                        return (FALSE);
218                                }
219                                break;
220                        case 'l':
221                                if (argv[i + 1] != NULL)
222                                        strcpy(szPathFileLog, argv[i + 1]);
223                                else {
224                                        errorLog(modulo, 11, FALSE);
225                                        return (FALSE);
226                                }
227                                break;
228                        case 'd':
229                                if (argv[i + 1] != NULL) {
230                                        ndebug = atoi(argv[i + 1]);
231                                        if (ndebug < 1)
232                                                ndebug = 1; // Por defecto el nivel de debug es 1
233                                } else
234                                        ndebug = 1; // Por defecto el nivel de debug es 1
235                                break;
236                        default:
237                                errorLog(modulo, 12, FALSE);
238                                exit(EXIT_FAILURE);
239                                break;
240                        }
241                }
242        }
243        return (TRUE);
244}
245//______________________________________________________________________________________________________
246// Función: reservaMemoria
247//
248//      Descripción:
249//              Reserva memoria para una variable
250//      Parámetros:
251//              - lon:  Longitud en bytes de la reserva
252//      Devuelve:
253//              Un puntero a la zona de memoria reservada que ha sido previamente rellena con zeros o nulos
254//______________________________________________________________________________________________________
255char* reservaMemoria(int lon)
256{
257        char *mem;
258
259        mem=(char*)malloc(lon);
260        if(mem!=NULL)
261                memset(mem,0,lon);
262        return(mem);
263}
264//______________________________________________________________________________________________________
265// Función: ampliaMemoria
266//
267//      Descripción:
268//              Amplia memoria para una variable
269//      Parámetros:
270//              - ptr:  Puntero al buffer de memoria que se quiere ampliar
271//              - lon:  Longitud en bytes de la amplicación
272//      Devuelve:
273//              Un puntero a la zona de memoria reservada que ha sido previamente rellena con zeros o nulos
274//______________________________________________________________________________________________________
275char* ampliaMemoria(char* ptr,int lon)
276{
277        char *mem;
278
279        mem=(char*)realloc(ptr,lon*sizeof(char*));
280        if(mem!=NULL)
281                return(mem);
282        return(NULL);
283}
284//______________________________________________________________________________________________________
285// Función: liberaMemoria
286//
287//      Descripción:
288//              Libera memoria para una variable
289//      Parámetros:
290//              - ptr:  Puntero al buffer de memoria que se quiere liberar
291//      Devuelve:
292//              Nada
293//______________________________________________________________________________________________________
294void liberaMemoria(void* ptr)
295{
296        if(ptr){
297                free (ptr);
298        }
299}
300// ________________________________________________________________________________________________________
301// Función: splitCadena
302//
303//      Descripción:
304//                      Trocea una cadena según un carácter delimitador
305//      Parámetros:
306//                      - trozos: Array de punteros a cadenas
307//                      - cadena: Cadena a trocear
308//                      - chd: Carácter delimitador
309//      Devuelve:
310//              Número de trozos en que se divide la cadena
311// ________________________________________________________________________________________________________
312int splitCadena(char **trozos,char *cadena, char chd)
313{
314        int w=0;
315        if(cadena==NULL) return(w);
316
317        trozos[w++]=cadena;
318        while(*cadena!='\0'){
319                if(*cadena==chd){
320                        *cadena='\0';
321                        if(*(cadena+1)!='\0')
322                                trozos[w++]=cadena+1;
323                }
324                cadena++;
325        }
326        return(w); // Devuelve el número de trozos
327}
328// ________________________________________________________________________________________________________
329// Función: sustituir
330//
331//      Descripción:
332//                      Sustituye las apariciones de un caracter por otro en una cadena
333//      Parámetros:
334//                      - cadena: Cadena a convertir
335//                      - cho: Caracter a sustituir
336//                      - chs: Caracter sustituto
337// ________________________________________________________________________________________________________
338void sustituir(char *cadena,char cho,char chs)
339{
340        int x=0;
341
342        while(cadena[x]!=0) {
343                if (cadena[x]==cho)
344                        cadena[x]=chs;
345                x++;
346        }
347}
348// ________________________________________________________________________________________________________
349// Función: escaparCadena
350//
351//      Descripción:
352//                      Sustituye las apariciones de un caracter comila simple ' por \'
353//      Parámetros:
354//                      - cadena: Cadena a escapar
355// Devuelve:
356//              La cadena con las comillas simples sustituidas por \'
357// ________________________________________________________________________________________________________
358char* escaparCadena(char *cadena)
359{
360        int b,c;
361        char *buffer;
362
363        buffer = (char*) reservaMemoria(strlen(cadena)*2); // Toma memoria para el buffer de conversión
364        if (buffer == NULL) { // No hay memoria suficiente para el buffer
365                return (FALSE);
366        }
367
368        c=b=0;
369        while(cadena[c]!=0) {
370                if (cadena[c]=='\''){
371                        buffer[b++]='\\';
372                        buffer[b++]='\'';
373                }
374                else{
375                        buffer[b++]=cadena[c];
376                }
377                c++;
378        }
379        return(buffer);
380}
381// ________________________________________________________________________________________________________
382// Función: StrToUpper
383//
384//      Descripción:
385//                      Convierta una cadena en mayúsculas
386//      Parámetros:
387//                      - cadena: Cadena a convertir
388// ________________________________________________________________________________________________________
389char* StrToUpper(char *cadena)
390{
391        int x=0;
392
393        while(cadena[x]!=0) {
394                if (cadena[x] >= 'a' && cadena[x] <= 'z') {
395                        cadena[x] -= 32;
396                }
397                x++;
398        }
399        return(cadena);
400}
401// ________________________________________________________________________________________________________
402// Función: StrToUpper
403//
404//      Descripción:
405//                      Convierta una cadena en mayúsculas
406//      Parámetros:
407//                      - cadena: Cadena a convertir
408// ________________________________________________________________________________________________________
409char* StrToLower(char *cadena)
410{
411        int x=0;
412
413        while(cadena[x]!=0) {
414                if (cadena[x] >= 'A' && cadena[x] <= 'Z') {
415                        cadena[x] += 32;
416                }
417                x++;
418        }
419        return(cadena);
420}
421// ________________________________________________________________________________________________________
422// Función: INTROaFINCAD
423//
424//              Descripción:
425//                      Cambia caracteres INTROS por fin de cadena ('\0')  en una trama
426//              Parametros:
427//                      - parametros: Puntero a los parametros de la trama
428//                      - lon: Longitud de la cadena de parametros
429// ________________________________________________________________________________________________________
430void INTROaFINCAD(TRAMA* ptrTrama)
431{
432        char *i,*a,*b;
433
434        a=ptrTrama->parametros;
435        b=a+ptrTrama->lonprm;
436        for(i=a;i<b;i++){ // Cambia los NULOS por INTROS
437                if(*i=='\r') *i='\0';
438        }
439}
440// ________________________________________________________________________________________________________
441// Función: FINCADaINTRO
442//
443//              Descripción:
444//                      Cambia caracteres fin de cadena ('\0') por INTROS en una trama
445//              Parametros:
446//                      - parametros: Puntero a los parametros de la trama
447//                      - lon: Longitud de la cadena de parametros
448// ________________________________________________________________________________________________________
449void FINCADaINTRO(TRAMA* ptrTrama)
450{
451        char *i,*a,*b;
452
453        a=ptrTrama->parametros;
454        b=a+ptrTrama->lonprm;
455        for(i=a;i<b;i++){ // Cambia los NULOS por INTROS
456                if(*i=='\0') *i='\r';
457        }
458}
459// ________________________________________________________________________________________________________
460// Función: cuentaIPES
461//
462//              Descripción:
463//                      Cuenta los caracteres "." de las IPES dentro del parámetros iph de una trama
464//                      con lo cual dividiendo por 3 se puede saber la cantdad de direcciones IPES en la cadena
465//              Parametros:
466//                      - ipes: Cadena con las IPES separadas por ";"
467// ________________________________________________________________________________________________________
468int cuentaIPES(char* ipes)
469{
470        int i,a,b,c=0;
471
472        a=0;
473        b=strlen(ipes);
474        for(i=a;i<b;i++){ // Cambia los NULOS por INTROS
475                if(ipes[i]=='.') c++;
476        }
477        return(c/3);
478}
479// ________________________________________________________________________________________________________
480// Función: tomaParametro
481//
482//              Descripción:
483//                      Devuelve el valor de un parametro incluido en una cadena con formatos: "nombre=valor"
484//              Parámetros:
485//                      - nombre: Nombre del parámetro a recuperar
486//                      - paramestros: Cadena que contiene todos los parámetros
487// ________________________________________________________________________________________________________
488char* tomaParametro(const char* nombre,TRAMA* ptrTrama)
489{
490        char *a,*b,*pos;
491
492        a=ptrTrama->parametros;
493        b=a+ptrTrama->lonprm;
494        for(pos=a;pos<b;pos++){ // Busca valor del parámetro
495                if(pos[0]==nombre[0]){
496                        if(pos[1]==nombre[1]){
497                                if(pos[2]==nombre[2]){
498                                        if(pos[3]=='='){
499                                                pos+=4;
500                                                return(pos);
501                                        }
502                                }
503                        }
504                }
505        }
506        return(NULL);
507}
508//______________________________________________________________________________________________________
509// Función: copiaParametro
510//
511//      Descripción:
512//              Devuelve una copia del valor de un parámetro
513//      Parámetros:
514//              - ptrTrama: contenido del mensaje
515//              - parametro: Nombre del parámetro
516//              - lon: Nombre del parámetro
517//      Devuelve:
518//              Un puntero a la cadena que contiene el valor del parámetro
519// ________________________________________________________________________________________________________
520char* copiaParametro(const char*nombre,TRAMA* ptrTrama)
521{
522        char *prm,*buffer;
523        char modulo[] = "copiaParametro()";
524
525
526        prm=tomaParametro(nombre,ptrTrama); // Toma identificador de acción
527        if(!prm)
528                return(NULL);
529        buffer = (char*) reservaMemoria(strlen(prm)+1); // Toma memoria para el buffer de lectura.
530        if (buffer == NULL) { // No hay memoria suficiente para el buffer
531                errorLog(modulo, 3, FALSE);
532                return (FALSE);
533        }
534        strcpy(buffer,prm);
535        return(buffer);
536}
537// ________________________________________________________________________________________________________
538// Función: igualIP
539//
540//      Descripción:
541//              Comprueba si una cadena con una dirección IP está incluida en otra que  contienen varias direcciones ipes
542//              separadas por punto y coma
543//      Parámetros:
544//              - cadenaiph: Cadena de direcciones IPES
545//              - ipcliente: Cadena de la IP a buscar
546//      Devuelve:
547//              TRUE: Si el proceso es correcto
548//              FALSE: En caso de ocurrir algún error
549// ________________________________________________________________________________________________________
550BOOLEAN contieneIP(char *cadenaiph,char *ipcliente)
551{
552        char *posa,*posb;
553        int lon;
554
555        posa=strstr(cadenaiph,ipcliente);
556        if(posa==NULL) return(FALSE); // No existe la IP en la cadena
557        posb=posa; // Iguala direcciones
558        while(TRUE){
559                posb++;
560                if(*posb==';') break;
561                if(*posb=='\0') break;
562                if(*posb=='\r') break;
563        }
564        lon=strlen(ipcliente);
565        if((posb-posa)==lon) return(TRUE); // IP encontrada
566        return(FALSE);
567}
568// ________________________________________________________________________________________________________
569// Función: rTrim
570//
571//               Descripción:
572//                      Elimina caracteres de espacios y de asci menor al espacio al final de la cadena
573//              Parámetros:
574//                      - cadena: Cadena a procesar
575// ________________________________________________________________________________________________________
576char* rTrim(char *cadena)
577{
578        int i,lon;
579       
580        lon=strlen(cadena);
581        for (i=lon-1;i>=0;i--){
582                if(cadena[i]<32)
583                        cadena[i]='\0';
584                else
585                        return(cadena);
586        }
587        return(cadena);
588}
589// ________________________________________________________________________________________________________
590// Función: mandaTrama
591//
592//      Descripción:
593//              Envía una trama por la red
594//      Parametros:
595//                      - sock : El socket del host al que se dirige la trama
596//                      - trama: El contenido de la trama
597//                      - lon: Longitud de la parte de parametros de la trama que se va a mandar
598//      Devuelve:
599//              TRUE: Si el proceso es correcto
600//              FALSE: En caso de ocurrir algún error
601// ________________________________________________________________________________________________________
602BOOLEAN mandaTrama(SOCKET *sock, TRAMA* ptrTrama)
603{
604        int lonprm;
605        char *buffer,hlonprm[LONHEXPRM+1];
606        BOOLEAN res;
607
608        lonprm=strlen(ptrTrama->parametros);
609        ptrTrama->parametros=encriptar(ptrTrama->parametros,&lonprm); // Encripta los parámetros
610        sprintf(hlonprm,"%05X",LONGITUD_CABECERATRAMA+LONHEXPRM+lonprm); // Convierte en hexadecimal la longitud
611
612        buffer=reservaMemoria(LONGITUD_CABECERATRAMA+LONHEXPRM+lonprm); // Longitud total de la trama
613        if(buffer==NULL)
614                return(FALSE);
615        memcpy(buffer,ptrTrama,LONGITUD_CABECERATRAMA); // Copia cabecera de trama
616        memcpy(&buffer[LONGITUD_CABECERATRAMA],hlonprm,LONHEXPRM); // Copia longitud de la trama
617        memcpy(&buffer[LONGITUD_CABECERATRAMA+LONHEXPRM],ptrTrama->parametros,lonprm);
618        res=sendData(sock,buffer,LONGITUD_CABECERATRAMA+LONHEXPRM+lonprm);
619        liberaMemoria(buffer);
620        return (res);
621}
622// ________________________________________________________________________________________________________
623// Función: sendData
624//
625//      Descripción:
626//              Envía datos por la red a través de un socket
627//      Parametros:
628//                      - sock : El socket por donde se envía
629//                      - datos: El contenido a enviar
630//                      - lon: Cantidad de bites a enviar
631//      Devuelve:
632//              TRUE: Si el proceso es correcto
633//              FALSE: En caso de ocurrir algún error
634// ________________________________________________________________________________________________________
635BOOLEAN sendData(SOCKET *sock, char* datos,int lon)
636{
637        int idx,ret;
638        idx = 0;
639        while (lon > 0) {
640                ret = send(*sock,&datos[idx],lon, 0);
641                if (ret == 0) { // Conexión cerrada por parte del cliente (Graceful close)
642                        break;
643                }
644                else{
645                        if (ret == SOCKET_ERROR)
646                                return (FALSE);
647                }
648                lon -= ret;
649                idx += ret;
650        }
651        return (TRUE);
652}
653// ________________________________________________________________________________________________________
654// Función: recibeTrama
655//
656//      Descripción:
657//              Recibe una trama por la red
658//      Parametros:
659//              - sock : El socket del cliente
660//              - trama: El buffer para recibir la trama
661//      Devuelve:
662//              Un puntero a una estrucutra TRAMA o NULL si ha habido algún error
663//              FALSE: En caso de ocurrir algún error
664// ________________________________________________________________________________________________________
665TRAMA* recibeTrama(SOCKET *sock)
666{
667        int ret,lon,lSize;
668        char *buffer,*bufferd,bloque[LONBLK],*hlonprm;
669        TRAMA * ptrTrama;
670
671        lon=lSize=0;
672        do{
673                if(!recData(sock,bloque,LONBLK,&ret)) // Lee bloque
674                        return(NULL);
675
676                if (lon==0 && lSize==0 && ret==0) // Comprueba trama válida
677                        return(NULL);
678
679                if(lSize==0){ // Comprueba tipo de trama y longitud total de los parámetros
680                        if (strncmp(bloque, "@JMMLCAMDJ_MCDJ",15)!=0)
681                                return(NULL); // No se reconoce la trama
682                        hlonprm=reservaMemoria(LONHEXPRM+1);
683                        if(!hlonprm) return(NULL);
684                        memcpy(hlonprm,&bloque[LONGITUD_CABECERATRAMA],LONHEXPRM);
685                        lSize=strtol(hlonprm,NULL,16); // Longitud total de la trama con los parametros encriptados
686                        liberaMemoria(hlonprm);
687                        buffer=(char*)reservaMemoria(lSize); // Toma memoria para la trama completa
688                        if(!buffer)
689                                return(NULL);
690                }
691
692                if(ret>0){ // Datos recibidos
693                        memcpy(&buffer[lon],bloque,ret); // Añade bloque
694                        lon+=ret;
695                }
696        }while(lon<lSize);
697
698        ptrTrama=(TRAMA *)reservaMemoria(sizeof(TRAMA));
699        if (!ptrTrama)  return(NULL);
700        memcpy(ptrTrama,buffer,LONGITUD_CABECERATRAMA); // Copia cabecera de trama
701        lon=lSize-(LONGITUD_CABECERATRAMA+LONHEXPRM); // Longitud de los parametros aún encriptados
702        bufferd=desencriptar(&buffer[LONGITUD_CABECERATRAMA+LONHEXPRM],&lon);
703        initParametros(ptrTrama,lon); // Desencripta la trama
704        memcpy(ptrTrama->parametros,bufferd,lon);
705        liberaMemoria((char*)buffer);
706        ptrTrama->lonprm=lon; // Almacena longitud de los parámetros ya desencriptados
707        return(ptrTrama);
708}
709// ________________________________________________________________________________________________________
710// Función: recData
711//
712//      Descripción:
713//              Recibe datos por la red a través de un socket
714//      Parametros:
715//              - sock : El socket por el que se reciben los datos
716//              - datos: El buffer donde se almacenan
717//              - lon: Cantidad máxima de bites a recibir
718//              - ret: Cantidad de bites recibidos (Parámetro de salida)
719//      Devuelve:
720//              TRUE: Si el proceso es correcto
721//              FALSE: En caso de ocurrir algún error
722// ________________________________________________________________________________________________________
723BOOLEAN recData(SOCKET *sock, char* buffer,int lon,int* ret)
724{
725        *ret = 0;
726
727        while (TRUE) { // Bucle para recibir datos del cliente
728                *ret = recv(*sock,buffer, lon, 0);
729                if (*ret == 0) // Conexión cerrada por parte del cliente (Graceful close)
730                        break;
731                else {
732                        if (*ret == SOCKET_ERROR) {
733                                return (FALSE);
734                        } else
735                                // Datos recibidos
736                                break;
737                }
738        }
739        return(TRUE);
740}
741//______________________________________________________________________________________________________
742// Función: enviaFlag
743//
744//      Descripción:
745//              Envia una señal de sincronización
746//      Parámetros:
747//              - socket_c: (Salida) Socket utilizado para el envío (operativo)
748//              - ptrTrama: contenido del mensaje
749//      Devuelve:
750//              TRUE: Si el proceso es correcto
751//              FALSE: En caso de ocurrir algún error
752// ________________________________________________________________________________________________________
753BOOLEAN enviaFlag(SOCKET *socket_c,TRAMA *ptrTrama)
754{
755        char modulo[] = "enviaFlag()";
756        if (!mandaTrama(socket_c,ptrTrama)) {
757                errorLog(modulo,26,FALSE);
758                return (FALSE);
759        }
760        return(TRUE);
761}
762//______________________________________________________________________________________________________
763// Función: recibeFlag
764//
765//      Descripción:
766//              Recibe una señal de sincronización
767//      Parámetros:
768//              - socket_c: Socket utilizadopara la recepción (operativo)
769//              - ptrTrama: (Salida) Contenido del mensaje
770//      Devuelve:
771//              TRUE: Si el proceso es correcto
772//              FALSE: En caso de ocurrir algún error
773// ________________________________________________________________________________________________________
774BOOLEAN recibeFlag(SOCKET *socket_c,TRAMA *ptrTrama)
775{
776        ptrTrama=recibeTrama(socket_c);
777        if(!ptrTrama){
778                return(FALSE);
779        }
780        return(TRUE);
781}
782//______________________________________________________________________________________________________
783// Función: URLEncode
784//
785//      Descripción:
786//              Codifica una cadena en UrlEncode
787//      Parámetros:
788//              - src: La cadena a decodificar
789//      Devuelve:
790//              La cadena decodificada
791// ________________________________________________________________________________________________________
792char* URLEncode(char *src)
793{
794        char *dest;
795        int i,j=0,lon;
796
797        lon=strlen(src);
798        dest=(char*)reservaMemoria(lon*2);      // Reserva buffer  para la cadena
799        for(i=0;i<lon;i++){
800                if(src[i]==0x20){ // Espacio
801                        dest[j++] = '%';
802                        dest[j++] = '2';
803                        dest[j++] = '0';
804                }
805                else
806                        dest[j++] = src[i];
807        }
808        return(dest);
809}
810//______________________________________________________________________________________________________
811// Función: URLDecode
812//
813//      Descripción:
814//              Decodifica una cadena codificada con UrlEncode
815//      Parámetros:
816//              - src: La cadena a decodificar
817//      Devuelve:
818//              La cadena decodificada
819// ________________________________________________________________________________________________________
820char* URLDecode(char *src)
821{
822        const char *p = src;
823        char code[3] = {0};
824        unsigned long ascii = 0;
825        char *end = NULL;
826        char *dest,*cad;
827
828        dest=(char*)reservaMemoria(strlen(src));        // Reserva buffer  para la cadena
829        cad=dest;
830        while(*p){
831                if(*p == '%'){
832                        memcpy(code, ++p, 2);
833                        ascii = strtoul(code, &end, 16);
834                        *dest++ = (char)ascii;
835                        p += 2;
836                }
837                else
838                        *dest++ = *p++;
839        }
840        return(cad);
841}
842// ________________________________________________________________________________________________________
843// Función: leeArchivo
844//
845//      Descripción:
846//              Lee un archivo
847//      Parámetros:
848//              fil: Nombre completo del archivo
849//      Devuelve:
850//              Un puntero al buffer con el contenido leido
851
852//______________________________________________________________________________________________________
853char * leeArchivo(char *fil)
854{
855        FILE *f;
856        long lSize;
857        char* buffer;
858
859        f=fopen(fil,"rb");
860        if (!f)
861                return(NULL);
862        fseek (f,0,SEEK_END); // Obtiene tamaño del fichero.
863        lSize = ftell (f);
864        rewind (f);
865        buffer = (char*) reservaMemoria(lSize+1); // Toma memoria para el buffer de lectura.
866        if (!buffer) // No hay memoria suficiente para el buffer
867                return (NULL);
868        lSize=fread (buffer,1,lSize,f); // Lee contenido del fichero
869        fclose(f);
870        return (buffer);
871}
872// ________________________________________________________________________________________________________
873// Función: leeArchivo
874//
875//      Descripción:
876//              Calcula la longitud de un archivo
877//      Parámetros:
878//              fil: Nombre completo del archivo
879//      Devuelve:
880//              Un puntero al buffer con el contenido leido
881
882//______________________________________________________________________________________________________
883int lonArchivo(char *fil)
884{
885        FILE *f;
886        long lSize;
887
888        f=fopen(fil,"rb");
889        if (!f)
890                return(0);
891        fseek (f,0,SEEK_END); // Obtiene tamaño del fichero.
892        lSize = ftell (f);
893        fclose(f);
894        return (lSize);
895}
896// ________________________________________________________________________________________________________
897// Función: escribeArchivo
898//
899//      Descripción:
900//              Escribe un archivo
901//      Parámetros:
902//              fil: Nombre completo del archivo
903//              buffer: Un puntero al buffer con el contenido a escribir
904//      Devuelve:
905//______________________________________________________________________________________________________
906BOOLEAN escribeArchivo(char *fil,char*buffer)
907{
908        FILE *f;
909        long lSize;
910
911        f=fopen(fil,"wb");
912        if (!f){
913                return(FALSE);
914        }
915        lSize=strlen(buffer);
916        fwrite(buffer,1,lSize,f); // Escribe el contenido en el fichero
917        fclose(f);
918        return (TRUE);
919}
920// ________________________________________________________________________________________________________
921// Función: sendArchivo
922//
923//      Descripción:
924//              Envía un archivo por la red
925//      Parámetros:
926//              sock: Socket para el envío
927//              fil: Nombre local completo del archivo
928//      Devuelve:
929//              TRUE: Si el proceso es correcto
930//              FALSE: En caso de ocurrir algún error
931//______________________________________________________________________________________________________
932BOOLEAN sendArchivo(SOCKET *sock,char *fil)
933{
934        long lSize;
935        FILE *f;
936        char buffer[LONBLK];
937
938        f = fopen(fil,"rb");
939        if(!f) // El fichero no existe
940                return(FALSE);
941
942        while(!feof(f)){
943                lSize=fread (buffer,1,LONBLK,f); // Lee el contenido del fichero
944                if(!sendData(sock,buffer,lSize))
945                        return (FALSE);
946        }
947        fclose(f);
948        return(TRUE);
949}
950// ________________________________________________________________________________________________________
951// Función: recArchivo
952//
953//      Descripción:
954//              Recibe un archivo por la red
955//      Parámetros:
956//              sock: Socket para la recepción
957//              fil: Nombre local completo del archivo que se creará
958//      Devuelve:
959//              TRUE: Si el proceso es correcto
960//              FALSE: En caso de ocurrir algún error
961//______________________________________________________________________________________________________
962BOOLEAN recArchivo(SOCKET *sock,char *fil)
963{
964        int lon;
965        FILE *f;
966        char buffer[LONBLK];
967
968        f = fopen(fil,"wb");
969        if(!f) // No se ha podido crear el archivo
970                return(FALSE);
971        do{
972                if(!recData(sock,buffer,LONBLK,&lon))
973                        return(FALSE);
974                // Datos recibidos
975                if(lon>0)
976                        fwrite(buffer,1,lon,f); // Lee el contenido del fichero
977        }while(lon>0); // Bucle para recibir datos del cliente
978        fclose(f);
979        return(TRUE);
980}
981//______________________________________________________________________________________________________
982// Función: initParammetros
983//
984//       Descripción:
985//              Libera memoria del buffer de los parametros de la trama y vuelve a reservar espacio
986//      Parámetros:
987//              - parametros : Puntero a la zona donde están los parametros de una trama
988//              - lon : Tamaño de la nueva reserva de espacio para los parametros
989//      Devuelve:
990//              Un puntero a la nueva zona de memoria o NULL si ha habido algún error
991// Especificaciones:
992//              En caso de que el parámetro lon valga cero el tamaño a reservar será el estandar
993//______________________________________________________________________________________________________
994BOOLEAN initParametros(TRAMA* ptrTrama,int lon)
995{
996        if(lon==0) lon=LONGITUD_PARAMETROS;
997        ptrTrama->parametros=(char*)ampliaMemoria(ptrTrama->parametros,lon);
998        if(!ptrTrama->parametros)
999                return(FALSE);
1000        else
1001                return(TRUE);
1002}
1003//______________________________________________________________________________________________________
1004// Función: TCPConnect
1005//
1006//       Descripción:
1007//              Crea un socket y lo conecta a un servidor
1008//      Parámetros:
1009//              - ips : La Dirección IP del servidor
1010//              - port : Puerto para la comunicación
1011//      Devuelve:
1012//              Un socket para comunicaciones por protocolo TCP
1013//______________________________________________________________________________________________________
1014SOCKET TCPConnect(char *ips,char* port)
1015{
1016        SOCKET s;
1017    struct sockaddr_in server;
1018        char modulo[] = "TCPConnect()";
1019
1020        s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1021        if (s == INVALID_SOCKET){
1022                return (INVALID_SOCKET);
1023        }
1024        server.sin_family = AF_INET;
1025        server.sin_port = htons((short)atoi(port));
1026        server.sin_addr.s_addr = inet_addr(ips);
1027
1028        if (connect(s, (struct sockaddr *)&server, sizeof(server)) == INVALID_SOCKET){
1029                errorLog(modulo,38,TRUE);
1030                return (INVALID_SOCKET);
1031        }
1032
1033        return(s);
1034}
1035//______________________________________________________________________________________________________
1036// Función: AbreConexion
1037//
1038//       Descripción:
1039//              Abre la conexión entre el cliente y el servidor de administración
1040//      Parámetros:
1041//              - Ninguno
1042//      Devuelve:
1043//              Un socket de cliente para comunicaciones
1044//______________________________________________________________________________________________________
1045SOCKET abreConexion(void)
1046{
1047        int swloop=0;
1048        SOCKET s;
1049
1050        while(swloop<MAXCNX){
1051                s=TCPConnect(servidoradm,puerto);
1052                if(s!= INVALID_SOCKET){
1053                        return(s);
1054                }
1055                swloop++;
1056                #ifdef  __WINDOWS__
1057                        Sleep(5*1000);
1058                #else
1059                        sleep(5); // Espera cinco segundos antes de intentar una nueva conexión
1060                #endif
1061        }
1062        return(INVALID_SOCKET);
1063}
1064//______________________________________________________________________________________________________
1065// Función: enviaMensaje
1066//
1067//      Descripción:
1068//              Envia un mensaje al servidor de Administración
1069//      Parámetros:
1070//              - socket_c: (Salida) Socket utilizado para el envío
1071//              - ptrTrama: contenido del mensaje
1072//              - tipo: Tipo de mensaje
1073//                              C=Comando, N=Respuesta a un comando, P=Peticion,R=Respuesta a una petición, I=Informacion
1074//      Devuelve:
1075//              TRUE: Si el proceso es correcto
1076//              FALSE: En caso de ocurrir algún error
1077// ________________________________________________________________________________________________________
1078BOOLEAN enviaMensaje(SOCKET *socket_c,TRAMA *ptrTrama,char tipo)
1079{
1080        char modulo[] = "enviaMensaje()";
1081
1082        *socket_c=abreConexion();
1083        if(*socket_c==INVALID_SOCKET){
1084                errorLog(modulo,38,FALSE); // Error de conexión con el servidor
1085                return(FALSE);
1086        }
1087        ptrTrama->arroba='@'; // Cabecera de la trama
1088        strncpy(ptrTrama->identificador,"JMMLCAMDJ_MCDJ",14);   // identificador de la trama
1089        ptrTrama->tipo=tipo; // Tipo de mensaje
1090
1091        if (!mandaTrama(socket_c,ptrTrama)) {
1092                errorLog(modulo,26,FALSE);
1093                return (FALSE);
1094        }
1095        return(TRUE);
1096}
1097//______________________________________________________________________________________________________
1098// Función: recibeMensaje
1099//
1100//      Descripción:
1101//              Recibe un mensaje del servidor de Administración
1102//      Parámetros:
1103//              - socket_c: Socket utilizadopara la recepción
1104//              - ptrTrama: (Salida) Contenido del mensaje
1105//      Devuelve:
1106//              TRUE: Si el proceso es correcto
1107//              FALSE: En caso de ocurrir algún error
1108// ________________________________________________________________________________________________________
1109TRAMA* recibeMensaje(SOCKET *socket_c)
1110{
1111        TRAMA* ptrTrama;
1112        char modulo[] = "recibeMensaje()";
1113
1114        ptrTrama=recibeTrama(socket_c);
1115        if(!ptrTrama){
1116                errorLog(modulo,17,FALSE);
1117                return(NULL);
1118        }
1119        return(ptrTrama);
1120}
1121
1122// ________________________________________________________________________________________________________
1123
1124int tomaPuerto(SOCKET s)
1125{
1126        struct sockaddr_in sin;
1127        socklen_t addrlen = sizeof(sin);
1128        int local_port;
1129
1130        if(getpeername(s, (struct sockaddr *)&sin, &addrlen) == 0
1131                &&      sin.sin_family == AF_INET &&
1132        addrlen == sizeof(sin))
1133                {
1134          local_port = ntohs(sin.sin_port);
1135                }
1136        else
1137          local_port=-1;
1138
1139        return(local_port);
1140
1141}
1142
Note: See TracBrowser for help on using the repository browser.