Files
main/network/connection/ppp/files/gentoo/0010-Add-option-to-ask-peer-for-WINS-address.patch
2021-02-25 23:07:43 +03:00

277 lines
8.8 KiB
Diff

From 369a393c957cc610e07e4bf4f07230eaf515b302 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Fri, 3 Jan 2020 17:19:40 +0100
Subject: [PATCH 10/14] Add option to ask peer for WINS address
---
pppd/ipcp.c | 79 ++++++++++++++++++++++++++++++++++++++++-------------
pppd/ipcp.h | 2 ++
pppd/pppd.8 | 19 +++++++++++++
3 files changed, 81 insertions(+), 19 deletions(-)
diff --git a/pppd/ipcp.c b/pppd/ipcp.c
index 302ca40..7db5156 100644
--- a/pppd/ipcp.c
+++ b/pppd/ipcp.c
@@ -89,6 +89,7 @@ struct notifier *ip_down_notifier = NULL;
static int default_route_set[NUM_PPP]; /* Have set up a default route */
static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */
static bool usepeerdns; /* Ask peer for DNS addrs */
+static bool usepeerwins; /* Ask peer for WINS addrs */
static int ipcp_is_up; /* have called np_up() */
static int ipcp_is_open; /* haven't called np_finished() */
static bool ask_for_local; /* request our address from peer */
@@ -217,6 +218,9 @@ static option_t ipcp_option_list[] = {
{ "usepeerdns", o_bool, &usepeerdns,
"Ask peer for DNS address(es)", 1 },
+ { "usepeerwins", o_bool, &usepeerwins,
+ "Ask peer for WINS address(es)", 1 },
+
{ "netmask", o_special, (void *)setnetmask,
"set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str },
@@ -686,6 +690,8 @@ ipcp_resetci(fsm *f)
wo->accept_remote = 1;
wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */
wo->req_dns2 = usepeerdns;
+ wo->req_wins1 = usepeerwins; /* Request WINS addresses from the peer */
+ wo->req_wins2 = usepeerwins;
*go = *wo;
if (!ask_for_local)
go->ouraddr = 0;
@@ -737,8 +743,8 @@ ipcp_cilen(fsm *f)
LENCIADDR(go->neg_addr) +
LENCIDNS(go->req_dns1) +
LENCIDNS(go->req_dns2) +
- LENCIWINS(go->winsaddr[0]) +
- LENCIWINS(go->winsaddr[1])) ;
+ LENCIWINS(go->req_wins1) +
+ LENCIWINS(go->req_wins2)) ;
}
@@ -809,8 +815,8 @@ ipcp_addci(fsm *f, u_char *ucp, int *lenp)
neg = 0; \
}
-#define ADDCIWINS(opt, addr) \
- if (addr) { \
+#define ADDCIWINS(opt, neg, addr) \
+ if (neg) { \
if (len >= CILEN_ADDR) { \
u_int32_t l; \
PUTCHAR(opt, ucp); \
@@ -819,7 +825,7 @@ ipcp_addci(fsm *f, u_char *ucp, int *lenp)
PUTLONG(l, ucp); \
len -= CILEN_ADDR; \
} else \
- addr = 0; \
+ neg = 0; \
}
ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
@@ -834,9 +840,9 @@ ipcp_addci(fsm *f, u_char *ucp, int *lenp)
ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
- ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+ ADDCIWINS(CI_MS_WINS1, go->req_wins1, go->winsaddr[0]);
- ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+ ADDCIWINS(CI_MS_WINS2, go->req_wins2, go->winsaddr[1]);
*lenp -= len;
}
@@ -938,8 +944,8 @@ ipcp_ackci(fsm *f, u_char *p, int len)
goto bad; \
}
-#define ACKCIWINS(opt, addr) \
- if (addr) { \
+#define ACKCIWINS(opt, neg, addr) \
+ if (neg) { \
u_int32_t l; \
if ((len -= CILEN_ADDR) < 0) \
goto bad; \
@@ -965,9 +971,9 @@ ipcp_ackci(fsm *f, u_char *p, int len)
ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
- ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+ ACKCIWINS(CI_MS_WINS1, go->req_wins1, go->winsaddr[0]);
- ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+ ACKCIWINS(CI_MS_WINS2, go->req_wins2, go->winsaddr[1]);
/*
* If there are any remaining CIs, then this packet is bad.
@@ -998,7 +1004,7 @@ ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
u_char cimaxslotindex, cicflag;
u_char citype, cilen, *next;
u_short cishort;
- u_int32_t ciaddr1, ciaddr2, l, cidnsaddr;
+ u_int32_t ciaddr1, ciaddr2, l, cidnsaddr, ciwinsaddr;
ipcp_options no; /* options we've seen Naks for */
ipcp_options try; /* options to request next time */
@@ -1063,6 +1069,19 @@ ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
code \
}
+#define NAKCIWINS(opt, neg, code) \
+ if (go->neg && \
+ ((cilen = p[1]) == CILEN_ADDR) && \
+ len >= cilen && \
+ p[0] == opt) { \
+ len -= cilen; \
+ INCPTR(2, p); \
+ GETLONG(l, p); \
+ ciwinsaddr = htonl(l); \
+ no.neg = 1; \
+ code \
+ }
+
/*
* Accept the peer's idea of {our,his} address, if different
* from our idea, only if the accept_{local,remote} flag is set.
@@ -1139,6 +1158,22 @@ ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
}
);
+ NAKCIWINS(CI_MS_WINS1, req_wins1,
+ if (treat_as_reject) {
+ try.req_wins1 = 0;
+ } else {
+ try.winsaddr[0] = ciwinsaddr;
+ }
+ );
+
+ NAKCIWINS(CI_MS_WINS2, req_wins2,
+ if (treat_as_reject) {
+ try.req_wins2 = 0;
+ } else {
+ try.winsaddr[1] = ciwinsaddr;
+ }
+ );
+
/*
* There may be remaining CIs, if the peer is requesting negotiation
* on an option that we didn't include in our request packet.
@@ -1231,7 +1266,6 @@ bad:
return 0;
}
-
/*
* ipcp_rejci - Reject some of our CIs.
* Callback from fsm_rconfnakrej.
@@ -1326,8 +1360,8 @@ ipcp_rejci(fsm *f, u_char *p, int len)
try.neg = 0; \
}
-#define REJCIWINS(opt, addr) \
- if (addr && \
+#define REJCIWINS(opt, neg, addr) \
+ if (go->neg && \
((cilen = p[1]) == CILEN_ADDR) && \
len >= cilen && \
p[0] == opt) { \
@@ -1339,7 +1373,7 @@ ipcp_rejci(fsm *f, u_char *p, int len)
/* Check rejected value. */ \
if (cilong != addr) \
goto bad; \
- try.winsaddr[opt == CI_MS_WINS2] = 0; \
+ try.neg = 0; \
}
REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
@@ -1354,9 +1388,9 @@ ipcp_rejci(fsm *f, u_char *p, int len)
REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
- REJCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+ REJCIWINS(CI_MS_WINS1, req_wins1, go->winsaddr[0]);
- REJCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+ REJCIWINS(CI_MS_WINS2, req_wins2, go->winsaddr[1]);
/*
* If there are any remaining CIs, then this packet is bad.
@@ -1546,7 +1580,7 @@ ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
/* Microsoft primary or secondary WINS request */
d = citype == CI_MS_WINS2;
- /* If we do not have a DNS address then we cannot send it */
+ /* If we do not have a WINS address then we cannot send it */
if (ao->winsaddr[d] == 0 ||
cilen != CILEN_ADDR) { /* Check CI length */
orc = CONFREJ; /* Reject CI */
@@ -1795,6 +1829,13 @@ ipcp_up(fsm *f)
create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
}
+ if (go->winsaddr[0])
+ script_setenv("WINS1", ip_ntoa(go->winsaddr[0]), 0);
+ if (go->winsaddr[1])
+ script_setenv("WINS2", ip_ntoa(go->winsaddr[1]), 0);
+ if (usepeerwins && (go->winsaddr[0] || go->winsaddr[1]))
+ script_setenv("USEPEERWINS", "1", 0);
+
/*
* Check that the peer is allowed to use the IP address it wants.
*/
diff --git a/pppd/ipcp.h b/pppd/ipcp.h
index 9c4f68d..2ec8190 100644
--- a/pppd/ipcp.h
+++ b/pppd/ipcp.h
@@ -76,6 +76,8 @@ typedef struct ipcp_options {
bool accept_remote; /* accept peer's value for hisaddr */
bool req_dns1; /* Ask peer to send primary DNS address? */
bool req_dns2; /* Ask peer to send secondary DNS address? */
+ bool req_wins1; /* Ask peer to send primary WINS address? */
+ bool req_wins2; /* Ask peer to send secondary WINS address? */
int vj_protocol; /* protocol value to use in VJ option */
int maxslotindex; /* values for RFC1332 VJ compression neg. */
bool cflag;
diff --git a/pppd/pppd.8 b/pppd/pppd.8
index fae91b2..bd188e4 100644
--- a/pppd/pppd.8
+++ b/pppd/pppd.8
@@ -1199,6 +1199,16 @@ USEPEERDNS will be set to 1. In addition, pppd will create an
/etc/ppp/resolv.conf file containing one or two nameserver lines with
the address(es) supplied by the peer.
.TP
+.B usepeerwins
+Ask the peer for up to 2 WINS server addresses. The addresses supplied
+by the peer (if any) are passed to the /etc/ppp/ip\-up script in the
+environment variables WINS1 and WINS2, and the environment variable
+USEPEERWINS will be set to 1.
+.LP
+Please note that some modems (like the Huawei E220) requires this option in
+order to avoid a race condition that results in the incorrect DNS servers
+being assigned.
+.TP
.B user \fIname
Sets the name used for authenticating the local system to the peer to
\fIname\fR.
@@ -1798,6 +1808,15 @@ option was given).
If the peer supplies DNS server addresses, this variable is set to the
second DNS server address supplied (whether or not the usepeerdns
option was given).
+.TP
+.B WINS1
+If the peer supplies WINS server addresses, this variable is set to the
+first WINS server address supplied.
+.TP
+.B WINS2
+If the peer supplies WINS server addresses, this variable is set to the
+second WINS server address supplied.
+.P
.P
Pppd invokes the following scripts, if they exist. It is not an error
if they don't exist.
--
2.30.0