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 $
8 * $DragonFly: src/sys/contrib/ipfilter/netinet/ip_rcmd_pxy.c,v 1.5 2004/07/28 00:22:37 hmp Exp $
10 #if SOLARIS && defined(_KERNEL)
11 extern kmutex_t ipf_rw;
14 #define isdigit(x) ((x) >= '0' && (x) <= '9')
16 #define IPF_RCMD_PROXY
19 int ippr_rcmd_init (void);
20 int ippr_rcmd_new (fr_info_t *, ip_t *, ap_session_t *, nat_t *);
21 int ippr_rcmd_out (fr_info_t *, ip_t *, ap_session_t *, nat_t *);
22 u_short ipf_rcmd_atoi (char *);
23 int ippr_rcmd_portmsg (fr_info_t *, ip_t *, ap_session_t *, nat_t *);
25 static frentry_t rcmdfr;
29 * RCMD application proxy initialization.
33 bzero((char *)&rcmdfr, sizeof(rcmdfr));
35 rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE;
41 * Setup for a new RCMD proxy.
43 int ippr_rcmd_new(fin, ip, aps, nat)
49 tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp;
51 aps->aps_psiz = sizeof(u_32_t);
52 KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t));
53 if (aps->aps_data == NULL)
55 *(u_32_t *)aps->aps_data = 0;
56 aps->aps_sport = tcp->th_sport;
57 aps->aps_dport = tcp->th_dport;
63 * ipf_rcmd_atoi - implement a simple version of atoi
65 u_short ipf_rcmd_atoi(ptr)
71 while ((c = *s++) && isdigit(c)) {
79 int ippr_rcmd_portmsg(fin, ip, aps, nat)
88 tcphdr_t *tcp, tcph, *tcp2 = &tcph;
94 tcp = (tcphdr_t *)fin->fin_dp;
96 if (tcp->th_flags & TH_SYN) {
97 *(u_32_t *)aps->aps_data = htonl(ntohl(tcp->th_seq) + 1);
101 if ((*(u_32_t *)aps->aps_data != 0) &&
102 (tcp->th_seq != *(u_32_t *)aps->aps_data))
105 off = fin->fin_hlen + (tcp->th_off << 2);
110 dlen = msgdsize(m) - off;
111 bzero(portbuf, sizeof(portbuf));
112 copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
114 m = *(mb_t **)fin->fin_mp;
115 dlen = mbufchainlen(m) - off;
116 bzero(portbuf, sizeof(portbuf));
117 m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
120 portbuf[sizeof(portbuf) - 1] = '\0';
122 sp = ipf_rcmd_atoi(s);
127 * Add skeleton NAT entry for connection which will come back the
130 bcopy((char *)fin, (char *)&fi, sizeof(fi));
132 fi.fin_data[1] = fin->fin_data[1];
133 ipn = nat_outlookup(&fi, IPN_TCP, nat->nat_p, nat->nat_inip,
139 ip->ip_len = fin->fin_hlen + sizeof(*tcp);
140 bzero((char *)tcp2, sizeof(*tcp2));
141 tcp2->th_win = htons(8192);
142 tcp2->th_sport = htons(sp);
143 tcp2->th_dport = 0; /* XXX - don't specify remote port */
145 tcp2->th_flags = TH_SYN;
147 fi.fin_dp = (char *)tcp2;
148 fi.fin_dlen = sizeof(*tcp2);
150 ip->ip_src = nat->nat_inip;
151 ipn = nat_new(&fi, ip, nat->nat_ptr, NULL, IPN_TCP|FI_W_DPORT,
154 ipn->nat_age = fr_defnatage;
156 (void) fr_addstate(ip, &fi, NULL,
157 FI_W_DPORT|FI_IGNOREPKT);
166 int ippr_rcmd_out(fin, ip, aps, nat)
172 return ippr_rcmd_portmsg(fin, ip, aps, nat);