2 * $Id: ip_rcmd_pxy.c,v 1.4.2.6 2002/10/01 15:24:59 darrenr Exp $
5 * Simple RCMD transparent proxy for in-kernel use. For use with the NAT
7 * $FreeBSD: src/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c,v 1.8.2.3 2003/03/01 03:55:54 darrenr Exp $
9 #if SOLARIS && defined(_KERNEL)
10 extern kmutex_t ipf_rw;
13 #define isdigit(x) ((x) >= '0' && (x) <= '9')
15 #define IPF_RCMD_PROXY
18 int ippr_rcmd_init __P((void));
19 int ippr_rcmd_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
20 int ippr_rcmd_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
21 u_short ipf_rcmd_atoi __P((char *));
22 int ippr_rcmd_portmsg __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *));
24 static frentry_t rcmdfr;
28 * RCMD application proxy initialization.
32 bzero((char *)&rcmdfr, sizeof(rcmdfr));
34 rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
40 * Setup for a new RCMD proxy.
42 int ippr_rcmd_new(fin, ip, aps, nat)
48 tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
50 aps->aps_psiz = sizeof(u_32_t);
51 KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t));
52 if (aps->aps_data == NULL)
54 *(u_32_t *)aps->aps_data = 0;
55 aps->aps_sport = tcp->th_sport;
56 aps->aps_dport = tcp->th_dport;
62 * ipf_rcmd_atoi - implement a simple version of atoi
64 u_short ipf_rcmd_atoi(ptr)
67 register char *s = ptr, c;
68 register u_short i = 0;
70 while ((c = *s++) && isdigit(c)) {
78 int ippr_rcmd_portmsg(fin, ip, aps, nat)
87 tcphdr_t *tcp, tcph, *tcp2 = &tcph;
96 tcp = (tcphdr_t *)fin->fin_dp;
98 if (tcp->th_flags & TH_SYN) {
99 *(u_32_t *)aps->aps_data = htonl(ntohl(tcp->th_seq) + 1);
103 if ((*(u_32_t *)aps->aps_data != 0) &&
104 (tcp->th_seq != *(u_32_t *)aps->aps_data))
107 off = fin->fin_hlen + (tcp->th_off << 2);
112 dlen = msgdsize(m) - off;
113 bzero(portbuf, sizeof(portbuf));
114 copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
116 m = *(mb_t **)fin->fin_mp;
117 dlen = mbufchainlen(m) - off;
118 bzero(portbuf, sizeof(portbuf));
119 m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
122 portbuf[sizeof(portbuf) - 1] = '\0';
124 sp = ipf_rcmd_atoi(s);
129 * Add skeleton NAT entry for connection which will come back the
132 bcopy((char *)fin, (char *)&fi, sizeof(fi));
134 fi.fin_data[1] = fin->fin_data[1];
135 ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
141 ip->ip_len = fin->fin_hlen + sizeof(*tcp);
142 bzero((char *)tcp2, sizeof(*tcp2));
143 tcp2->th_win = htons(8192);
144 tcp2->th_sport = htons(sp);
145 tcp2->th_dport = 0; /* XXX - don't specify remote port */
147 tcp2->th_flags = TH_SYN;
149 fi.fin_dp = (char *)tcp2;
150 fi.fin_dlen = sizeof(*tcp2);
152 ip->ip_src = nat->nat_inip;
153 ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
156 ipn->nat_age = fr_defnatage;
158 (void) fr_addstate(ip, &fi, NULL,
159 FI_W_DPORT|FI_IGNOREPKT);
168 int ippr_rcmd_out(fin, ip, aps, nat)
174 return ippr_rcmd_portmsg(fin, ip, aps, nat);