13b9b51feSCy Schubert /*
23b9b51feSCy Schubert * Simple netbios-dgm transparent proxy for in-kernel use.
33b9b51feSCy Schubert * For use with the NAT code.
43b9b51feSCy Schubert * $Id$
53b9b51feSCy Schubert */
63b9b51feSCy Schubert
73b9b51feSCy Schubert /*-
83b9b51feSCy Schubert * Copyright (c) 2002-2003 Paul J. Ledbetter III
93b9b51feSCy Schubert * All rights reserved.
103b9b51feSCy Schubert *
113b9b51feSCy Schubert * Redistribution and use in source and binary forms, with or without
123b9b51feSCy Schubert * modification, are permitted provided that the following conditions
133b9b51feSCy Schubert * are met:
143b9b51feSCy Schubert * 1. Redistributions of source code must retain the above copyright
153b9b51feSCy Schubert * notice, this list of conditions and the following disclaimer.
163b9b51feSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright
173b9b51feSCy Schubert * notice, this list of conditions and the following disclaimer in the
183b9b51feSCy Schubert * documentation and/or other materials provided with the distribution.
193b9b51feSCy Schubert *
203b9b51feSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
213b9b51feSCy Schubert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
223b9b51feSCy Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
233b9b51feSCy Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
243b9b51feSCy Schubert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
253b9b51feSCy Schubert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
263b9b51feSCy Schubert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
273b9b51feSCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
283b9b51feSCy Schubert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
293b9b51feSCy Schubert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
303b9b51feSCy Schubert * SUCH DAMAGE.
313b9b51feSCy Schubert *
323b9b51feSCy Schubert * $Id$
333b9b51feSCy Schubert */
343b9b51feSCy Schubert
353b9b51feSCy Schubert #define IPF_NETBIOS_PROXY
363b9b51feSCy Schubert
373b9b51feSCy Schubert void ipf_p_netbios_main_load(void);
383b9b51feSCy Schubert void ipf_p_netbios_main_unload(void);
393b9b51feSCy Schubert int ipf_p_netbios_out(void *, fr_info_t *, ap_session_t *, nat_t *);
403b9b51feSCy Schubert
413b9b51feSCy Schubert static frentry_t netbiosfr;
423b9b51feSCy Schubert
433b9b51feSCy Schubert int netbios_proxy_init = 0;
443b9b51feSCy Schubert
453b9b51feSCy Schubert /*
463b9b51feSCy Schubert * Initialize local structures.
473b9b51feSCy Schubert */
483b9b51feSCy Schubert void
ipf_p_netbios_main_load(void)49064a5a95SCy Schubert ipf_p_netbios_main_load(void)
503b9b51feSCy Schubert {
513b9b51feSCy Schubert bzero((char *)&netbiosfr, sizeof(netbiosfr));
523b9b51feSCy Schubert netbiosfr.fr_ref = 1;
533b9b51feSCy Schubert netbiosfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
543b9b51feSCy Schubert MUTEX_INIT(&netbiosfr.fr_lock, "NETBIOS proxy rule lock");
553b9b51feSCy Schubert netbios_proxy_init = 1;
563b9b51feSCy Schubert }
573b9b51feSCy Schubert
583b9b51feSCy Schubert
593b9b51feSCy Schubert void
ipf_p_netbios_main_unload(void)60064a5a95SCy Schubert ipf_p_netbios_main_unload(void)
613b9b51feSCy Schubert {
623b9b51feSCy Schubert if (netbios_proxy_init == 1) {
633b9b51feSCy Schubert MUTEX_DESTROY(&netbiosfr.fr_lock);
643b9b51feSCy Schubert netbios_proxy_init = 0;
653b9b51feSCy Schubert }
663b9b51feSCy Schubert }
673b9b51feSCy Schubert
683b9b51feSCy Schubert
693b9b51feSCy Schubert int
ipf_p_netbios_out(void * arg,fr_info_t * fin,ap_session_t * aps,nat_t * nat)70064a5a95SCy Schubert ipf_p_netbios_out(void *arg, fr_info_t *fin, ap_session_t *aps, nat_t *nat)
713b9b51feSCy Schubert {
723b9b51feSCy Schubert char dgmbuf[6];
733b9b51feSCy Schubert int off, dlen;
743b9b51feSCy Schubert udphdr_t *udp;
753b9b51feSCy Schubert ip_t *ip;
763b9b51feSCy Schubert mb_t *m;
773b9b51feSCy Schubert
783b9b51feSCy Schubert aps = aps; /* LINT */
793b9b51feSCy Schubert nat = nat; /* LINT */
803b9b51feSCy Schubert
813b9b51feSCy Schubert m = fin->fin_m;
823b9b51feSCy Schubert dlen = fin->fin_dlen - sizeof(*udp);
833b9b51feSCy Schubert /*
843b9b51feSCy Schubert * no net bios datagram could possibly be shorter than this
853b9b51feSCy Schubert */
863b9b51feSCy Schubert if (dlen < 11)
878c82b374SCy Schubert return (0);
883b9b51feSCy Schubert
893b9b51feSCy Schubert ip = fin->fin_ip;
903b9b51feSCy Schubert udp = (udphdr_t *)fin->fin_dp;
913b9b51feSCy Schubert off = (char *)udp - (char *)ip + sizeof(*udp) + fin->fin_ipoff;
923b9b51feSCy Schubert
933b9b51feSCy Schubert /*
943b9b51feSCy Schubert * move past the
953b9b51feSCy Schubert * ip header;
963b9b51feSCy Schubert * udp header;
973b9b51feSCy Schubert * 4 bytes into the net bios dgm header.
983b9b51feSCy Schubert * According to rfc1002, this should be the exact location of
993b9b51feSCy Schubert * the source address/port
1003b9b51feSCy Schubert */
1013b9b51feSCy Schubert off += 4;
1023b9b51feSCy Schubert
1033b9b51feSCy Schubert /* Copy NATed source Address/port*/
1043b9b51feSCy Schubert dgmbuf[0] = (char)((ip->ip_src.s_addr ) &0xFF);
1053b9b51feSCy Schubert dgmbuf[1] = (char)((ip->ip_src.s_addr >> 8) &0xFF);
1063b9b51feSCy Schubert dgmbuf[2] = (char)((ip->ip_src.s_addr >> 16)&0xFF);
1073b9b51feSCy Schubert dgmbuf[3] = (char)((ip->ip_src.s_addr >> 24)&0xFF);
1083b9b51feSCy Schubert
1093b9b51feSCy Schubert dgmbuf[4] = (char)((udp->uh_sport )&0xFF);
1103b9b51feSCy Schubert dgmbuf[5] = (char)((udp->uh_sport >> 8)&0xFF);
1113b9b51feSCy Schubert
1123b9b51feSCy Schubert /* replace data in packet */
1133b9b51feSCy Schubert COPYBACK(m, off, sizeof(dgmbuf), dgmbuf);
1143b9b51feSCy Schubert
1158c82b374SCy Schubert return (0);
1163b9b51feSCy Schubert }
117