2 * IP_MASQ_USER user space control module
5 * $Id: ip_masq_user.c,v 1.1 1998/08/29 23:51:08 davem Exp $
8 #include <linux/config.h>
9 #include <linux/module.h>
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/skbuff.h>
14 #include <asm/system.h>
15 #include <linux/stat.h>
16 #include <linux/proc_fs.h>
19 #include <linux/inet.h>
20 #include <linux/init.h>
21 #include <net/protocol.h>
25 #include <net/checksum.h>
26 #include <net/ip_masq.h>
27 #include <net/ip_masq_mod.h>
28 #include <linux/sysctl.h>
29 #include <linux/ip_fw.h>
31 #include <linux/ip_masq.h>
38 MODULE_PARM(ports
, "1-" __MODULE_STRING(MAX_MASQ_APP_PORTS
) "i");
39 MODULE_PARM(debug
, "i");
42 static int check_5uple (struct ip_masq_user *ums) {
46 static void masq_user_k2u(const struct ip_masq
*ms
, struct ip_masq_user
*ums
)
48 ums
->protocol
= ms
->protocol
;
49 ums
->daddr
= ms
->daddr
;
50 ums
->dport
= ms
->dport
;
51 ums
->maddr
= ms
->maddr
;
52 ums
->mport
= ms
->mport
;
53 ums
->saddr
= ms
->saddr
;
54 ums
->sport
= ms
->sport
;
55 ums
->timeout
= ms
->timeout
;
59 static int ip_masq_user_maddr(struct ip_masq_user
*ums
)
64 u32 rt_daddr
, rt_saddr
;
68 * Did specify masq address.
74 * Select address to use for routing query
77 rt_daddr
= ums
->rt_daddr
? ums
->rt_daddr
: ums
->daddr
;
78 rt_saddr
= ums
->rt_saddr
? ums
->rt_saddr
: ums
->saddr
;
82 * No address for routing, cannot continue
85 IP_MASQ_DEBUG(1-debug
, "cannot setup maddr with daddr=%lX, rt_addr=%lX\n",
86 ntohl(ums
->daddr
), ntohl(ums
->rt_daddr
));
95 tos
= RT_TOS(ums
->ip_tos
) | RTO_CONN
;
97 if ((ret
=ip_route_output(&rt
, rt_daddr
, rt_saddr
, tos
, 0 /* dev */))) {
98 IP_MASQ_DEBUG(0-debug
, "could not setup maddr for routing daddr=%lX, saddr=%lX\n",
99 ntohl(rt_daddr
), ntohl(rt_saddr
));
103 ums
->maddr
= ip_masq_select_addr(dev
, rt
->rt_gateway
, RT_SCOPE_UNIVERSE
);
105 IP_MASQ_DEBUG(1-debug
, "did setup maddr=%lX\n", ntohl(ums
->maddr
));
111 * Create new entry (from uspace)
113 static int ip_masq_user_new(struct ip_masq_user
*ums
)
115 struct ip_masq
*ms
= NULL
;
119 if (masq_proto_num (ums
->protocol
) == -1) {
120 return EPROTONOSUPPORT
;
123 if (ums
->dport
== 0) {
124 ums
->flags
|= IP_MASQ_USER_F_LISTEN
;
127 if (ums
->flags
| IP_MASQ_USER_F_LISTEN
) {
128 if ((ums
->saddr
== 0) || (ums
->sport
== 0)) {
131 mflags
|= (IP_MASQ_F_NO_DPORT
|IP_MASQ_F_NO_DADDR
);
135 if ((ret
= ip_masq_user_maddr(ums
)) < 0) {
139 mflags
|= IP_MASQ_F_USER
;
140 ms
= ip_masq_new(ums
->protocol
,
141 ums
->maddr
, ums
->mport
,
142 ums
->saddr
, ums
->sport
,
143 ums
->daddr
, ums
->dport
,
148 * FIXME: ip_masq_new() should return errno
154 * Setup timeouts for this new entry
158 ms
->timeout
= ums
->timeout
;
159 } else if (ums
->flags
| IP_MASQ_USER_F_LISTEN
) {
163 masq_user_k2u(ms
, ums
);
169 * Delete existing entry
171 static int ip_masq_user_del(struct ip_masq_user
*ums
)
173 struct ip_masq
*ms
=NULL
;
175 if (masq_proto_num (ums
->protocol
) == -1) {
176 return EPROTONOSUPPORT
;
179 if (ums
->mport
&& ums
->maddr
) {
180 ms
= ip_masq_in_get(ums
->protocol
,
181 ums
->daddr
, ums
->dport
,
182 ums
->maddr
, ums
->mport
);
184 } else if (ums
->sport
&& ums
->saddr
) {
185 ms
= ip_masq_out_get(ums
->protocol
,
186 ums
->saddr
, ums
->sport
,
187 ums
->daddr
, ums
->dport
);
197 * got (locked) entry, setup almost tiny timeout :) and
200 * FIXME: should use something better than S_CLOSE
202 ms
->timeout
= IP_MASQ_S_CLOSE
;
204 masq_user_k2u(ms
, ums
);
209 static struct ip_masq
* ip_masq_user_locked_get (struct ip_masq_user
*ums
, int *err
)
211 struct ip_masq
*ms
=NULL
;
212 if (masq_proto_num (ums
->protocol
) == -1) {
213 *err
= EPROTONOSUPPORT
;
217 if (ums
->mport
&& ums
->maddr
) {
218 ms
= ip_masq_in_get(ums
->protocol
,
219 ums
->daddr
, ums
->dport
,
220 ums
->maddr
, ums
->mport
);
222 } else if (ums
->sport
&& ums
->saddr
) {
223 ms
= ip_masq_out_get(ums
->protocol
,
224 ums
->saddr
, ums
->sport
,
225 ums
->daddr
, ums
->dport
);
230 if (ms
== NULL
) *err
= ESRCH
;
235 * Get existing entry (complete full tunnel info)
237 static int ip_masq_user_get(struct ip_masq_user
*ums
)
239 struct ip_masq
*ms
=NULL
;
242 ms
= ip_masq_user_locked_get(ums
, &err
);
246 masq_user_k2u(ms
, ums
);
253 * Set (some, valid) entry parameters
255 static int ip_masq_user_set(struct ip_masq_user
*ums
)
257 struct ip_masq
*ms
= NULL
;
260 ms
= ip_masq_user_locked_get(ums
, &err
);
265 * FIXME: must allow selecting what you want to set
267 ms
->timeout
= ums
->timeout
;
269 masq_user_k2u(ms
, ums
);
281 * >0 ok, copy to user
283 static int ip_masq_user_ctl(int optname
, struct ip_masq_ctl
*mctl
, int optlen
)
285 struct ip_masq_user
*ums
= &mctl
->u
.user
;
287 int arglen
= optlen
- IP_MASQ_CTL_BSIZE
;
290 IP_MASQ_DEBUG(1-debug
, "ip_masq_user_ctl(len=%d/%d|%d/%d)\n",
297 * Yes, I'm a bad guy ...
299 if (arglen
!= sizeof(*ums
) && optlen
!= sizeof(*mctl
))
305 * Don't trust the lusers - plenty of error checking!
308 IP_MASQ_DEBUG(1-debug
, "ip_masq_user_ctl(cmd=%d)\n", cmd
);
310 switch (mctl
->m_cmd
) {
311 case IP_MASQ_CMD_ADD
:
312 case IP_MASQ_CMD_INSERT
:
313 ret
= ip_masq_user_new(ums
);
315 case IP_MASQ_CMD_DEL
:
316 ret
= ip_masq_user_del(ums
);
318 case IP_MASQ_CMD_SET
:
319 ret
= ip_masq_user_set(ums
);
321 case IP_MASQ_CMD_GET
:
322 ret
= ip_masq_user_get(ums
);
327 * For all of the above, return masq tunnel info
333 ret
= sizeof (*ums
) + IP_MASQ_CTL_BSIZE
;
334 IP_MASQ_DEBUG(1-debug
, "will return %d bytes to user\n", ret
);
342 #ifdef CONFIG_PROC_FS
343 static int ip_masq_user_info(char *buffer
, char **start
, off_t offset
,
344 int length
, int proto
)
355 IP_MASQ_DEBUG(1-debug
, "Entered user_info with proto=%d\n", proto
);
360 "Prot SrcIP SPrt DstIP DPrt MAddr MPrt State Flgs Ref Ctl Expires (free=%d,%d,%d)",
361 atomic_read(ip_masq_free_ports
),
362 atomic_read(ip_masq_free_ports
+1),
363 atomic_read(ip_masq_free_ports
+2));
364 len
= sprintf(buffer
, "%-127s\n", temp
);
368 for(idx
= 0; idx
< IP_MASQ_TAB_SIZE
; idx
++)
371 * Lock is actually only need in next loop
372 * we are called from uspace: must stop bh.
374 read_lock_bh(&__ip_masq_lock
);
375 for(ms
= ip_masq_m_tab
[idx
]; ms
; ms
= ms
->m_link
)
377 if (ms
->protocol
!= proto
) {
388 * We have locked the tables, no need to del/add timers
393 magic_control
= atomic_read(&ms
->n_control
);
394 if (!magic_control
&& ms
->control
) magic_control
= -1;
395 sprintf(temp
,"%-4s %08lX:%04X %08lX:%04X %08lX:%04X %-12s %3X %4d %3d %7lu",
396 masq_proto_name(ms
->protocol
),
397 ntohl(ms
->saddr
), ntohs(ms
->sport
),
398 ntohl(ms
->daddr
), ntohs(ms
->dport
),
399 ntohl(ms
->maddr
), ntohs(ms
->mport
),
400 ip_masq_state_name(ms
->state
),
402 atomic_read(&ms
->refcnt
),
404 (ms
->timer
.expires
-jiffies
)/HZ
);
405 len
+= sprintf(buffer
+len
, "%-127s\n", temp
);
408 read_unlock_bh(&__ip_masq_lock
);
412 read_unlock_bh(&__ip_masq_lock
);
418 begin
= len
- (pos
- offset
);
419 *start
= buffer
+ begin
;
428 #define ip_masq_user_info NULL
431 static struct ip_masq_hook ip_masq_user
= {
436 int ip_masq_user_init(void)
438 if (ip_masq_user_hook
!= NULL
)
440 ip_masq_user_hook
= &ip_masq_user
;
444 int ip_masq_user_done(void)
446 if (ip_masq_user_hook
== NULL
)
448 ip_masq_user_hook
= NULL
;
454 int init_module(void)
456 if (ip_masq_user_init() != 0)
461 void cleanup_module(void)
463 if (ip_masq_user_done() != 0)
464 printk(KERN_INFO
"ip_masq_user_done(): can't remove module");