root/trunk/src/renetcolSender.c @ 61

Revision 58, 10.0 KB (checked in by andreu, 15 years ago)

new aggregation method, new configuration files, corrections on the php script for graph generation.

  • Property svn:eol-style set to native
Line 
1/*
2 * File: renetcolSender.c
3 *
4 * Authors: ANDREU Francois-Xavier
5 *
6 * Copyright (C) 2005 2006 2007 GIP RENATER
7 */
8
9/*  This file is part of renetcol.
10 *
11 *  renetcol is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  renetcol is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with renetcol; if not, write to the Free Software
23 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
24 */
25
26#include "renetcolSender.h"
27
28key_t myKey = 0;
29int myQueue = 0;
30msgType myMsg;
31long type;
32RulesPtr rulesListPtr;
33char *keyId;
34char *remoteHost;
35int i=0;
36int j=0;
37unsigned char *myText;
38unsigned char buffer2[2];
39unsigned char buffer4[4];
40unsigned short nb=0;
41unsigned short typeMsg = 0;
42RulesPtr tmp = NULL;
43
44/*
45 * todo
46 */
47int
48todo(int sock, char *host)
49{
50  char buffer[256];
51  int length;
52  FILE *ruleFile;
53  FILE *tmpFile;
54  char field[4];
55  char port[6];
56  char value[44];
57  char operator[2];
58  char lines[256][256];
59  char line[256];
60  char lineCopy[256];
61  char strTok[1];
62  char strName[100];
63  int cpt = 0;
64  int i = 0;
65  int ruleToDelete = 0;
66
67  while (1){
68    length = read(sock, buffer, 256);
69    if (length < 0){
70      syslog(LOG_ERR, " read : %s", strerror(errno));
71      close(sock);
72      return 1;
73    }
74    if (length == 0)
75      break;
76    buffer[length] = '\0';
77    if (strncmp("DELETE", buffer, 6)==0){
78      /* DELETE ALL RULES FROM A REMOTE CLIENT */
79      if (!(ruleFile = fopen(RULES_FILE, "r"))) {
80        syslog (LOG_ERR, "error during %s opening\n", RULES_FILE);
81        close(sock);
82        exit(1);
83      } else {
84        while ( fgets(line, 256, ruleFile) != 0) {
85          strncpy(lineCopy, line, 256);
86          if (strncmp("N", lineCopy, 1) == 0){
87            ruleToDelete = 0;
88            if (sscanf(lineCopy, "%1s %s\n",
89                       strTok,
90                       strName) != 0) {
91              if (strncmp(strName, host, strlen(host)) == 0){
92                ruleToDelete = 1;
93              } else {
94                strncpy(lines[cpt], line, strlen(line));
95              }
96            } else {
97              close(sock);
98              return 1;
99            }
100          } else {
101            if (ruleToDelete==0) {
102              strncpy(lines[cpt], lineCopy, strlen(lineCopy));
103            }
104          }
105          cpt++;
106        } /* while end */
107        fclose(ruleFile);
108        if (!(tmpFile = fopen(FILE_TEMPO, "w"))) {
109          syslog (LOG_ERR, "error during %s opening", FILE_TEMPO);
110          close(sock);
111          return 1;
112        } else {
113          for (i=0; i<cpt; i++){
114            fprintf(tmpFile, "%s", lines[i]);
115          }
116          fclose(tmpFile);
117          if (remove(RULES_FILE)!=0){
118            syslog(LOG_ERR, "rules.txt remove pb: %s", strerror(errno));
119            close(sock);
120            return 1;
121          }
122          if (rename(FILE_TEMPO, RULES_FILE)!=0){
123            syslog(LOG_ERR, "rename file pb: %s", strerror(errno));
124            close(sock);
125            return 1;
126          }
127        }
128      }
129    } else {
130      /* NEW RULE */
131      if (sscanf(buffer, "%s %s %1s %s\n",
132                 port,
133                 field,
134                 operator,
135                 value) == 0) {
136        syslog (LOG_ERR, "error in recept rule: %s", buffer);
137        close(sock);
138        return 1;
139      }
140      if (!(ruleFile = fopen(RULES_FILE, "a"))) {
141        syslog (LOG_ERR, "error during %s opening", RULES_FILE);
142        close(sock);
143        return 1;
144      } else {
145        fprintf(ruleFile, "N %s\n", host);
146        fprintf(ruleFile, "O socket %s %s\n", host, port);
147        fprintf(ruleFile, "C %s %s %s\n", field, operator, value);
148        fclose(ruleFile);
149      }
150    }
151  }
152  close(sock);
153  return 0;
154}
155
156/*
157 * tcpServer
158 */
159int
160tcpServer ()
161{
162  struct addrinfo index, *result;
163  struct sockaddr_storage listenAddress;
164  socklen_t listenAddressLen;
165  int listenSock;
166  int returnCode;
167  pid_t renetcolPID = 0;
168  FILE *pidFile;
169  unsigned pid;
170  char line[256];
171  int status;
172
173  memset(&index, 0, sizeof index);
174  index.ai_flags = AI_PASSIVE;
175  index.ai_family = AF_UNSPEC;
176  index.ai_socktype = SOCK_STREAM;
177  index.ai_protocol = IPPROTO_TCP;
178  returnCode = getaddrinfo(NULL, RECEPT_PORT, &index, &result);
179  if (returnCode != 0) {
180    syslog(LOG_ERR, "getaddrinfo : %s", strerror(errno));
181    return -1;
182  }
183  listenAddressLen = result->ai_addrlen;
184  memcpy(&listenAddress, result->ai_addr, (size_t) listenAddressLen);   
185  listenSock = socket(result->ai_family, result->ai_socktype,
186                      result->ai_protocol);
187  if ( listenSock < 0) {
188    syslog(LOG_ERR, "socket : %s", strerror(errno));
189    freeaddrinfo(result);
190    return -1;
191  }
192  freeaddrinfo(result);
193 
194  {
195    int on = 1;
196    setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof on);
197  }
198  if (bind(listenSock, (struct sockaddr *) &listenAddress,
199           listenAddressLen) < 0 ||
200      listen(listenSock, 8) < 0) {
201    syslog(LOG_ERR, "bind or listen : %s", strerror(errno));
202    return -1;
203  }
204  for (;;) {           
205    int clientSock;
206    struct sockaddr_storage clientAddress;
207    socklen_t clientAddressLen;
208    char host[NI_MAXHOST];
209   
210    memset(&clientAddress, 0, sizeof clientAddress);
211    clientAddressLen = (socklen_t) sizeof clientAddress;
212   
213    if ((clientSock =
214         accept(listenSock, (struct sockaddr *)
215                &clientAddress,
216                &clientAddressLen)) < 0) {
217      continue;
218    }
219    if (clientAddress.ss_family != AF_INET &&
220        clientAddress.ss_family != AF_INET6) {
221      close(clientSock);
222      continue;
223    }
224    if (getnameinfo((struct sockaddr *) &clientAddress,
225                    clientAddressLen, host, sizeof host,
226                    NULL, (size_t) 0, NI_NUMERICHOST) == 0) {
227      syslog(LOG_INFO,
228             "New connection from %s", host);
229    }
230    remoteHost = host;
231    switch (fork ()) {
232    case 0 :
233      close (listenSock);
234      todo(clientSock, remoteHost);
235      if (!(pidFile = fopen("/tmp/pidrenetcol.tmp", "r"))) {
236        syslog (LOG_ERR, "error during /tmp/pidrenetcol.tmp opening : %s\n",
237                strerror(errno));
238        exit(1);
239      } else {
240        fgets(line, 256, pidFile);
241        if (sscanf(line, "%u", &pid)==0)
242          syslog(LOG_ERR,"sscanf : %s", strerror(errno));
243        renetcolPID = pid;
244      }
245      fclose(pidFile);
246      if (renetcolPID==0){
247        syslog(LOG_INFO, "PID null");
248      }else{
249        if (kill(renetcolPID, SIGUSR1)<0)
250          syslog(LOG_ERR, "I can't send SIGUSR1 to renetcol process : %s",
251                 strerror(errno));
252      }
253      exit (0);
254    case -1 :
255      syslog (LOG_ERR, "fork : %s", strerror(errno));
256      return (-1);
257    default :
258      close (clientSock);
259      if (waitpid( -1, &status, WNOHANG)==-1){
260        syslog(LOG_ERR, "waitpid : %s", strerror(errno));
261        exit(1);
262      }
263    }
264  }
265  return (0);
266}
267
268/*
269 *
270 */
271void initConfSender(){
272  RulesPtr tmp = NULL;
273
274  tmp = rulesListPtr;
275  for ( ; tmp; tmp=tmp->next) {
276    rulesListPtr = delRule(tmp, rulesListPtr);
277  }
278  rulesListPtr = NULL;
279  rulesListPtr = getRules(rulesListPtr, RULES_FILE);
280  tmp = rulesListPtr;
281  for ( ; tmp; tmp=tmp->next) {
282    if (tmp->type != 2) {
283      rulesListPtr = delRule(tmp, rulesListPtr);
284    }
285  }
286  tmp = NULL;
287}
288
289/*
290 * Main
291 * ----
292 */
293int 
294main (int argc, char *argv[])
295{
296  int s=0;
297  unsigned short rulesID = 0;
298  FILE *pidFile;
299  pid_t renetcolPID = 0;
300
301  if ( argc != 3) {
302    fprintf (stderr,
303             "%s: Usage: %s <key> <msg type>\n exp: %s renetcol 1 \n",
304             argv[0], argv[0], argv[0]);
305    exit(1);
306  }
307  if (sscanf (argv[2], "%ld", &type) != 1){
308    fprintf(stderr, "renetcolSender: Error, Invalid message type in command\n");
309    exit(1);
310  } 
311
312  openlog(argv[0], LOG_PID, LOG_USER);
313  keyId = (char *) malloc((strlen(argv[1])+1) * sizeof(char));
314  strcpy (keyId, argv[1]);
315  rulesListPtr = NULL;
316  rulesListPtr = getRules(rulesListPtr, RULES_FILE);
317  /* we delete rules which are not type socket */
318  tmp = rulesListPtr;
319  for ( ; tmp; tmp=tmp->next) {
320    if (tmp->type != 2) {
321      rulesListPtr = delRule(tmp, rulesListPtr);
322    }
323  }
324  tmp = NULL;
325  /* get IPC messages queue */
326  if ((myKey = ftok(keyId, 0))== -1){
327    syslog(LOG_ERR, "ftok : %s", strerror(errno));
328    exit(1);
329  }
330  if ((myQueue = msgget(myKey, 0)) == -1){
331    syslog(LOG_ERR, "msgget : %s", strerror(errno));
332    exit(1);
333  }
334
335/*   chdir ("/"); */
336  fprintf(stderr, "renetcolSender: I become a deamon, next messages via syslogd. By.\n");
337  if (fork () != 0)
338    exit (0);
339  if (setsid() == -1){
340    exit(4);
341  }
342/*   for (i = 0; i < FOPEN_MAX; i ++) */
343/*     close (i); */
344 
345  /* launch a TCP server to listen remote clients */
346  switch (fork ()) {
347  case 0 : /* son */
348    tcpServer();
349  case -1 :
350    syslog (LOG_ERR, "fork : %s", strerror(errno));
351    return (-1);
352  default : /* father */
353    break;
354  }
355  /* loop on the message queue */
356  while (1) {
357    i=0;
358    myText = msgRcv(myQueue, &myMsg, type);
359    buffer2[0]= *(myText+i); i++;
360    buffer2[1]= *(myText+i); i++;
361    typeMsg = *((unsigned short *)&buffer2);
362    if (1==typeMsg){
363      /* we send the template definition to all the known destination */
364      tmp = rulesListPtr;
365      for ( ; tmp; tmp=tmp->next) {
366        s = sendMessage(tmp->host->sockId, myText, sizeof(myMsg.text),
367                        tmp->host->hostAddressPtr);
368      }
369    } else if (11==*((unsigned short*)&buffer2)){
370      buffer2[0]= *(myText+i); i++;
371      buffer2[1]= *(myText+i); i++;
372      rulesID = *((unsigned short *)&buffer2);
373      /* here we send the flow to the correct remote client */
374      tmp = rulesListPtr;
375      for ( ; tmp; tmp=tmp->next) { /* FIXME while */
376        if (tmp->id == rulesID){
377          s = sendMessage(tmp->host->sockId, myText, sizeof(myMsg.text),
378                          tmp->host->hostAddressPtr);
379        }
380      }
381    } else if (12==*((unsigned short*)&buffer2)){
382      buffer4[0]= *(myText+i); i++;
383      buffer4[1]= *(myText+i); i++;
384      buffer4[2]= *(myText+i); i++;
385      buffer4[3]= *(myText+i); i++;
386      renetcolPID = *((pid_t *)&buffer4);
387      if (!(pidFile = fopen("/tmp/pidrenetcol.tmp", "w"))) {
388        syslog (LOG_ERR, "error during /tmp/pidrenetcol.tmp opening : %s\n",
389                strerror(errno));
390        exit(1);
391      } else {
392        if (fprintf(pidFile, "%u", renetcolPID)==0)
393          syslog(LOG_ERR,"fprintf : %s", strerror(errno));
394      }
395      fclose(pidFile);
396    } else if (13==*((unsigned short*)&buffer2)){
397      initConfSender();
398    } else {
399      syslog(LOG_INFO, "Msg type undefined ??");
400    }
401    i=0;
402  }
403  return(0);
404}
Note: See TracBrowser for help on using the browser.