1118132Ssimon/*
2118132Ssimon * Simple netbios-dgm transparent proxy for in-kernel use.
3118132Ssimon * For use with the NAT code.
4118132Ssimon * $Id$
5118132Ssimon */
6118132Ssimon
7118132Ssimon/*-
8118132Ssimon * Copyright (c) 2002-2003 Paul J. Ledbetter III
9118132Ssimon * All rights reserved.
10118132Ssimon *
11118132Ssimon * Redistribution and use in source and binary forms, with or without
12118132Ssimon * modification, are permitted provided that the following conditions
13118132Ssimon * are met:
14118132Ssimon * 1. Redistributions of source code must retain the above copyright
15118132Ssimon *    notice, this list of conditions and the following disclaimer.
16118132Ssimon * 2. Redistributions in binary form must reproduce the above copyright
17118132Ssimon *    notice, this list of conditions and the following disclaimer in the
18118132Ssimon *    documentation and/or other materials provided with the distribution.
19118132Ssimon *
20118132Ssimon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21118132Ssimon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22118132Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23118132Ssimon * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24118132Ssimon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25118132Ssimon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26118132Ssimon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27118132Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28118132Ssimon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29206622Suqs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30118132Ssimon * SUCH DAMAGE.
31118132Ssimon *
32118132Ssimon * $Id$
33118132Ssimon */
34118132Ssimon
35118132Ssimon#define	IPF_NETBIOS_PROXY
36118132Ssimon
37118132Ssimonvoid ipf_p_netbios_main_load __P((void));
38118132Ssimonvoid ipf_p_netbios_main_unload __P((void));
39118132Ssimonint ipf_p_netbios_out __P((void *, fr_info_t *, ap_session_t *, nat_t *));
40118132Ssimon
41118132Ssimonstatic	frentry_t	netbiosfr;
42118132Ssimon
43118132Ssimonint	netbios_proxy_init = 0;
44118132Ssimon
45118132Ssimon/*
46118132Ssimon * Initialize local structures.
47118132Ssimon */
48118132Ssimonvoid
49118132Ssimonipf_p_netbios_main_load()
50118132Ssimon{
51118132Ssimon	bzero((char *)&netbiosfr, sizeof(netbiosfr));
52118132Ssimon	netbiosfr.fr_ref = 1;
53118132Ssimon	netbiosfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
54118132Ssimon	MUTEX_INIT(&netbiosfr.fr_lock, "NETBIOS proxy rule lock");
55118132Ssimon	netbios_proxy_init = 1;
56118132Ssimon}
57118132Ssimon
58118132Ssimon
59118132Ssimonvoid
60118132Ssimonipf_p_netbios_main_unload()
61118132Ssimon{
62118132Ssimon	if (netbios_proxy_init == 1) {
63118132Ssimon		MUTEX_DESTROY(&netbiosfr.fr_lock);
64118132Ssimon		netbios_proxy_init = 0;
65118132Ssimon	}
66118132Ssimon}
67118132Ssimon
68118132Ssimon
69118132Ssimonint
70118132Ssimonipf_p_netbios_out(arg, fin, aps, nat)
71118132Ssimon	void *arg;
72118132Ssimon	fr_info_t *fin;
73118132Ssimon	ap_session_t *aps;
74118132Ssimon	nat_t *nat;
75118132Ssimon{
76118132Ssimon	char dgmbuf[6];
77118132Ssimon	int off, dlen;
78118132Ssimon	udphdr_t *udp;
79118132Ssimon	ip_t *ip;
80118132Ssimon	mb_t *m;
81118132Ssimon
82118132Ssimon	aps = aps;	/* LINT */
83118132Ssimon	nat = nat;	/* LINT */
84118132Ssimon
85118132Ssimon	m = fin->fin_m;
86118132Ssimon	dlen = fin->fin_dlen - sizeof(*udp);
87118132Ssimon	/*
88118132Ssimon	 * no net bios datagram could possibly be shorter than this
89118132Ssimon	 */
90118132Ssimon	if (dlen < 11)
91118132Ssimon		return 0;
92118132Ssimon
93118132Ssimon	ip = fin->fin_ip;
94118132Ssimon	udp = (udphdr_t *)fin->fin_dp;
95118132Ssimon	off = (char *)udp - (char *)ip + sizeof(*udp) + fin->fin_ipoff;
96118132Ssimon
97118132Ssimon	/*
98118132Ssimon	 * move past the
99118132Ssimon	 *	ip header;
100118132Ssimon	 *	udp header;
101118132Ssimon	 *	4 bytes into the net bios dgm header.
102118132Ssimon	 *  According to rfc1002, this should be the exact location of
103118132Ssimon	 *  the source address/port
104118132Ssimon	 */
105118132Ssimon	off += 4;
106118132Ssimon
107118132Ssimon	/* Copy NATed source Address/port*/
108118132Ssimon	dgmbuf[0] = (char)((ip->ip_src.s_addr     ) &0xFF);
109118132Ssimon	dgmbuf[1] = (char)((ip->ip_src.s_addr >> 8) &0xFF);
110118132Ssimon	dgmbuf[2] = (char)((ip->ip_src.s_addr >> 16)&0xFF);
111118132Ssimon	dgmbuf[3] = (char)((ip->ip_src.s_addr >> 24)&0xFF);
112118132Ssimon
113118132Ssimon	dgmbuf[4] = (char)((udp->uh_sport     )&0xFF);
114118132Ssimon	dgmbuf[5] = (char)((udp->uh_sport >> 8)&0xFF);
115118132Ssimon
116118132Ssimon	/* replace data in packet */
117118132Ssimon	COPYBACK(m, off, sizeof(dgmbuf), dgmbuf);
118118132Ssimon
119118132Ssimon	return 0;
120118132Ssimon}
121118132Ssimon