20 #include <linux/module.h>
21 #include <linux/tcp.h>
31 #define NF_NAT_PPTP_VERSION "3.0"
33 #define REQ_CID(req, off) (*(__be16 *)((char *)(req) + (off)))
40 static void pptp_nat_expected(
struct nf_conn *
ct,
43 struct net *
net = nf_ct_net(ct);
51 ct_pptp_info = nfct_help_data(master);
52 nat_pptp_info = &nfct_nat(master)->help.nat_pptp_info;
59 t.src.u3.ip = master->
tuplehash[!exp->dir].tuple.src.u3.ip;
60 t.src.u.gre.key = ct_pptp_info->pac_call_id;
61 t.dst.u3.ip = master->
tuplehash[!exp->dir].tuple.dst.u3.ip;
62 t.dst.u.gre.key = ct_pptp_info->pns_call_id;
68 t.src.u3.ip = master->
tuplehash[!exp->dir].tuple.src.u3.ip;
70 t.dst.u3.ip = master->
tuplehash[!exp->dir].tuple.dst.u3.ip;
75 pr_debug(
"trying to unexpect other dir: ");
76 nf_ct_dump_tuple_ip(&
t);
92 = ct->
master->tuplehash[!exp->dir].tuple.dst.u3;
95 range.min_proto =
range.max_proto = exp->saved_proto;
102 = ct->
master->tuplehash[!exp->dir].tuple.src.u3;
105 range.min_proto =
range.max_proto = exp->saved_proto;
115 unsigned int protoff,
116 struct PptpControlHeader *ctlh,
117 union pptp_ctrl_union *pptpReq)
124 unsigned int cid_off;
126 ct_pptp_info = nfct_help_data(ct);
127 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
131 switch (msg =
ntohs(ctlh->messageType)) {
132 case PPTP_OUT_CALL_REQUEST:
133 cid_off =
offsetof(
union pptp_ctrl_union, ocreq.callID);
149 case PPTP_IN_CALL_REPLY:
150 cid_off =
offsetof(
union pptp_ctrl_union, icack.callID);
152 case PPTP_CALL_CLEAR_REQUEST:
153 cid_off =
offsetof(
union pptp_ctrl_union, clrreq.callID);
156 pr_debug(
"unknown outbound packet 0x%04x:%s\n", msg,
157 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
160 case PPTP_SET_LINK_INFO:
162 case PPTP_START_SESSION_REQUEST:
163 case PPTP_START_SESSION_REPLY:
164 case PPTP_STOP_SESSION_REQUEST:
165 case PPTP_STOP_SESSION_REPLY:
166 case PPTP_ECHO_REQUEST:
167 case PPTP_ECHO_REPLY:
174 pr_debug(
"altering call id from 0x%04x to 0x%04x\n",
178 if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff,
179 cid_off +
sizeof(
struct pptp_pkt_hdr) +
180 sizeof(
struct PptpControlHeader),
181 sizeof(new_callid), (
char *)&new_callid,
182 sizeof(new_callid)) == 0)
195 ct_pptp_info = nfct_help_data(ct);
196 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
202 expect_orig->saved_proto.gre.key = ct_pptp_info->
pns_call_id;
208 expect_reply->saved_proto.gre.key = nat_pptp_info->
pns_call_id;
216 pptp_inbound_pkt(
struct sk_buff *skb,
219 unsigned int protoff,
220 struct PptpControlHeader *ctlh,
221 union pptp_ctrl_union *pptpReq)
226 unsigned int pcid_off;
228 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
231 switch (msg =
ntohs(ctlh->messageType)) {
232 case PPTP_OUT_CALL_REPLY:
233 pcid_off =
offsetof(
union pptp_ctrl_union, ocack.peersCallID);
235 case PPTP_IN_CALL_CONNECT:
236 pcid_off =
offsetof(
union pptp_ctrl_union, iccon.peersCallID);
238 case PPTP_IN_CALL_REQUEST:
241 case PPTP_WAN_ERROR_NOTIFY:
242 pcid_off =
offsetof(
union pptp_ctrl_union, wanerr.peersCallID);
244 case PPTP_CALL_DISCONNECT_NOTIFY:
245 pcid_off =
offsetof(
union pptp_ctrl_union, disc.callID);
247 case PPTP_SET_LINK_INFO:
248 pcid_off =
offsetof(
union pptp_ctrl_union, setlink.peersCallID);
251 pr_debug(
"unknown inbound packet %s\n",
252 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
255 case PPTP_START_SESSION_REQUEST:
256 case PPTP_START_SESSION_REPLY:
257 case PPTP_STOP_SESSION_REQUEST:
258 case PPTP_STOP_SESSION_REPLY:
259 case PPTP_ECHO_REQUEST:
260 case PPTP_ECHO_REPLY:
269 pr_debug(
"altering peer call id from 0x%04x to 0x%04x\n",
272 if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff,
273 pcid_off +
sizeof(
struct pptp_pkt_hdr) +
274 sizeof(
struct PptpControlHeader),
275 sizeof(new_pcid), (
char *)&new_pcid,
276 sizeof(new_pcid)) == 0)
281 static int __init nf_nat_helper_pptp_init(
void)
299 static void __exit nf_nat_helper_pptp_fini(
void)