Browse code

posops: new module with functions working with the position in message buffer

- add/remove content at a specific position in the sip message buffer

Daniel-Constantin Mierla authored on 15/09/2021 12:54:59
Showing 6 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,13 @@
1
+#
2
+# posops module makefile
3
+#
4
+#
5
+# WARNING: do not run this directly, it should be run by the main Makefile
6
+
7
+include ../../Makefile.defs
8
+auto_gen=
9
+NAME=posops.so
10
+LIBS=
11
+
12
+include ../../Makefile.modules
13
+
0 14
new file mode 100644
... ...
@@ -0,0 +1,137 @@
1
+POSOPS Module
2
+
3
+Daniel-Constantin Mierla
4
+
5
+   asipto.com
6
+   <miconda@gmail.com>
7
+
8
+Edited by
9
+
10
+Daniel-Constantin Mierla
11
+
12
+   <miconda@gmail.com>
13
+
14
+   Copyright � 2021 http://www.asipto.com
15
+     __________________________________________________________________
16
+
17
+   Table of Contents
18
+
19
+   1. Admin Guide
20
+
21
+        1. Overview
22
+        2. Dependencies
23
+
24
+              2.1. Kamailio Modules
25
+              2.2. External Libraries or Applications
26
+
27
+        3. Functions
28
+
29
+              3.1. pos_append(idx, val)
30
+              3.2. pos_insert(idx, val)
31
+              3.3. pos_rm(idx, len)
32
+
33
+   List of Examples
34
+
35
+   1.1. pos_append() usage
36
+   1.2. pos_insert() usage
37
+   1.3. pos_rm() usage
38
+
39
+Chapter 1. Admin Guide
40
+
41
+   Table of Contents
42
+
43
+   1. Overview
44
+   2. Dependencies
45
+
46
+        2.1. Kamailio Modules
47
+        2.2. External Libraries or Applications
48
+
49
+   3. Functions
50
+
51
+        3.1. pos_append(idx, val)
52
+        3.2. pos_insert(idx, val)
53
+        3.3. pos_rm(idx, len)
54
+
55
+1. Overview
56
+
57
+   The module exports utility functions to work with position inside the
58
+   SIP message buffer.
59
+
60
+   Among them are function to add or remove content at a specific
61
+   position.
62
+
63
+2. Dependencies
64
+
65
+   2.1. Kamailio Modules
66
+   2.2. External Libraries or Applications
67
+
68
+2.1. Kamailio Modules
69
+
70
+   The following modules must be installed (but not loaded) to use this
71
+   module:
72
+     * none.
73
+
74
+2.2. External Libraries or Applications
75
+
76
+   The following libraries or applications must be installed before
77
+   running Kamailio with this module loaded:
78
+     * none.
79
+
80
+3. Functions
81
+
82
+   3.1. pos_append(idx, val)
83
+   3.2. pos_insert(idx, val)
84
+   3.3. pos_rm(idx, len)
85
+
86
+3.1. pos_append(idx, val)
87
+
88
+   Append the value val after the position idx in the SIP message buffer.
89
+
90
+   The idx can be an integer value or a variable holding an integer. If
91
+   the value is negative, the position is counted from the end of the
92
+   buffer.
93
+
94
+   The val can be a static string or variables.
95
+
96
+   This function can be used from ANY_ROUTE.
97
+
98
+   Example 1.1. pos_append() usage
99
+...
100
+pos_append("100", "kamailio-$si");
101
+...
102
+
103
+3.2. pos_insert(idx, val)
104
+
105
+   Insert the value val at the position idx in the SIP message buffer.
106
+
107
+   The idx can be an integer value or a variable holding an integer. If
108
+   the value is negative, the position is counted from the end of the
109
+   buffer.
110
+
111
+   The val can be a static string or variables.
112
+
113
+   This function can be used from ANY_ROUTE.
114
+
115
+   Example 1.2. pos_insert() usage
116
+...
117
+pos_insert("100", "kamailio-$si");
118
+...
119
+
120
+3.3. pos_rm(idx, len)
121
+
122
+   Remove len characters starting at the position idx in the SIP message
123
+   buffer.
124
+
125
+   The idx can be an integer value or a variable holding an integer. If
126
+   the value is negative, the position is counted from the end of the
127
+   buffer.
128
+
129
+   The idx can be a positive integer value or a variable holding a
130
+   positive integer.
131
+
132
+   This function can be used from ANY_ROUTE.
133
+
134
+   Example 1.3. pos_rm() usage
135
+...
136
+pos_insert("100", "10");
137
+...
0 138
new file mode 100644
... ...
@@ -0,0 +1,4 @@
1
+docs = posops.xml
2
+
3
+docbook_dir = ../../../../doc/docbook
4
+include $(docbook_dir)/Makefile.module
0 5
new file mode 100644
... ...
@@ -0,0 +1,42 @@
1
+<?xml version="1.0" encoding='ISO-8859-1'?>
2
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4
+
5
+<!-- Include general documentation entities -->
6
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
7
+%docentities;
8
+
9
+]>
10
+
11
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
12
+    <bookinfo>
13
+	<title>POSOPS Module</title>
14
+	<productname class="trade">&kamailioname;</productname>
15
+	<authorgroup>
16
+	    <author>
17
+		<firstname>Daniel-Constantin</firstname>
18
+		<surname>Mierla</surname>
19
+		<affiliation><orgname>asipto.com</orgname></affiliation>
20
+		<email>miconda@gmail.com</email>
21
+		<address>
22
+		<otheraddr>
23
+		<ulink url="http://www.asipto.com">http://www.asipto.com</ulink>
24
+		</otheraddr>
25
+		</address>
26
+	    </author>
27
+	    <editor>
28
+		<firstname>Daniel-Constantin</firstname>
29
+		<surname>Mierla</surname>
30
+		<email>miconda@gmail.com</email>
31
+	    </editor>
32
+	</authorgroup>
33
+	<copyright>
34
+	    <year>2021</year>
35
+	    <holder>http://www.asipto.com</holder>
36
+	</copyright>
37
+    </bookinfo>
38
+    <toc></toc>
39
+
40
+    <xi:include href="posops_admin.xml"/>
41
+
42
+</book>
0 43
new file mode 100644
... ...
@@ -0,0 +1,141 @@
1
+<?xml version="1.0" encoding='ISO-8859-1'?>
2
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4
+
5
+<!-- Include general documentation entities -->
6
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
7
+%docentities;
8
+
9
+]>
10
+<!-- Module User's Guide -->
11
+
12
+<chapter>
13
+
14
+	<title>&adminguide;</title>
15
+
16
+	<section>
17
+	<title>Overview</title>
18
+	<para>
19
+		The module exports utility functions to work with position inside the
20
+		SIP message buffer.
21
+	</para>
22
+	<para>
23
+		Among them are function to add or remove content at a specific position.
24
+	</para>
25
+	</section>
26
+	<section>
27
+	<title>Dependencies</title>
28
+	<section>
29
+		<title>&kamailio; Modules</title>
30
+		<para>
31
+		The following modules must be installed (but not loaded) to use this module:
32
+			<itemizedlist>
33
+			<listitem>
34
+			<para>
35
+				<emphasis>none</emphasis>.
36
+			</para>
37
+			</listitem>
38
+			</itemizedlist>
39
+		</para>
40
+	</section>
41
+	<section>
42
+		<title>External Libraries or Applications</title>
43
+		<para>
44
+		The following libraries or applications must be installed before running
45
+		&kamailio; with this module loaded:
46
+			<itemizedlist>
47
+			<listitem>
48
+			<para>
49
+				<emphasis>none</emphasis>.
50
+			</para>
51
+			</listitem>
52
+			</itemizedlist>
53
+		</para>
54
+	</section>
55
+	</section>
56
+
57
+	<section>
58
+	<title>Functions</title>
59
+		<section id="posops.f.pos_append">
60
+			<title>
61
+				<function moreinfo="none">pos_append(idx, val)</function>
62
+			</title>
63
+			<para>
64
+			Append the value val after the position idx in the SIP message buffer.
65
+			</para>
66
+			<para>
67
+			The idx can be an integer value or a variable holding an integer. If
68
+			the value is negative, the position is counted from the end of the buffer.
69
+			</para>
70
+			<para>
71
+			The val can be a static string or variables.
72
+			</para>
73
+			<para>
74
+			This function can be used from ANY_ROUTE.
75
+			</para>
76
+			<example>
77
+				<title><function>pos_append()</function> usage</title>
78
+				<programlisting format="linespecific">
79
+...
80
+pos_append("100", "kamailio-$si");
81
+...
82
+				</programlisting>
83
+			</example>
84
+		</section>
85
+		<section id="posops.f.pos_insert">
86
+			<title>
87
+				<function moreinfo="none">pos_insert(idx, val)</function>
88
+			</title>
89
+			<para>
90
+			Insert the value val at the position idx in the SIP message buffer.
91
+			</para>
92
+			<para>
93
+			The idx can be an integer value or a variable holding an integer. If
94
+			the value is negative, the position is counted from the end of the buffer.
95
+			</para>
96
+			<para>
97
+			The val can be a static string or variables.
98
+			</para>
99
+			<para>
100
+			This function can be used from ANY_ROUTE.
101
+			</para>
102
+			<example>
103
+				<title><function>pos_insert()</function> usage</title>
104
+				<programlisting format="linespecific">
105
+...
106
+pos_insert("100", "kamailio-$si");
107
+...
108
+				</programlisting>
109
+			</example>
110
+		</section>
111
+		<section id="posops.f.pos_rm">
112
+			<title>
113
+				<function moreinfo="none">pos_rm(idx, len)</function>
114
+			</title>
115
+			<para>
116
+			Remove len characters starting at the position idx in the SIP message buffer.
117
+			</para>
118
+			<para>
119
+			The idx can be an integer value or a variable holding an integer. If
120
+			the value is negative, the position is counted from the end of the buffer.
121
+			</para>
122
+			<para>
123
+			The idx can be a positive integer value or a variable holding a positive
124
+			integer.
125
+			</para>
126
+			<para>
127
+			This function can be used from ANY_ROUTE.
128
+			</para>
129
+			<example>
130
+				<title><function>pos_rm()</function> usage</title>
131
+				<programlisting format="linespecific">
132
+...
133
+pos_insert("100", "10");
134
+...
135
+				</programlisting>
136
+			</example>
137
+		</section>
138
+	</section>
139
+
140
+</chapter>
141
+
0 142
new file mode 100644
... ...
@@ -0,0 +1,305 @@
1
+/**
2
+ * Copyright (C) 2021 Daniel-Constantin Mierla (asipto.com)
3
+ *
4
+ * This file is part of Kamailio, a free SIP server.
5
+ *
6
+ * This file 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
+ *
12
+ * This file is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
+ *
21
+ */
22
+
23
+#include <stdio.h>
24
+#include <unistd.h>
25
+#include <stdlib.h>
26
+#include <string.h>
27
+
28
+#include "../../core/sr_module.h"
29
+#include "../../core/dprint.h"
30
+#include "../../core/mod_fix.h"
31
+#include "../../core/data_lump.h"
32
+#include "../../core/kemi.h"
33
+
34
+
35
+MODULE_VERSION
36
+
37
+static int mod_init(void);
38
+static int child_init(int);
39
+static void mod_destroy(void);
40
+
41
+static int w_posops_pos_append(sip_msg_t* msg, char* p1idx, char* p2val);
42
+static int w_posops_pos_insert(sip_msg_t* msg, char* p1idx, char* p2val);
43
+static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len);
44
+
45
+typedef struct posops_data {
46
+	int ret;
47
+	int idx;
48
+} pospos_data_t;
49
+
50
+/* clang-format off */
51
+static cmd_export_t cmds[]={
52
+	{"pos_append", (cmd_function)w_posops_pos_append, 2, fixup_igp_spve,
53
+		fixup_free_igp_spve, ANY_ROUTE},
54
+	{"pos_insert", (cmd_function)w_posops_pos_insert, 2, fixup_igp_spve,
55
+		fixup_free_igp_spve, ANY_ROUTE},
56
+	{"pos_rm", (cmd_function)w_posops_pos_rm, 2, fixup_igp_igp,
57
+		fixup_free_igp_igp, ANY_ROUTE},
58
+
59
+	{0, 0, 0, 0, 0, 0}
60
+};
61
+
62
+static param_export_t params[]={
63
+
64
+	{0, 0, 0}
65
+};
66
+
67
+struct module_exports exports = {
68
+	"posops",
69
+	DEFAULT_DLFLAGS, /* dlopen flags */
70
+	cmds,
71
+	params,
72
+	0,              /* exported RPC methods */
73
+	0,              /* exported pseudo-variables */
74
+	0,              /* response function */
75
+	mod_init,       /* module initialization function */
76
+	child_init,     /* per child init function */
77
+	mod_destroy    	/* destroy function */
78
+};
79
+/* clang-format on */
80
+
81
+
82
+/**
83
+ * init module function
84
+ */
85
+static int mod_init(void)
86
+{
87
+	return 0;
88
+}
89
+
90
+/**
91
+ * @brief Initialize async module children
92
+ */
93
+static int child_init(int rank)
94
+{
95
+	return 0;
96
+}
97
+
98
+/**
99
+ * destroy module function
100
+ */
101
+static void mod_destroy(void)
102
+{
103
+	return;
104
+}
105
+
106
+/**
107
+ *
108
+ */
109
+static int ki_posops_pos_append(sip_msg_t *msg, int idx, str *val)
110
+{
111
+	int offset;
112
+	sr_lump_t *anchor = NULL;
113
+
114
+	if(val==NULL || val->s==NULL || val->len<=0) {
115
+		LM_ERR("invalid val parameter\n");
116
+		return -1;
117
+	}
118
+
119
+	if(idx<0) {
120
+		offset = msg->len + idx + 1;
121
+	} else {
122
+		offset = idx;
123
+	}
124
+	if(offset>msg->len) {
125
+		LM_ERR("offset invalid: %d (msg-len: %d)\n", offset, msg->len);
126
+		return -1;
127
+	}
128
+
129
+	anchor = anchor_lump(msg, offset, 0, 0);
130
+	if (insert_new_lump_after(anchor, val->s, val->len, 0) == 0) {
131
+		LM_ERR("unable to add lump\n");
132
+		return -1;
133
+	}
134
+
135
+	return 1;
136
+}
137
+
138
+/**
139
+ *
140
+ */
141
+static int w_posops_pos_append(sip_msg_t* msg, char* p1idx, char* p2val)
142
+{
143
+	int idx = 0;
144
+	str val = STR_NULL;
145
+
146
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
147
+		LM_ERR("unable to get idx parameter\n");
148
+		return -1;
149
+	}
150
+
151
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
152
+		LM_ERR("unable to get val parameter\n");
153
+		return -1;
154
+	}
155
+
156
+	return ki_posops_pos_append(msg, idx, &val);
157
+}
158
+
159
+/**
160
+ *
161
+ */
162
+static int ki_posops_pos_insert(sip_msg_t *msg, int idx, str *val)
163
+{
164
+	int offset;
165
+	sr_lump_t *anchor = NULL;
166
+
167
+	if(val==NULL || val->s==NULL || val->len<=0) {
168
+		LM_ERR("invalid val parameter\n");
169
+		return -1;
170
+	}
171
+
172
+	if(idx<0) {
173
+		offset = msg->len + idx + 1;
174
+	} else {
175
+		offset = idx;
176
+	}
177
+	if(offset>msg->len) {
178
+		LM_ERR("offset invalid: %d (msg-len: %d)\n", offset, msg->len);
179
+		return -1;
180
+	}
181
+
182
+	anchor = anchor_lump(msg, offset, 0, 0);
183
+	if (insert_new_lump_before(anchor, val->s, val->len, 0) == 0) {
184
+		LM_ERR("unable to add lump\n");
185
+		return -1;
186
+	}
187
+
188
+	return 1;
189
+}
190
+
191
+/**
192
+ *
193
+ */
194
+static int w_posops_pos_insert(sip_msg_t* msg, char* p1idx, char* p2val)
195
+{
196
+	int idx = 0;
197
+	str val = STR_NULL;
198
+
199
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
200
+		LM_ERR("unable to get idx parameter\n");
201
+		return -1;
202
+	}
203
+
204
+	if(fixup_get_svalue(msg, (gparam_t*)p2val, &val)!=0) {
205
+		LM_ERR("unable to get val parameter\n");
206
+		return -1;
207
+	}
208
+
209
+	return ki_posops_pos_insert(msg, idx, &val);
210
+}
211
+
212
+
213
+/**
214
+ *
215
+ */
216
+static int ki_posops_pos_rm(sip_msg_t *msg, int idx, int len)
217
+{
218
+	int offset;
219
+	sr_lump_t *anchor = NULL;
220
+
221
+	if(len<=0) {
222
+		LM_ERR("length invalid: %d (msg-len: %d)\n", len, msg->len);
223
+		return -1;
224
+	}
225
+	if(idx<0) {
226
+		offset = msg->len + idx + 1;
227
+	} else {
228
+		offset = idx;
229
+	}
230
+	if(offset>msg->len) {
231
+		LM_ERR("offset invalid: %d (msg-len: %d)\n", offset, msg->len);
232
+		return -1;
233
+	}
234
+	if(offset==msg->len) {
235
+		LM_WARN("offset at the end of message: %d (msg-len: %d)\n",
236
+				offset, msg->len);
237
+		return 1;
238
+	}
239
+	if(offset + len > msg->len) {
240
+		LM_WARN("offset + len over the end of message: %d + %d (msg-len: %d)\n",
241
+				offset, len, msg->len);
242
+		return -1;
243
+	}
244
+	anchor=del_lump(msg, offset, len, 0);
245
+	if (anchor==0) {
246
+		LM_ERR("cannot remove - offset: %d - len: %d - msg-len: %d\n",
247
+				offset, len, msg->len);
248
+		return -1;
249
+	}
250
+	return 1;
251
+}
252
+
253
+/**
254
+ *
255
+ */
256
+static int w_posops_pos_rm(sip_msg_t* msg, char* p1idx, char* p2len)
257
+{
258
+	int idx = 0;
259
+	int len = 0;
260
+
261
+	if(fixup_get_ivalue(msg, (gparam_t*)p1idx, &idx)!=0) {
262
+		LM_ERR("unable to get idx parameter\n");
263
+		return -1;
264
+	}
265
+	if(fixup_get_ivalue(msg, (gparam_t*)p2len, &len)!=0) {
266
+		LM_ERR("unable to get len parameter\n");
267
+		return -1;
268
+	}
269
+
270
+	return ki_posops_pos_rm(msg, idx, len);
271
+}
272
+
273
+/**
274
+ *
275
+ */
276
+/* clang-format off */
277
+static sr_kemi_t sr_kemi_posops_exports[] = {
278
+	{ str_init("posops"), str_init("pos_append"),
279
+		SR_KEMIP_INT, ki_posops_pos_append,
280
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
281
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
282
+	},
283
+	{ str_init("posops"), str_init("pos_insert"),
284
+		SR_KEMIP_INT, ki_posops_pos_insert,
285
+		{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
286
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
287
+	},
288
+	{ str_init("posops"), str_init("pos_rm"),
289
+		SR_KEMIP_INT, ki_posops_pos_rm,
290
+		{ SR_KEMIP_INT, SR_KEMIP_INT, SR_KEMIP_NONE,
291
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
292
+	},
293
+
294
+	{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
295
+};
296
+/* clang-format on */
297
+
298
+/**
299
+ *
300
+ */
301
+int mod_register(char *path, int *dlflags, void *p1, void *p2)
302
+{
303
+	sr_kemi_modules_add(sr_kemi_posops_exports);
304
+	return 0;
305
+}