modules/pm/protocol_mirror.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- parse_request
- 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() */