## modules/pm/protocol_mirror.c

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. parse_request
2. PM_interact

       1 /***************************************
       2
       3   Protocol mirror module (pw).  Whois protocol.
       4
       5   Status: NOT REVUED, NOT TESTED
       6
       7   ******************/ /******************
       8   Filename            : protocol_mirror.c
       9   Author              : andrei
      10   OSs Tested          : Solaris
      11   ******************/ /******************
      12   Copyright (c) 1999                              RIPE NCC
      13
      14   All Rights Reserved
      15
      16   Permission to use, copy, modify, and distribute this software and its
      17   documentation for any purpose and without fee is hereby granted,
      18   provided that the above copyright notice appear in all copies and that
      19   both that copyright notice and this permission notice appear in
      20   supporting documentation, and that the name of the author not be
      21   used in advertising or publicity pertaining to distribution of the
      22   software without specific, written prior permission.
      23
      24   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      25   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      26   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      27   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      28   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      29   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      30   ***************************************/
      31 #include <stdio.h>
      32 #include <glib.h>
      33
      34 #include "protocol_mirror.h"
      35 #include "mysql_driver.h"
      36 #include "constants.h"
      37
      38 //#include "access_control.h"
      39 #include "socket.h"
      40 #include "stubs.h"
      41 #include "ud.h"
      42 #include "ta.h"
      43
      44 #include "ca_configFns.h"
      45 #include "ca_dictSyms.h"
      46 #include "ca_macros.h"
      47 #include "ca_srcAttribs.h"
      48
      49
      50
      51 #define MIN_ARG_LENGTH  6
      52 #define NRTM_DELIM "-:"
      53 /*
      54 * parses input and fills nrtm_q_t structure
      55 *
      56 * Returns:
      57 *  -1 in case of garbage
      58 *  0  in case of valid -g
      59 *  1  in case of -q sources
      60 *
      61 */
      62 static int parse_request(char *input, nrtm_q_t *nrtm_q)
         /* [<][>][^][v][top][bottom][index][help] */
      63 {
      64  char *ptr=input;
      65  char *token;
      66  char **tokens;
      67  char **tokens2;
      68  int res=0;
      69
      70 // return(-1);
      71
      72  if(strlen(input)<MIN_ARG_LENGTH) return(-1);
      73  g_strchug(input);
      74  res=strncmp(input, "-g", 2);
      75  if(res!=0) {
      76          /* may be this is -q source query */
      77          res=strncmp(input, "-q", 2);
      78          if(res!=0)return(-1);
      79          ptr+=2;
      80          g_strchug(ptr);
      81          res=strncmp(ptr, "sources", 7);
      82          if(res!=0)return(-1);
      83          ptr+=7;
      84          g_strchug(ptr);
      85          token=ptr;
      86          if ((*token=='\0') || (*token=='\n'))nrtm_q->source=NULL;
      87          else {
      88            ptr=index(token, ' ');
      89            if (ptr) nrtm_q->source=g_strndup(token, (ptr-token));
      90            else nrtm_q->source=g_strdup(token);
      91          }
      92          return(1);
      93  }
      94
      95  /* this is -q query */
      96  ptr+=2;
      97
      98
      99  g_strchug(ptr);
     100  g_strdelimit(ptr, NRTM_DELIM, ':');
     101  tokens=g_strsplit(ptr, ":", 4);
     102  if(tokens==NULL) return(-1);
     103
     104  if(tokens[0]) {
     105     /* first token is source name */
     106     nrtm_q->source=g_strdup(tokens[0]);
     107     if(tokens[1]) {
     108       /* second token is version number */
     109       nrtm_q->version=atoi(tokens[1]);
     110       if(tokens[2]) {
     111         /* this is first serial */
     112         nrtm_q->first=atol(tokens[2]);
     113           if(tokens[3]) {
     114             /* this is last serial */
     115               nrtm_q->last=atol(tokens[3]);
     116           } else res=-1;
     117       } else res=-1;
     118     } else res=-1;
     119  } else res=-1;
     120  g_strfreev(tokens);
     121
     122 return(res);
     123 }
     124
     125
     126 /* PM_interact() */
     127 /*++++++++++++++++++++++++++++++++++++++
     128   Interact with the client.
     129
     130   int sock Socket that client is connected to.
     131
     132   More:
     133   +html+ <PRE>
     134   Authors:
     135         ottrey
     136         andrei
     137
     138   +html+ </PRE><DL COMPACT>
     139   +html+ <DT>Online References:
     140   +html+ <DD><UL>
     141   +html+ </UL></DL>
     142
     143   ++++++++++++++++++++++++++++++++++++++*/
     144 void PM_interact(int sock) {
         /* [<][>][^][v][top][bottom][index][help] */
     145   char input[MAX_INPUT_SIZE];
     146   ca_dbSource_t *source_hdl;
     147   int read_result;
     148   int parse_result;
     149
     150
     151   char *hostaddress=NULL;
     152 //  acl_st acl_rip,   acl_eip;
     153
     154   sk_conn_st condat;
     155   nrtm_q_t nrtm_q;
     156   long current_serial;
     157   long oldest_serial;
     158
     159   char *object;
     160   int operation;
     161   char buff[STR_S];
     162
     163   const char *db_host;
     164   int  db_port;
     165   const char *db_name;
     166   const char *db_user;
     167   const char *db_pswd;
     168
     169   GString *gbuff;
     170
     171   SQ_connection_t *sql_connection;
     172
     173   /* make a record for thread accounting */
     174   TA_add(sock, "nrtm_srv");
     175
     176
     177   /* Get the IP of the client */
     178   hostaddress = SK_getpeername(sock);
     179   printf("SK address: %s\n", hostaddress);
     180
     181   /* initialise the connection structure */
     182   memset( &condat, 0, sizeof(sk_conn_st));
     183   /* set the connection data: both rIP and eIP to real IP */
     184   condat.sock = sock;
     185   condat.ip = hostaddress;
     186   SK_getpeerip(sock, &(condat.rIP));
     187   memcpy( &(condat.eIP), &(condat.rIP), sizeof(ip_addr_t));
     188
     189
     190   /* Read input */
     191   read_result = SK_cd_gets(&(condat), input, MAX_INPUT_SIZE);
     192
     193   /* read_result < 0 is an error and connection should be closed */
     194   if (read_result < 0 ) {
     195       /* log the fact, rtc was set */
     196 //not yet, SK_... returns arb number      return;
     197   }
     198
     199   parse_result = parse_request(input, &nrtm_q);
     200   if (parse_result < 0 ) {
     201       fprintf(stderr, "Garbage received: %s\n", input);
     202       /* log the fact and exit */
     203       /* Free the hostaddress */
     204       SK_cd_close(&(condat));
     205       free(hostaddress);
     206       return;
     207   }
     208   if (parse_result == 1 ) {
     209
     210      fprintf(stderr, "-q sources\n");
     211      gbuff=PM_get_nrtm_sources(&(condat.rIP), nrtm_q.source);
     212      SK_cd_puts(&condat, gbuff->str);
     213      /* Free allocated memory  */
     214      g_string_free(gbuff, TRUE);
     215      free(hostaddress);
     216      free(nrtm_q.source);
     217      SK_cd_close(&(condat));
     218      return;
     219   }
     220
     221
     222
     223   source_hdl = ca_get_SourceHandleByName(nrtm_q.source);
     224   /* get database */
     225 /*  db_name=CO_get_database(); */
     226   db_name = ca_get_srcdbname(source_hdl);
     227
     228   /* get database host*/
     229 /*  db_host=CO_get_host();*/
     230   db_host = ca_get_srcdbmachine(source_hdl);
     231   /* get database port*/
     232 /*  db_port=CO_get_database_port();*/
     233   db_port = ca_get_srcdbport(source_hdl);
     234   /* get database user*/
     235 /*  db_user=CO_get_user(); */
     236   db_user = ca_get_srcdbuser(source_hdl);
     237   /* get database password*/
     238 /*  db_pswd=CO_get_password(); */
     239   db_pswd = ca_get_srcdbpassword(source_hdl);
     240
     241   fprintf(stderr, "D: Making SQL connection to %s@%s ...", db_name, db_host);
     242   sql_connection = SQ_get_connection(db_host, db_port,db_name, db_user, db_pswd);
     243   if(!sql_connection) {
     244       fprintf(stderr, "E: ERROR: no SQL connection\n");
     245       return;
     246   }
     247   fprintf(stderr, "OK\n");
     248
     249   /* free copies of the variables */
     250   free(db_host);
     251   free(db_name);
     252   free(db_user);
     253   free(db_pswd);
     254
     255   current_serial=PM_get_current_serial(sql_connection);
     256   oldest_serial=PM_get_oldest_serial(sql_connection);
     257
     258   if((current_serial==-1) || (oldest_serial==-1)) {
     259       fprintf(stderr, "E: ERROR: cannot get serial #\n");
     260       /* Free the hostaddress */
     261       SK_cd_close(&(condat));
     262       free(hostaddress);
     263       return;
     264   }
     265
     266   /* zero indicates that LAST keyword has been used */
     267   if(nrtm_q.last==0)nrtm_q.last=current_serial;
     268
     269
     270   if((nrtm_q.first>nrtm_q.last) || (nrtm_q.first<oldest_serial) || (nrtm_q.last>current_serial)) {
     271       if(nrtm_q.first<oldest_serial) nrtm_q.last=oldest_serial-1;
     272       if(nrtm_q.last>current_serial) nrtm_q.first=current_serial+1;
     273       fprintf(stderr, "E: ERROR: invalid range\n");
     274       /* write error message back to the client */
     275       sprintf(buff, "%%ERROR:4: Invalid range: serial(s) %ld-%ld don't exist\n", nrtm_q.first, nrtm_q.last);
     276       sprintf(buff, "%%ERROR:4: Invalid range: Not within %ld-%ld \n", oldest_serial, current_serial);
     277       SK_cd_puts(&condat, buff);
     278       /* Free the hostaddress */
     279       free(hostaddress);
     280       free(nrtm_q.source);
     281       SK_cd_close(&(condat));
     282       return;
     283   }
     284
     285   current_serial=nrtm_q.first;
     286   /* print banner */
     287
     288   sprintf(buff, "%%START Version:%d %s %ld-%ld\n", nrtm_q.version, nrtm_q.source, nrtm_q.first, nrtm_q.last);
     289   SK_cd_puts(&condat, buff);
     290
     291   /* make a record for thread accounting */
     292   TA_setactivity(buff);
     293
     294 /* now start feeding client with data */
     295   do {
     296
     297     object=PM_get_serial_object(sql_connection, current_serial, &operation);
     298     if (operation == OP_ADD) SK_cd_puts(&condat, "\nADD\n\n");
     299     else SK_cd_puts(&condat, "\nDEL\n\n");
     300
     301     SK_cd_puts(&condat, object);
     302
     303
     304     current_serial++;
     305
     306
     307   } /* do */
     308    while((current_serial<=nrtm_q.last) && (condat.rtc == 0));
     309
     310
     311   sprintf(buff, "\n%%END %s\n\n", nrtm_q.source);
     312   SK_cd_puts(&condat, buff);
     313
     314   /* make a record for thread accounting */
     315   TA_delete();
     316
     317   SK_cd_close(&(condat));
     318   /* Free the hostaddress */
     319   free(hostaddress);
     320   free(nrtm_q.source);
     321
     322
     323
     324 } /* PM_interact() */

/* [<][>][^][v][top][bottom][index][help] */