Browse code

add files with funcs for converting sip_msg to buf

Bogdan-Andrei Iancu authored on 28/11/2001 23:26:56
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,401 @@
0
+#include "msg_translator.h"
1
+#include "mem.h"
2
+#include "dprint.h"
3
+#include "config.h"
4
+#include <netdb.h>
5
+
6
+
7
+#define MAX_VIA_LINE_SIZE      240
8
+#define MAX_RECEIVED_SIZE  57
9
+
10
+
11
+
12
+
13
+/* faster than inet_ntoa */
14
+static inline char* q_inet_itoa(unsigned long ip)
15
+{
16
+	static char q_inet_itoa_buf[16]; /* 123.567.901.345\0 */
17
+	unsigned char* p;
18
+	unsigned char a,b,c;  /* abc.def.ghi.jkl */
19
+	int offset;
20
+	int r;
21
+	p=(unsigned char*)&ip;
22
+
23
+	offset=0;
24
+	/* unrolled loops (faster)*/
25
+	for(r=0;r<3;r++){
26
+		a=p[r]/100;
27
+		c=p[r]%10;
28
+		b=p[r]%100/10;
29
+		if (a){
30
+			q_inet_itoa_buf[offset]=a+'0';
31
+			q_inet_itoa_buf[offset+1]=b+'0';
32
+			q_inet_itoa_buf[offset+2]=c+'0';
33
+			q_inet_itoa_buf[offset+3]='.';
34
+			offset+=4;
35
+		}else if (b){
36
+			q_inet_itoa_buf[offset]=b+'0';
37
+			q_inet_itoa_buf[offset+1]=c+'0';
38
+			q_inet_itoa_buf[offset+2]='.';
39
+			offset+=3;
40
+		}else{
41
+			q_inet_itoa_buf[offset]=c+'0';
42
+			q_inet_itoa_buf[offset+1]='.';
43
+			offset+=2;
44
+		}
45
+	}
46
+	/* last number */
47
+	a=p[r]/100;
48
+	c=p[r]%10;
49
+	b=p[r]%100/10;
50
+	if (a){
51
+		q_inet_itoa_buf[offset]=a+'0';
52
+		q_inet_itoa_buf[offset+1]=b+'0';
53
+		q_inet_itoa_buf[offset+2]=c+'0';
54
+		q_inet_itoa_buf[offset+3]=0;
55
+	}else if (b){
56
+		q_inet_itoa_buf[offset]=b+'0';
57
+		q_inet_itoa_buf[offset+1]=c+'0';
58
+		q_inet_itoa_buf[offset+2]=0;
59
+	}else{
60
+		q_inet_itoa_buf[offset]=c+'0';
61
+		q_inet_itoa_buf[offset+1]=0;
62
+	}
63
+
64
+	return q_inet_itoa_buf;
65
+}
66
+
67
+
68
+
69
+
70
+/* checks if ip is in host(name) and ?host(ip)=name?
71
+ * ip must be in network byte order!
72
+ *  resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made
73
+ * return 0 if equal */
74
+int check_address(unsigned long ip, char *name, int resolver)
75
+{
76
+	struct hostent* he;
77
+	int i;
78
+
79
+	/* maybe we are lucky and name it's an ip */
80
+	if (strcmp(name, q_inet_itoa( /* *(struct in_addr *)&*/ip ))==0)
81
+		return 0;
82
+	if (resolver&DO_DNS){
83
+		DBG("check_address: doing dns lookup\n");
84
+		/* try all names ips */
85
+		he=gethostbyname(name);
86
+		for(i=0;he && he->h_addr_list[i];i++){
87
+			if (*(unsigned long*)he->h_addr_list[i]==ip)
88
+				return 0;
89
+		}
90
+	}
91
+	if (resolver&DO_REV_DNS){
92
+		DBG("check_address: doing rev. dns lookup\n");
93
+		print_ip(ip);
94
+		/* try reverse dns */
95
+		he=gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
96
+		if (he && (strcmp(he->h_name, name)==0))
97
+			return 0;
98
+		for (i=0; he && he->h_aliases[i];i++){
99
+			if (strcmp(he->h_aliases[i],name)==0)
100
+				return 0;
101
+		}
102
+	}
103
+	return -1;
104
+}
105
+
106
+
107
+
108
+
109
+
110
+char * build_buf_from_sip_request(struct sip_msg* msg, unsigned int *returned_len)
111
+{
112
+	unsigned int len, new_len, via_len, received_len, uri_len;
113
+	char* line_buf;
114
+	char* received_buf;
115
+	char* tmp;
116
+	int tmp_len;
117
+	char* new_buf;
118
+	char* orig;
119
+	char* buf;
120
+	unsigned int offset, s_offset, size;
121
+	unsigned long source_ip;
122
+	struct lump *t,*r;
123
+	struct lump* anchor;
124
+
125
+	orig=msg->orig;
126
+	buf=msg->buf;
127
+	len=msg->len;
128
+	source_ip=msg->src_ip;
129
+	received_len=0;
130
+	new_buf=0;
131
+	line_buf=0;
132
+	received_buf=0;
133
+
134
+	line_buf=pkg_malloc(sizeof(char)*MAX_VIA_LINE_SIZE);
135
+	if (line_buf==0){
136
+		LOG(L_ERR, "ERROR: forward_request: out of memory\n");
137
+		goto error1;
138
+	}
139
+/*
140
+	via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
141
+						names[0], port_no);
142
+*/
143
+	via_len=MY_VIA_LEN+names_len[0]; /* space included in MY_VIA*/
144
+	if ((via_len+port_no_str_len+CRLF_LEN)<MAX_VIA_LINE_SIZE){
145
+		memcpy(line_buf, MY_VIA, MY_VIA_LEN);
146
+		memcpy(line_buf+MY_VIA_LEN, names[0], names_len[0]);
147
+		if (port_no!=SIP_PORT){
148
+			memcpy(line_buf+via_len, port_no_str, port_no_str_len);
149
+			via_len+=port_no_str_len;
150
+		}
151
+		memcpy(line_buf+via_len, CRLF, CRLF_LEN);
152
+		via_len+=CRLF_LEN;
153
+		line_buf[via_len]=0; /* null terminate the string*/
154
+	}else{
155
+		LOG(L_ERR, "forward_request: ERROR: via too long (%d)\n",
156
+				via_len);
157
+		goto error1;
158
+	}
159
+
160
+
161
+
162
+	/* check if received needs to be added */
163
+	if (check_address(source_ip, msg->via1->host.s, received_dns)!=0){
164
+		received_buf=pkg_malloc(sizeof(char)*MAX_RECEIVED_SIZE);
165
+		if (received_buf==0){
166
+			LOG(L_ERR, "ERROR: forward_request: out of memory\n");
167
+			goto error1;
168
+		}
169
+		/*
170
+		received_len=snprintf(received_buf, MAX_RECEIVED_SIZE,
171
+								";received=%s",
172
+								inet_ntoa(*(struct in_addr *)&source_ip));
173
+		*/
174
+		memcpy(received_buf, RECEIVED, RECEIVED_LEN);
175
+		tmp=q_inet_itoa( /* *(struct in_addr *)& */source_ip);
176
+		tmp_len=strlen(tmp);
177
+		received_len=RECEIVED_LEN+tmp_len;
178
+		memcpy(received_buf+RECEIVED_LEN, tmp, tmp_len);
179
+		received_buf[received_len]=0; /*null terminate it */
180
+	}
181
+
182
+	/* add via header to the list */
183
+	/* try to add it before msg. 1st via */
184
+	/*add first via, as an anchor for second via*/
185
+	anchor=anchor_lump(&(msg->add_rm), msg->via1->hdr.s-buf, 0, HDR_VIA);
186
+	if (anchor==0) goto error;
187
+	if (insert_new_lump_before(anchor, line_buf, via_len, HDR_VIA)==0)
188
+		goto error;
189
+	/* if received needs to be added, add anchor after host and add it */
190
+	if (received_len){
191
+		if (msg->via1->params.s){
192
+				size= msg->via1->params.s-msg->via1->hdr.s-1; /*compensate
193
+															  for ';' */
194
+		}else{
195
+				size= msg->via1->host.s-msg->via1->hdr.s+msg->via1->host.len;
196
+				if (msg->via1->port!=0){
197
+					size+=strlen(msg->via1->hdr.s+size+1)+1; /* +1 for ':'*/
198
+				}
199
+		}
200
+		anchor=anchor_lump(&(msg->add_rm),msg->via1->hdr.s-buf+size,0,
201
+				HDR_VIA);
202
+		if (anchor==0) goto error;
203
+		if (insert_new_lump_after(anchor, received_buf, received_len, HDR_VIA)
204
+				==0 ) goto error;
205
+	}
206
+
207
+
208
+	/* compute new msg len and fix overlapping zones*/
209
+	new_len=len;
210
+	s_offset=0;
211
+	for(t=msg->add_rm;t;t=t->next){
212
+		for(r=t->before;r;r=r->before){
213
+			switch(r->op){
214
+				case LUMP_ADD:
215
+					new_len+=r->len;
216
+					break;
217
+				default:
218
+					/* only ADD allowed for before/after */
219
+					LOG(L_CRIT, "BUG:forward_request: invalid op for"
220
+								" data lump (%x)\n", r->op);
221
+			}
222
+		}
223
+		switch(t->op){
224
+			case LUMP_ADD:
225
+				new_len+=t->len;
226
+				break;
227
+			case LUMP_DEL:
228
+				/* fix overlapping deleted zones */
229
+				if (t->u.offset < s_offset){
230
+					/* change len */
231
+					if (t->len>s_offset-t->u.offset)
232
+							t->len-=s_offset-t->u.offset;
233
+					else t->len=0;
234
+					t->u.offset=s_offset;
235
+				}
236
+				s_offset=t->u.offset+t->len;
237
+				new_len-=t->len;
238
+				break;
239
+			case LUMP_NOP:
240
+				/* fix offset if overlapping on a deleted zone */
241
+				if (t->u.offset < s_offset){
242
+					t->u.offset=s_offset;
243
+				}else
244
+					s_offset=t->u.offset;
245
+				/* do nothing */
246
+				break;
247
+			debug:
248
+				LOG(L_CRIT,"BUG:forward_request: invalid"
249
+							" op for data lump (%x)\n", r->op);
250
+		}
251
+		for (r=t->after;r;r=r->after){
252
+			switch(r->op){
253
+				case LUMP_ADD:
254
+					new_len+=r->len;
255
+					break;
256
+				default:
257
+					/* only ADD allowed for before/after */
258
+					LOG(L_CRIT, "BUG:forward_request: invalid"
259
+								" op for data lump (%x)\n", r->op);
260
+			}
261
+		}
262
+	}
263
+
264
+
265
+	if (msg->new_uri.s){
266
+		uri_len=msg->new_uri.len;
267
+		new_len=new_len-msg->first_line.u.request.uri.len+uri_len;
268
+	}
269
+	new_buf=(char*)malloc(new_len+1);
270
+	if (new_buf==0){
271
+		LOG(L_ERR, "ERROR: forward_request: out of memory\n");
272
+		goto error;
273
+	}
274
+
275
+	offset=s_offset=0;
276
+	if (msg->new_uri.s){
277
+		/* copy message up to uri */
278
+		size=msg->first_line.u.request.uri.s-buf;
279
+		memcpy(new_buf, orig, size);
280
+		offset+=size;
281
+		s_offset+=size;
282
+		/* add our uri */
283
+		memcpy(new_buf+offset, msg->new_uri.s, uri_len);
284
+		offset+=uri_len;
285
+		s_offset+=msg->first_line.u.request.uri.len; /* skip original uri */
286
+	}
287
+/* copy msg adding/removing lumps */
288
+	for (t=msg->add_rm;t;t=t->next){
289
+		switch(t->op){
290
+			case LUMP_ADD:
291
+				/* just add it here! */
292
+				/* process before  */
293
+				for(r=t->before;r;r=r->before){
294
+					switch (r->op){
295
+						case LUMP_ADD:
296
+							/*just add it here*/
297
+							memcpy(new_buf+offset, r->u.value, r->len);
298
+							offset+=r->len;
299
+							break;
300
+						default:
301
+							/* only ADD allowed for before/after */
302
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
303
+									" data lump (%x)\n", r->op);
304
+
305
+					}
306
+				}
307
+				/* copy "main" part */
308
+				memcpy(new_buf+offset, t->u.value, t->len);
309
+				offset+=t->len;
310
+				/* process after */
311
+				for(r=t->after;r;r=r->after){
312
+					switch (r->op){
313
+						case LUMP_ADD:
314
+							/*just add it here*/
315
+							memcpy(new_buf+offset, r->u.value, r->len);
316
+							offset+=r->len;
317
+							break;
318
+						default:
319
+							/* only ADD allowed for before/after */
320
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
321
+									" data lump (%x)\n", r->op);
322
+					}
323
+				}
324
+				break;
325
+			case LUMP_NOP:
326
+			case LUMP_DEL:
327
+				/* copy till offset */
328
+				if (s_offset>t->u.offset){
329
+					DBG("Warning: (%d) overlapped lumps offsets,"
330
+						" ignoring(%x, %x)\n", t->op, s_offset,t->u.offset);
331
+					/* this should've been fixed above (when computing len) */
332
+					/* just ignore it*/
333
+					break;
334
+				}
335
+				size=t->u.offset-s_offset;
336
+				if (size){
337
+					memcpy(new_buf+offset, orig+s_offset,size);
338
+					offset+=size;
339
+					s_offset+=size;
340
+				}
341
+				/* process before  */
342
+				for(r=t->before;r;r=r->before){
343
+					switch (r->op){
344
+						case LUMP_ADD:
345
+							/*just add it here*/
346
+							memcpy(new_buf+offset, r->u.value, r->len);
347
+							offset+=r->len;
348
+							break;
349
+						default:
350
+							/* only ADD allowed for before/after */
351
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
352
+									" data lump (%x)\n", r->op);
353
+
354
+					}
355
+				}
356
+				/* process main (del only) */
357
+				if (t->op==LUMP_DEL){
358
+					/* skip len bytes from orig msg */
359
+					s_offset+=t->len;
360
+				}
361
+				/* process after */
362
+				for(r=t->after;r;r=r->after){
363
+					switch (r->op){
364
+						case LUMP_ADD:
365
+							/*just add it here*/
366
+							memcpy(new_buf+offset, r->u.value, r->len);
367
+							offset+=r->len;
368
+							break;
369
+						default:
370
+							/* only ADD allowed for before/after */
371
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
372
+									" data lump (%x)\n", r->op);
373
+					}
374
+				}
375
+				break;
376
+			default:
377
+					LOG(L_CRIT, "BUG: forward_request: unknown op (%x)\n",
378
+							t->op);
379
+		}
380
+	}
381
+	/* copy the rest of the message */
382
+	memcpy(new_buf+offset, orig+s_offset, len-s_offset);
383
+	new_buf[new_len]=0;
384
+
385
+	*returned_len=new_len;
386
+	return new_buf;
387
+
388
+error1:
389
+	if (line_buf) pkg_free(line_buf);
390
+	if (received_buf) pkg_free(received_buf);
391
+error:
392
+	if (new_buf) free(new_buf);
393
+	*returned_len=0;
394
+	return 0;
395
+}
396
+
397
+
398
+
399
+
400
+
0 401
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+#ifndef  _MSG_TRANSLATOR_H
1
+#define _MSG_TRANSLATOR_H
2
+
3
+#include "msg_parser.h"
4
+
5
+char * build_buf_from_sip_request(struct sip_msg* msg, unsigned int *returned_len);
6
+
7
+
8
+
9
+
10
+
11
+#endif