From a243f217f1c6ac1aa7793806bc88590d077f490a Mon Sep 17 00:00:00 2001 From: Bertram Felgenhauer Date: Thu, 2 Jan 2014 15:20:35 +1100 Subject: [PATCH] pppd: Accept IPCP ConfAck packets containing MS-WINS options Since last week I'm seeing IPCP negotiations going like this (and eventually failing) when connecting to my ISP: Jul 11 20:03:25 * pppd[4833]: sent [IPCP ConfReq id=0x2 ] Jul 11 20:03:26 * pppd[4833]: sent [IPCP ConfReq id=0x2 ] Jul 11 20:03:26 * pppd[4833]: rcvd [IPCP ConfNak id=0x2 ] Jul 11 20:03:26 * pppd[4833]: sent [IPCP ConfReq id=0x3 ] Jul 11 20:03:26 * pppd[4833]: rcvd [IPCP ConfAck id=0x3 ] Jul 11 20:03:27 * pppd[4833]: sent [IPCP ConfReq id=0x3 ] ... with the last two lines repeating until the IPCP error limit is reached. As you can see, the peer added two extra fields in the ConfNak reply. This is allowed, and indeed the following sent ConfReq packet reflects this. However, when the ConfAck packet is received, pppd discards it as invalid, because of the ms-wins fields. This fixes it. Signed-off-by: Paul Mackerras --- pppd/ipcp.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pppd/ipcp.c b/pppd/ipcp.c index 12bcc61..e9738fe 100644 --- a/pppd/ipcp.c +++ b/pppd/ipcp.c @@ -962,6 +962,21 @@ ipcp_ackci(f, p, len) goto bad; \ } +#define ACKCIWINS(opt, addr) \ + if (addr) { \ + u_int32_t l; \ + if ((len -= CILEN_ADDR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDR || citype != opt) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (addr != cilong) \ + goto bad; \ + } + ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, go->hisaddr); @@ -974,6 +989,10 @@ ipcp_ackci(f, p, len) ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]); + + ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]); + /* * If there are any remaining CIs, then this packet is bad. */ -- 2.39.2