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