Browse code

core: basic support for receiving udp sip packets on raw sockets

Functions for receiving udp sip packets from raw sockets.

Andrei Pelinescu-Onciul authored on 09/06/2010 20:55:21
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,147 @@
0
+/*
1
+ * Copyright (C) 2010 iptelorg GmbH
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+/** raw socket udp listen functions.
16
+ *  @file raw_listener.c
17
+ *  @ingroup core
18
+ *  Module: @ref core
19
+ */
20
+/*
21
+ * History:
22
+ * --------
23
+ *  2010-06-09  intial version (from older code) andrei
24
+ */
25
+
26
+#ifdef USE_RAW_SOCKS
27
+
28
+#include "../../config.h"
29
+#include "../../receive.h"
30
+
31
+#include "raw_listener.h"
32
+#include "raw_sock.h"
33
+#include "tlb_send.h"
34
+#include "tlb_cfg.h"
35
+
36
+#include <errno.h>
37
+#include <string.h>
38
+
39
+struct raw_listen_info* raw_sendipv4=0;
40
+
41
+/** creates a raw socket based on a socket_info structure.
42
+ * Side-effects: sets raw_udp_sendipv4 if not already set.
43
+ * @param si - pointer to partially filled socket_info structure (su must
44
+ *              be set).
45
+ * @param iface - pointer to network interface to bind on (str). Can be null.
46
+ * @param iphdr_incl - 1 if send on these socket will include the IP header.
47
+ * @return <0 on error, socket on success.
48
+ */
49
+int raw_listener_init(struct socket_info* si, str* iface, int iphdr_incl)
50
+{
51
+	int sock;
52
+	struct ip_addr ip;
53
+	
54
+	su2ip_addr(&ip, &si->su);
55
+	sock=raw_udp4_socket(&ip, iface, iphdr_incl);
56
+	if (sock>=0){
57
+		if (raw_sendipv4==0 || iface==0 || iface->s==0)
58
+			raw_udp_sendipv4=si;
59
+	}
60
+	return sock;
61
+}
62
+
63
+
64
+
65
+/** receive sip udp ipv4 packets over a raw socket in a loop.
66
+ * It should be called by a "raw socket receiver" process
67
+ * (since the function never exits unless it encounters a
68
+ *  critical error).
69
+ * @param rsock - initialized raw socket.
70
+ * @param port1 - start of port range.
71
+ * @param port2 - end of port range. If 0 it's equivalent to listening only
72
+ *                on port1.
73
+ * @return <0 on error, never returns on success.
74
+ */
75
+int raw_udp4_rcv_loop(int rsock, int port1, int port2)
76
+{
77
+	static char buf[BUF_SIZE+1];
78
+	char* p;
79
+	char* tmp;
80
+	union sockaddr_union from;
81
+	union sockaddr_union to;
82
+	struct receive_info ri;
83
+	struct raw_filter rf;
84
+	int len;
85
+	
86
+	/* this will not change */
87
+	from.sin.sin_family=AF_INET;
88
+	ri.bind_address=0;
89
+	ri.proto=PROTO_UDP;
90
+	ri.proto_reserved1=0;
91
+	ri.proto_reserved2=0;
92
+	/* set filter to match any address but with the specified port range */
93
+	memset(&rf, 0, sizeof(rf));
94
+	rf.dst.ip.af=AF_INET;
95
+	rf.dst.ip.len=4;
96
+	rf.dst.mask.af=AF_INET;
97
+	rf.dst.mask.len=4;
98
+	rf.proto=PROTO_UDP;
99
+	rf.port1=port1;
100
+	rf.port2=port2?port2:port1;
101
+	for(;;){
102
+		p=buf;
103
+		len=raw_udp4_recv(rsock, &p, BUF_SIZE, &from, &to, &rf);
104
+		if (len<0){
105
+			if (len==-1){
106
+				LOG(L_ERR, "ERROR: raw_udp4_rcv_loop:raw_udp4_recv: %s [%d]\n",
107
+						strerror(errno), errno);
108
+				if ((errno==EINTR)||(errno==EWOULDBLOCK))
109
+					continue;
110
+				else
111
+					goto error;
112
+			}else{
113
+				DBG("raw_udp4_rcv_loop: raw_udp4_recv error: %d\n", len);
114
+				continue;
115
+			}
116
+		}
117
+		/* we must 0-term the message */
118
+		p[len]=0;
119
+		ri.src_su=from;
120
+		su2ip_addr(&ri.src_ip, &from);
121
+		ri.src_port=su_getport(&from);
122
+		su2ip_addr(&ri.dst_ip, &to);
123
+		ri.dst_port=su_getport(&to);
124
+		/* sanity checks */
125
+		if (len<MIN_UDP_PACKET){
126
+			tmp=ip_addr2a(&ri.src_ip);
127
+			DBG("raw_udp4_rcv_loop: probing packet received from %s %d\n",
128
+					tmp, htons(ri.src_port));
129
+			continue;
130
+		}
131
+		if (ri.src_port==0){
132
+			tmp=ip_addr2a(&ri.src_ip);
133
+			LOG(L_INFO, "raw_udp4_rcv_loop: dropping 0 port packet from %s\n",
134
+						tmp);
135
+			continue;
136
+		}
137
+		tmp=ip_addr2a(&ri.src_ip);
138
+		DBG("raw_udp4_rcv_loop: received from %s:\n[%.*s]\n", tmp, len, p);
139
+		receive_msg(p, len, &ri);
140
+	}
141
+error:
142
+	return -1;
143
+}
144
+
145
+
146
+#endif /* USE_RAW_SOCKS */
0 147
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+/*
1
+ * Copyright (C) 2010 iptelorg GmbH
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+/** raw socket udp listen functions.
16
+ *  @file raw_listener.h
17
+ *  @ingroup core
18
+ *  Module: @ref core
19
+ */
20
+/*
21
+ * History:
22
+ * --------
23
+ *  2010-06-09  initial version (from older code) andrei
24
+ */
25
+
26
+#ifndef _raw_listener_h
27
+#define _raw_listener_h
28
+
29
+#include "../../ip_addr.h"
30
+
31
+
32
+/** default raw socket used for sending on udp ipv4 */
33
+struct struct_info* raw_udp_sendipv4;
34
+
35
+int raw_listener_init(struct socket_info* si, str* iface, int iphdr_incl);
36
+int raw_udp4_rcv_loop(int rsock, int port1, int port2);
37
+
38
+#endif /* _raw_listener_h */