kemix: fix export of gete_fhost()
[sip-router] / src / modules / kemix / kemix_mod.c
1 /**
2  * Copyright (C) 2019 Daniel-Constantin Mierla (asipto.com)
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "../../core/sr_module.h"
28 #include "../../core/dprint.h"
29 #include "../../core/kemi.h"
30 #include "../../core/parser/parse_uri.h"
31 #include "../../core/parser/parse_from.h"
32 #include "../../core/parser/parse_to.h"
33 #include "../../core/parser/digest/digest.h"
34
35 MODULE_VERSION
36
37 struct module_exports exports = {
38         "kemix",         /* module name */
39         DEFAULT_DLFLAGS, /* dlopen flags */
40         0,               /* cmd (cfg function) exports */
41         0,               /* param exports */
42         0,               /* RPC method exports */
43         0,               /* pseudo-variables exports */
44         0,               /* response handling function */
45         0,               /* module init function */
46         0,               /* per-child init function */
47         0                /* module destroy function */
48 };
49
50
51 /**
52  *
53  */
54 static sr_kemi_xval_t _sr_kemi_kx_xval = {0};
55
56 /**
57  *
58  */
59 static sr_kemi_xval_t* ki_kx_get_ruri(sip_msg_t *msg)
60 {
61         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
62
63         if(msg==NULL) {
64                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
65                 return &_sr_kemi_kx_xval;
66         }
67
68         if(msg->first_line.type == SIP_REPLY) {
69                 /* REPLY doesnt have a ruri */
70                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
71                 return &_sr_kemi_kx_xval;
72         }
73
74         if(msg->parsed_uri_ok==0 /* R-URI not parsed*/ && parse_sip_msg_uri(msg)<0) {
75                 LM_ERR("failed to parse the R-URI\n");
76                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
77                 return &_sr_kemi_kx_xval;
78         }
79
80         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
81         if (msg->new_uri.s!=NULL) {
82                 _sr_kemi_kx_xval.v.s = msg->new_uri;
83         } else {
84                 _sr_kemi_kx_xval.v.s = msg->first_line.u.request.uri;
85         }
86         return &_sr_kemi_kx_xval;
87 }
88
89 /**
90  *
91  */
92 static sr_kemi_xval_t* ki_kx_get_ouri(sip_msg_t *msg)
93 {
94         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
95
96         if(msg==NULL) {
97                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
98                 return &_sr_kemi_kx_xval;
99         }
100
101         if(msg->first_line.type == SIP_REPLY) {
102                 /* REPLY doesnt have a ruri */
103                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
104                 return &_sr_kemi_kx_xval;
105         }
106
107         if(msg->parsed_uri_ok==0 /* R-URI not parsed*/ && parse_sip_msg_uri(msg)<0) {
108                 LM_ERR("failed to parse the R-URI\n");
109                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
110                 return &_sr_kemi_kx_xval;
111         }
112
113         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
114         _sr_kemi_kx_xval.v.s = msg->first_line.u.request.uri;
115         return &_sr_kemi_kx_xval;
116 }
117
118 /**
119  *
120  */
121 static sr_kemi_xval_t* ki_kx_get_furi(sip_msg_t *msg)
122 {
123         to_body_t *xto = NULL;
124
125         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
126
127         if(msg==NULL) {
128                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
129                 return &_sr_kemi_kx_xval;
130         }
131         if(parse_from_header(msg)<0) {
132                 LM_ERR("cannot parse From header\n");
133                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
134                 return &_sr_kemi_kx_xval;
135         }
136         if(msg->from==NULL || get_from(msg)==NULL) {
137                 LM_DBG("no From header\n");
138                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
139                 return &_sr_kemi_kx_xval;
140         }
141
142         xto = get_from(msg);
143         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
144         _sr_kemi_kx_xval.v.s = xto->uri;
145         return &_sr_kemi_kx_xval;
146 }
147
148 /**
149  *
150  */
151 static sr_kemi_xval_t* ki_kx_get_turi(sip_msg_t *msg)
152 {
153         to_body_t *xto = NULL;
154
155         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
156
157         if(msg==NULL) {
158                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
159                 return &_sr_kemi_kx_xval;
160         }
161         if(parse_to_header(msg)<0) {
162                 LM_ERR("cannot parse To header\n");
163                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
164                 return &_sr_kemi_kx_xval;
165         }
166         if(msg->to==NULL || get_to(msg)==NULL) {
167                 LM_DBG("no To header\n");
168                 sr_kemi_xval_null(&_sr_kemi_kx_xval, 0);
169                 return &_sr_kemi_kx_xval;
170         }
171
172         xto = get_to(msg);
173         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
174         _sr_kemi_kx_xval.v.s = xto->uri;
175         return &_sr_kemi_kx_xval;
176 }
177
178 /**
179  *
180  */
181 static sr_kemi_xval_t* ki_kx_get_xuri_attr(sip_msg_t *msg, sip_uri_t *puri,
182                 int iattr, int xmode)
183 {
184         if(iattr==1) {
185                 /* username */
186                 if(puri->user.s==NULL || puri->user.len<=0) {
187                         sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
188                         return &_sr_kemi_kx_xval;
189                 }
190                 _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
191                 _sr_kemi_kx_xval.v.s = puri->user;
192                 return &_sr_kemi_kx_xval;
193         } else if(iattr==2) {
194                 /* domain */
195                 if(puri->host.s==NULL || puri->host.len<=0) {
196                         sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
197                         return &_sr_kemi_kx_xval;
198                 }
199                 _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
200                 _sr_kemi_kx_xval.v.s = puri->host;
201                 return &_sr_kemi_kx_xval;
202         }
203         LM_ERR("unknown attribute id: %d\n", iattr);
204         sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
205         return &_sr_kemi_kx_xval;
206 }
207
208 /**
209  *
210  */
211 static sr_kemi_xval_t* ki_kx_get_ruri_attr(sip_msg_t *msg, int iattr, int xmode)
212 {
213         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
214
215         if(msg==NULL || msg->first_line.type == SIP_REPLY) {
216                 sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
217                 return &_sr_kemi_kx_xval;
218         }
219
220         if(msg->parsed_uri_ok==0 /* R-URI not parsed*/ && parse_sip_msg_uri(msg)<0) {
221                 LM_ERR("failed to parse the R-URI\n");
222                 sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
223                 return &_sr_kemi_kx_xval;
224         }
225         return ki_kx_get_xuri_attr(msg, &(msg->parsed_uri), iattr, xmode);
226 }
227
228 /**
229  *
230  */
231 static sr_kemi_xval_t* ki_kx_get_ruser(sip_msg_t *msg)
232 {
233         return ki_kx_get_ruri_attr(msg, 1, SR_KEMI_XVAL_NULL_NONE);
234 }
235
236 /**
237  *
238  */
239 static sr_kemi_xval_t* ki_kx_getw_ruser(sip_msg_t *msg)
240 {
241         return ki_kx_get_ruri_attr(msg, 1, SR_KEMI_XVAL_NULL_PRINT);
242 }
243
244 /**
245  *
246  */
247 static sr_kemi_xval_t* ki_kx_gete_ruser(sip_msg_t *msg)
248 {
249         return ki_kx_get_ruri_attr(msg, 1, SR_KEMI_XVAL_NULL_EMPTY);
250 }
251
252 /**
253  *
254  */
255 static sr_kemi_xval_t* ki_kx_get_rhost(sip_msg_t *msg)
256 {
257         return ki_kx_get_ruri_attr(msg, 2, SR_KEMI_XVAL_NULL_NONE);
258 }
259
260 /**
261  *
262  */
263 static sr_kemi_xval_t* ki_kx_getw_rhost(sip_msg_t *msg)
264 {
265         return ki_kx_get_ruri_attr(msg, 2, SR_KEMI_XVAL_NULL_PRINT);
266 }
267
268 /**
269  *
270  */
271 static sr_kemi_xval_t* ki_kx_gete_rhost(sip_msg_t *msg)
272 {
273         return ki_kx_get_ruri_attr(msg, 2, SR_KEMI_XVAL_NULL_EMPTY);
274 }
275
276 /**
277  *
278  */
279 static sr_kemi_xval_t* ki_kx_get_furi_attr(sip_msg_t *msg, int iattr, int xmode)
280 {
281         sip_uri_t *uri;
282
283         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
284         uri=parse_from_uri(msg);
285         if(uri==NULL) {
286                 sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
287                 return &_sr_kemi_kx_xval;
288         }
289
290         return ki_kx_get_xuri_attr(msg, uri, iattr, xmode);
291 }
292
293 /**
294  *
295  */
296 static sr_kemi_xval_t* ki_kx_get_fuser(sip_msg_t *msg)
297 {
298         return ki_kx_get_furi_attr(msg, 1, SR_KEMI_XVAL_NULL_NONE);
299 }
300
301 /**
302  *
303  */
304 static sr_kemi_xval_t* ki_kx_getw_fuser(sip_msg_t *msg)
305 {
306         return ki_kx_get_furi_attr(msg, 1, SR_KEMI_XVAL_NULL_PRINT);
307 }
308
309 /**
310  *
311  */
312 static sr_kemi_xval_t* ki_kx_gete_fuser(sip_msg_t *msg)
313 {
314         return ki_kx_get_furi_attr(msg, 1, SR_KEMI_XVAL_NULL_EMPTY);
315 }
316
317 /**
318  *
319  */
320 static sr_kemi_xval_t* ki_kx_get_fhost(sip_msg_t *msg)
321 {
322         return ki_kx_get_furi_attr(msg, 2, SR_KEMI_XVAL_NULL_NONE);
323 }
324
325 /**
326  *
327  */
328 static sr_kemi_xval_t* ki_kx_getw_fhost(sip_msg_t *msg)
329 {
330         return ki_kx_get_furi_attr(msg, 2, SR_KEMI_XVAL_NULL_PRINT);
331 }
332
333 /**
334  *
335  */
336 static sr_kemi_xval_t* ki_kx_gete_fhost(sip_msg_t *msg)
337 {
338         return ki_kx_get_furi_attr(msg, 2, SR_KEMI_XVAL_NULL_EMPTY);
339 }
340
341 /**
342  *
343  */
344 static sr_kemi_xval_t* ki_kx_get_ua_mode(sip_msg_t *msg, int rmode)
345 {
346         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
347         if(msg==NULL) {
348                 sr_kemi_xval_null(&_sr_kemi_kx_xval, rmode);
349                 return &_sr_kemi_kx_xval;
350         }
351         if(msg->user_agent==NULL && ((parse_headers(msg, HDR_USERAGENT_F, 0)==-1)
352                         || (msg->user_agent==NULL))) {
353                 sr_kemi_xval_null(&_sr_kemi_kx_xval, rmode);
354                 return &_sr_kemi_kx_xval;
355         }
356
357         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
358         _sr_kemi_kx_xval.v.s = msg->user_agent->body;
359         return &_sr_kemi_kx_xval;
360 }
361
362 /**
363  *
364  */
365 static sr_kemi_xval_t* ki_kx_get_ua(sip_msg_t *msg)
366 {
367         return ki_kx_get_ua_mode(msg, SR_KEMI_XVAL_NULL_NONE);
368 }
369
370 /**
371  *
372  */
373 static sr_kemi_xval_t* ki_kx_gete_ua(sip_msg_t *msg)
374 {
375         return ki_kx_get_ua_mode(msg, SR_KEMI_XVAL_NULL_EMPTY);
376 }
377
378 /**
379  *
380  */
381 static sr_kemi_xval_t* ki_kx_getw_ua(sip_msg_t *msg)
382 {
383         return ki_kx_get_ua_mode(msg, SR_KEMI_XVAL_NULL_PRINT);
384 }
385
386 /**
387  *
388  */
389 static sr_kemi_xval_t* ki_kx_get_srcip(sip_msg_t *msg)
390 {
391         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
392         if(msg==NULL) {
393                 sr_kemi_xval_null(&_sr_kemi_kx_xval, SR_KEMI_XVAL_NULL_NONE);
394                 return &_sr_kemi_kx_xval;
395         }
396
397         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
398         _sr_kemi_kx_xval.v.s.s = ip_addr2a(&msg->rcv.src_ip);
399         _sr_kemi_kx_xval.v.s.len = strlen(_sr_kemi_kx_xval.v.s.s);
400         return &_sr_kemi_kx_xval;
401 }
402
403 /**
404  *
405  */
406 static sr_kemi_xval_t* ki_kx_get_srcport(sip_msg_t *msg)
407 {
408         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
409         if(msg==NULL) {
410                 _sr_kemi_kx_xval.vtype = SR_KEMIP_INT;
411                 _sr_kemi_kx_xval.v.n = 0;
412                 return &_sr_kemi_kx_xval;
413         }
414
415         _sr_kemi_kx_xval.vtype = SR_KEMIP_INT;
416         _sr_kemi_kx_xval.v.n = (int)msg->rcv.src_port;
417         return &_sr_kemi_kx_xval;
418 }
419
420 /**
421  *
422  */
423 static sr_kemi_xval_t* ki_kx_get_rcvip(sip_msg_t *msg)
424 {
425         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
426         if(msg==NULL || msg->rcv.bind_address==NULL
427                         || msg->rcv.bind_address->address_str.s==NULL) {
428                 sr_kemi_xval_null(&_sr_kemi_kx_xval, SR_KEMI_XVAL_NULL_NONE);
429                 return &_sr_kemi_kx_xval;
430         }
431
432         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
433         _sr_kemi_kx_xval.v.s = msg->rcv.bind_address->address_str;
434         return &_sr_kemi_kx_xval;
435 }
436
437 /**
438  *
439  */
440 static sr_kemi_xval_t* ki_kx_get_rcvport(sip_msg_t *msg)
441 {
442         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
443         if(msg==NULL || msg->rcv.bind_address==NULL) {
444                 _sr_kemi_kx_xval.vtype = SR_KEMIP_INT;
445                 _sr_kemi_kx_xval.v.n = 0;
446                 return &_sr_kemi_kx_xval;
447         }
448
449         _sr_kemi_kx_xval.vtype = SR_KEMIP_INT;
450         _sr_kemi_kx_xval.v.n = (int)msg->rcv.bind_address->port_no;
451         return &_sr_kemi_kx_xval;
452 }
453
454 /**
455  *
456  */
457 static sr_kemi_xval_t* ki_kx_get_proto(sip_msg_t *msg)
458 {
459         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
460         if(msg==NULL) {
461                 sr_kemi_xval_null(&_sr_kemi_kx_xval, SR_KEMI_XVAL_NULL_EMPTY);
462                 return &_sr_kemi_kx_xval;
463         }
464
465         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
466         if(get_valid_proto_string(msg->rcv.proto, 0, 0, &_sr_kemi_kx_xval.v.s)<0) {
467                 sr_kemi_xval_null(&_sr_kemi_kx_xval, SR_KEMI_XVAL_NULL_EMPTY);
468         }
469
470         return &_sr_kemi_kx_xval;
471 }
472
473 /**
474  *
475  */
476 static int ki_kx_get_protoid(sip_msg_t *msg)
477 {
478         if(msg==NULL) {
479                 return -1;
480         }
481
482         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
483         return (int)msg->rcv.proto;
484 }
485
486 /**
487  *
488  */
489 static sr_kemi_xval_t* ki_kx_get_auth_attr(sip_msg_t *msg, int iattr, int xmode)
490 {
491         hdr_field_t *hdr;
492
493         memset(&_sr_kemi_kx_xval, 0, sizeof(sr_kemi_xval_t));
494         if(msg==NULL) {
495                 sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
496                 return &_sr_kemi_kx_xval;
497         }
498
499         if ((msg->REQ_METHOD == METHOD_ACK) ||
500                         (msg->REQ_METHOD == METHOD_CANCEL)) {
501                 LM_DBG("no [Proxy-]Authorization header\n");
502                 sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
503                 return &_sr_kemi_kx_xval;
504         }
505
506         if ((parse_headers(msg, HDR_PROXYAUTH_F|HDR_AUTHORIZATION_F, 0)==-1)
507                         || (msg->proxy_auth==0 && msg->authorization==0)) {
508                 LM_DBG("no [Proxy-]Authorization header\n");
509                 sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
510                 return &_sr_kemi_kx_xval;
511         }
512
513         hdr = (msg->proxy_auth==0)?msg->authorization:msg->proxy_auth;
514
515         if(parse_credentials(hdr)!=0) {
516                 LM_ERR("failed to parse credentials\n");
517                 sr_kemi_xval_null(&_sr_kemi_kx_xval, xmode);
518                 return &_sr_kemi_kx_xval;
519         }
520         switch(iattr) {
521                 case 1:
522                         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
523                         _sr_kemi_kx_xval.v.s = ((auth_body_t*)(hdr->parsed))->digest.username.user;
524                         return &_sr_kemi_kx_xval;
525
526                 break;
527                 default:
528                         _sr_kemi_kx_xval.vtype = SR_KEMIP_STR;
529                         _sr_kemi_kx_xval.v.s = ((auth_body_t*)(hdr->parsed))->digest.username.whole;
530                         return &_sr_kemi_kx_xval;
531         }
532 }
533
534 /**
535  *
536  */
537 static sr_kemi_xval_t* ki_kx_get_au(sip_msg_t *msg)
538 {
539         return ki_kx_get_auth_attr(msg, 1, SR_KEMI_XVAL_NULL_NONE);
540 }
541
542 /**
543  *
544  */
545 static sr_kemi_xval_t* ki_kx_getw_au(sip_msg_t *msg)
546 {
547         return ki_kx_get_auth_attr(msg, 1, SR_KEMI_XVAL_NULL_PRINT);
548 }
549
550 /**
551  *
552  */
553 static sr_kemi_xval_t* ki_kx_gete_au(sip_msg_t *msg)
554 {
555         return ki_kx_get_auth_attr(msg, 1, SR_KEMI_XVAL_NULL_EMPTY);
556 }
557
558 /**
559  *
560  */
561 /* clang-format off */
562 static sr_kemi_t sr_kemi_kx_exports[] = {
563         { str_init("kx"), str_init("get_ruri"),
564                 SR_KEMIP_XVAL, ki_kx_get_ruri,
565                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
566                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
567         },
568         { str_init("kx"), str_init("get_ruser"),
569                 SR_KEMIP_XVAL, ki_kx_get_ruser,
570                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
571                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
572         },
573         { str_init("kx"), str_init("getw_ruser"),
574                 SR_KEMIP_XVAL, ki_kx_getw_ruser,
575                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
576                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
577         },
578         { str_init("kx"), str_init("gete_ruser"),
579                 SR_KEMIP_XVAL, ki_kx_gete_ruser,
580                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
581                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
582         },
583         { str_init("kx"), str_init("get_rhost"),
584                 SR_KEMIP_XVAL, ki_kx_get_rhost,
585                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
586                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
587         },
588         { str_init("kx"), str_init("getw_rhost"),
589                 SR_KEMIP_XVAL, ki_kx_getw_rhost,
590                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
591                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
592         },
593         { str_init("kx"), str_init("gete_rhost"),
594                 SR_KEMIP_XVAL, ki_kx_gete_rhost,
595                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
596                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
597         },
598         { str_init("kx"), str_init("get_ouri"),
599                 SR_KEMIP_XVAL, ki_kx_get_ouri,
600                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
601                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
602         },
603         { str_init("kx"), str_init("get_furi"),
604                 SR_KEMIP_XVAL, ki_kx_get_furi,
605                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
606                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
607         },
608         { str_init("kx"), str_init("get_fuser"),
609                 SR_KEMIP_XVAL, ki_kx_get_fuser,
610                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
611                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
612         },
613         { str_init("kx"), str_init("getw_fuser"),
614                 SR_KEMIP_XVAL, ki_kx_getw_fuser,
615                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
616                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
617         },
618         { str_init("kx"), str_init("gete_fuser"),
619                 SR_KEMIP_XVAL, ki_kx_gete_fuser,
620                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
621                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
622         },
623         { str_init("kx"), str_init("get_fhost"),
624                 SR_KEMIP_XVAL, ki_kx_get_fhost,
625                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
626                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
627         },
628         { str_init("kx"), str_init("getw_fhost"),
629                 SR_KEMIP_XVAL, ki_kx_getw_fhost,
630                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
631                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
632         },
633         { str_init("kx"), str_init("gete_fhost"),
634                 SR_KEMIP_XVAL, ki_kx_gete_fhost,
635                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
636                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
637         },
638         { str_init("kx"), str_init("get_turi"),
639                 SR_KEMIP_XVAL, ki_kx_get_turi,
640                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
641                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
642         },
643         { str_init("kx"), str_init("get_ua"),
644                 SR_KEMIP_XVAL, ki_kx_get_ua,
645                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
646                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
647         },
648         { str_init("kx"), str_init("gete_ua"),
649                 SR_KEMIP_XVAL, ki_kx_gete_ua,
650                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
651                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
652         },
653         { str_init("kx"), str_init("getw_ua"),
654                 SR_KEMIP_XVAL, ki_kx_getw_ua,
655                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
656                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
657         },
658         { str_init("kx"), str_init("get_srcip"),
659                 SR_KEMIP_XVAL, ki_kx_get_srcip,
660                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
661                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
662         },
663         { str_init("kx"), str_init("get_srcport"),
664                 SR_KEMIP_XVAL, ki_kx_get_srcport,
665                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
666                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
667         },
668         { str_init("kx"), str_init("get_rcvip"),
669                 SR_KEMIP_XVAL, ki_kx_get_rcvip,
670                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
671                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
672         },
673         { str_init("kx"), str_init("get_rcvport"),
674                 SR_KEMIP_XVAL, ki_kx_get_rcvport,
675                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
676                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
677         },
678         { str_init("kx"), str_init("get_proto"),
679                 SR_KEMIP_XVAL, ki_kx_get_proto,
680                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
681                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
682         },
683         { str_init("kx"), str_init("get_protoid"),
684                 SR_KEMIP_INT, ki_kx_get_protoid,
685                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
686                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
687         },
688         { str_init("kx"), str_init("get_au"),
689                 SR_KEMIP_XVAL, ki_kx_get_au,
690                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
691                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
692         },
693         { str_init("kx"), str_init("getw_au"),
694                 SR_KEMIP_XVAL, ki_kx_getw_au,
695                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
696                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
697         },
698         { str_init("kx"), str_init("gete_au"),
699                 SR_KEMIP_XVAL, ki_kx_gete_au,
700                 { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE,
701                         SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
702         },
703
704         { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
705 };
706
707 /**
708  *
709  */
710 int mod_register(char *path, int *dlflags, void *p1, void *p2)
711 {
712         sr_kemi_modules_add(sr_kemi_kx_exports);
713         return 0;
714 }