add a lot of debian fixes to ppp (should fix persist and demand, too), clean up patches

git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@1417 3c298f89-4303-0410-b956-a3cf2f4a3e73
master
Felix Fietkau 2005-07-12 09:38:18 +00:00
parent 96e5e35126
commit dc40819709
18 changed files with 1845 additions and 1 deletions

View File

@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=ppp
PKG_VERSION:=2.4.3
PKG_RELEASE:=4
PKG_RELEASE:=5
PKG_MD5SUM:=848f6c3cafeb6074ffeb293c3af79b7c
PKG_SOURCE_URL:=ftp://ftp.samba.org/pub/ppp/

View File

@ -0,0 +1,34 @@
From: Simon Peter <dn.tlp@gmx.net>
Subject: Bug#306261: pppd does not properly close /dev/ppp on persist
When using the kernel PPPoE driver, pppd never
closes /dev/ppp when the link has come down.
It opens superfluous fds to the device each time it re-opens the
connection, with the unclosed ones falsely reported always ready for
data by select().
This makes pppd eat up 100% CPU time after the first persist because of
the always instantly returning select() on the unclosed fds.
The problem also occurs with the upstream version, but does not occur
when a pty/tty device is used for the ppp connection.
diff -u -r ppp-2.4.3/pppd/sys-linux.c ppp-2.4.3/pppd/sys-linux.c
--- ppp-2.4.3/pppd/sys-linux.c 2005-04-29 20:08:37.000000000 +0200
+++ ppp-2.4.3/pppd/sys-linux.c 2005-04-29 20:07:03.000000000 +0200
@@ -455,6 +455,13 @@
if (new_style_driver) {
int flags;
+ /* if a ppp_fd is already open, close it first */
+ if(ppp_fd > 0) {
+ close(ppp_fd);
+ remove_fd(ppp_fd);
+ ppp_fd = -1;
+ }
+
/* Open an instance of /dev/ppp and connect the channel to it */
if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
error("Couldn't get channel number: %m");

View File

@ -0,0 +1,88 @@
diff -ruNp ppp-2.4.3.orig/pppd/ipcp.c ppp-2.4.3/pppd/ipcp.c
--- ppp-2.4.3.orig/pppd/ipcp.c 2004-11-13 13:03:26.000000000 +0100
+++ ppp-2.4.3/pppd/ipcp.c 2005-02-20 18:45:22.241810136 +0100
@@ -1846,7 +1846,7 @@ ipcp_up(f)
*/
if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
ipcp_script_state = s_up;
- ipcp_script(_PATH_IPUP);
+ ipcp_script(path_ipup);
}
}
@@ -1896,7 +1896,7 @@ ipcp_down(f)
/* Execute the ip-down script */
if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
ipcp_script_state = s_down;
- ipcp_script(_PATH_IPDOWN);
+ ipcp_script(path_ipdown);
}
}
@@ -1950,13 +1950,13 @@ ipcp_script_done(arg)
case s_up:
if (ipcp_fsm[0].state != OPENED) {
ipcp_script_state = s_down;
- ipcp_script(_PATH_IPDOWN);
+ ipcp_script(path_ipdown);
}
break;
case s_down:
if (ipcp_fsm[0].state == OPENED) {
ipcp_script_state = s_up;
- ipcp_script(_PATH_IPUP);
+ ipcp_script(path_ipup);
}
break;
}
diff -ruNp ppp-2.4.3.orig/pppd/main.c ppp-2.4.3/pppd/main.c
--- ppp-2.4.3.orig/pppd/main.c 2005-02-20 18:46:14.409879384 +0100
+++ ppp-2.4.3/pppd/main.c 2005-02-20 18:45:22.243809832 +0100
@@ -314,6 +314,9 @@ main(argc, argv)
struct protent *protp;
char numbuf[16];
+ strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
+ strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
+
link_stats_valid = 0;
new_phase(PHASE_INITIALIZE);
diff -ruNp ppp-2.4.3.orig/pppd/options.c ppp-2.4.3/pppd/options.c
--- ppp-2.4.3.orig/pppd/options.c 2005-02-20 18:46:14.410879232 +0100
+++ ppp-2.4.3/pppd/options.c 2005-02-20 18:46:02.154742448 +0100
@@ -108,6 +108,8 @@ char linkname[MAXPATHLEN]; /* logical na
bool tune_kernel; /* may alter kernel settings */
int connect_delay = 1000; /* wait this many ms after connect script */
int req_unit = -1; /* requested interface unit */
+char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
bool multilink = 0; /* Enable multilink operation */
char *bundle_name = NULL; /* bundle name for multilink */
bool dump_options; /* print out option values */
@@ -276,6 +278,13 @@ option_t general_options[] = {
"Number of seconds to wait for child processes at exit",
OPT_PRIO },
+ { "ip-up-script", o_string, path_ipup,
+ "Set pathname of ip-up script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+ { "ip-down-script", o_string, path_ipdown,
+ "Set pathname of ip-down script",
+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+
#ifdef HAVE_MULTILINK
{ "multilink", o_bool, &multilink,
"Enable multilink operation", OPT_PRIO | 1 },
diff -ruNp ppp-2.4.3.orig/pppd/pppd.h ppp-2.4.3/pppd/pppd.h
--- ppp-2.4.3.orig/pppd/pppd.h 2005-02-20 18:46:14.414878624 +0100
+++ ppp-2.4.3/pppd/pppd.h 2005-02-20 18:45:22.247809224 +0100
@@ -312,6 +312,8 @@ extern bool tune_kernel; /* May alter ke
extern int connect_delay; /* Time to delay after connect script */
extern int max_data_rate; /* max bytes/sec through charshunt */
extern int req_unit; /* interface unit number to use */
+extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
extern bool multilink; /* enable multilink operation */
extern bool noendpoint; /* don't send or accept endpt. discrim. */
extern char *bundle_name; /* bundle name for multilink */

View File

@ -0,0 +1,14 @@
diff -ruNp ppp-2.4.3.orig/pppd/plugins/rp-pppoe/discovery.c ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c
--- ppp-2.4.3.orig/pppd/plugins/rp-pppoe/discovery.c 2004-11-04 11:07:37.000000000 +0100
+++ ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c 2005-02-24 21:00:11.586697752 +0100
@@ -365,8 +365,8 @@ waitForPADO(PPPoEConnection *conn, int t
if (!packetIsForMe(conn, &packet)) continue;
if (packet.code == CODE_PADO) {
- if (NOT_UNICAST(packet.ethHdr.h_source)) {
- printErr("Ignoring PADO packet from non-unicast MAC address");
+ if (BROADCAST(packet.ethHdr.h_source)) {
+ printErr("Ignoring PADO packet from broadcast MAC address");
continue;
}
parsePacket(&packet, parsePADOTags, &pc);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
Subject: Bug#284382: ppp: linkpidfile is not created upon detachment
From: <herbert@gondor.apana.org.au>
Package: ppp
Version: 2.4.2+20040428-2
Severity: wishlist
When pppd detaches from the parent normally, that is, without nodetach
or updetach set, the linkpidfile is not created even when linkname is
set.
This is because the create_linkpidfile call in detach() is only made
if the linkpidfile is filled in. However, linkpidfile is never filled
in until create_linkpidfile has been called.
IMHO the call should be made uncondtionally in detach() since
create_linkpidfile does its own check on linkname anyway.
Please note that the version of pppd in woody always wrote the
linkpidfile after detaching. It did so in main() however. That
call has now been removed which is why I'm seeing this problem.
[...]
--
Index: pppd/main.c
===================================================================
RCS file: /var/cvs/snwb/packages/ppp/pppd/main.c,v
retrieving revision 1.11
diff -u -r1.11 main.c
--- ppp/pppd/main.c 29 Nov 2004 22:49:23 -0000 1.11
+++ ppp/pppd/main.c 5 Dec 2004 23:59:58 -0000
@@ -819,8 +819,7 @@
/* update pid files if they have been written already */
if (pidfilename[0])
create_pidfile(pid);
- if (linkpidfile[0])
- create_linkpidfile(pid);
+ create_linkpidfile(pid);
exit(0); /* parent dies */
}
setsid();

View File

@ -0,0 +1,95 @@
diff -ruNp ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c
--- ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c 2005-03-22 14:44:18.000000000 +0100
+++ ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c 2005-03-22 14:44:02.000000000 +0100
@@ -70,18 +70,20 @@ static int setdevname_pppoatm(const char
{
struct sockaddr_atmpvc addr;
extern struct stat devstat;
+
if (device_got_set)
return 0;
- //info("PPPoATM setdevname_pppoatm: '%s'", cp);
+
memset(&addr, 0, sizeof addr);
if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr),
T2A_PVC | T2A_NAME) < 0) {
- if(doit)
- info("atm does not recognize: %s", cp);
+ if (doit)
+ info("cannot parse the ATM address: %s", cp);
return 0;
- }
- if (!doit) return 1;
- //if (!dev_set_ok()) return -1;
+ }
+ if (!doit)
+ return 1;
+
memcpy(&pvcaddr, &addr, sizeof pvcaddr);
strlcpy(devnam, cp, sizeof devnam);
devstat.st_mode = S_IFSOCK;
@@ -93,7 +95,6 @@ static int setdevname_pppoatm(const char
lcp_allowoptions[0].neg_asyncmap = 0;
lcp_wantoptions[0].neg_pcompression = 0;
}
- info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp);
device_got_set = 1;
return 1;
}
@@ -108,6 +109,7 @@ static void no_device_given_pppoatm(void
static void set_line_discipline_pppoatm(int fd)
{
struct atm_backend_ppp be;
+
be.backend_num = ATM_BACKEND_PPP;
if (!llc_encaps)
be.encaps = PPPOATM_ENCAPS_VC;
@@ -115,6 +117,7 @@ static void set_line_discipline_pppoatm(
be.encaps = PPPOATM_ENCAPS_LLC;
else
be.encaps = PPPOATM_ENCAPS_AUTODETECT;
+
if (ioctl(fd, ATM_SETBACKEND, &be) < 0)
fatal("ioctl(ATM_SETBACKEND): %m");
}
@@ -179,16 +182,19 @@ static void send_config_pppoa(int mtu,
{
int sock;
struct ifreq ifr;
+
if (mtu > pppoatm_max_mtu)
error("Couldn't increase MTU to %d", mtu);
+
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
fatal("Couldn't create IP socket: %m");
+
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
ifr.ifr_mtu = mtu;
if (ioctl(sock, SIOCSIFMTU, (caddr_t) &ifr) < 0)
fatal("ioctl(SIOCSIFMTU): %m");
- (void) close (sock);
+ close(sock);
}
static void recv_config_pppoa(int mru,
@@ -202,7 +208,7 @@ static void recv_config_pppoa(int mru,
void plugin_init(void)
{
-#if defined(__linux__)
+#ifdef linux
extern int new_style_driver; /* From sys-linux.c */
if (!ppp_available() && !new_style_driver)
fatal("Kernel doesn't support ppp_generic - "
@@ -210,9 +216,9 @@ void plugin_init(void)
#else
fatal("No PPPoATM support on this OS");
#endif
- info("PPPoATM plugin_init");
add_options(pppoa_options);
}
+
struct channel pppoa_channel = {
options: pppoa_options,
process_extra_options: NULL,

View File

@ -0,0 +1,31 @@
diff -ruNp ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c
--- ppp-2.4.3.orig/pppd/plugins/pppoatm/pppoatm.c 2005-05-04 02:00:28.000000000 +0200
+++ ppp-2.4.3/pppd/plugins/pppoatm/pppoatm.c 2005-05-04 01:59:11.000000000 +0200
@@ -183,8 +183,11 @@ static void send_config_pppoa(int mtu,
int sock;
struct ifreq ifr;
- if (mtu > pppoatm_max_mtu)
- error("Couldn't increase MTU to %d", mtu);
+ if (pppoatm_max_mtu && mtu > pppoatm_max_mtu) {
+ warn("Couldn't increase MTU to %d. Using %d",
+ mtu, pppoatm_max_mtu);
+ mtu = pppoatm_max_mtu;
+ }
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
@@ -202,8 +205,11 @@ static void recv_config_pppoa(int mru,
int pcomp,
int accomp)
{
- if (mru > pppoatm_max_mru)
- error("Couldn't increase MRU to %d", mru);
+ if (pppoatm_max_mru && mru > pppoatm_max_mru) {
+ warn("Couldn't increase MRU to %d. Using %d",
+ mru, pppoatm_max_mru);
+ mru = pppoatm_max_mru;
+ }
}
void plugin_init(void)

View File

@ -0,0 +1,35 @@
diff -ruN ppp.orig/pppd/chap-new.c ppp/pppd/chap-new.c
--- ppp.orig/pppd/chap-new.c 2003-11-27 23:25:17.000000000 +0100
+++ ppp/pppd/chap-new.c 2003-12-02 12:26:21.000000000 +0100
@@ -57,6 +57,7 @@
int chap_timeout_time = 3;
int chap_max_transmits = 10;
int chap_rechallenge_time = 0;
+int chapms_strip_domain = 0;
/*
* Command-line options.
@@ -68,6 +69,8 @@
"Set max #xmits for challenge", OPT_PRIO },
{ "chap-interval", o_int, &chap_rechallenge_time,
"Set interval for rechallenge", OPT_PRIO },
+ { "chapms-strip-domain", o_bool, &chapms_strip_domain,
+ "Strip the domain prefix before the Username", 1 },
{ NULL }
};
@@ -338,6 +341,14 @@
/* Null terminate and clean remote name. */
slprintf(rname, sizeof(rname), "%.*v", len, name);
name = rname;
+
+ /* strip the MS domain name */
+ if (chapms_strip_domain && strrchr(rname, '\\')) {
+ char tmp[MAXNAMELEN+1];
+
+ strcpy(tmp, strrchr(rname, '\\') + 1);
+ strcpy(rname, tmp);
+ }
}
if (chap_verify_hook)

View File

@ -0,0 +1,253 @@
--- ppp/pppd/ipcp.c Wed May 31 17:20:41 2000
+++ ppp/pppd/ipcp.c Wed May 31 17:27:19 2000
@@ -145,7 +145,17 @@
{ "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
"disable defaultroute option", OPT_A2COPY,
&ipcp_wantoptions[0].default_route },
+#ifdef __linux__
+ { "replacedefaultroute", o_bool,
+ &ipcp_wantoptions[0].replace_default_route,
+ "Replace default route", 1
+ },
+ { "noreplacedefaultroute", o_bool,
+ &ipcp_allowoptions[0].replace_default_route,
+ "Never replace default route", OPT_A2COPY,
+ &ipcp_wantoptions[0].replace_default_route },
+#endif
{ "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
"Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
{ "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
@@ -195,7 +205,7 @@
ip_active_pkt
};
-static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
+static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool));
static void ipcp_script __P((char *)); /* Run an up/down script */
static void ipcp_script_done __P((void *));
@@ -1344,7 +1354,12 @@
if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
return 0;
if (wo->default_route)
+#ifndef __linux__
if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
+#else
+ if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
+ wo->replace_default_route))
+#endif
default_route_set[u] = 1;
if (wo->proxy_arp)
if (sifproxyarp(u, wo->hisaddr))
@@ -1420,7 +1435,8 @@
*/
if (demand) {
if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
- ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
+ ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
+ wo->replace_default_route);
if (go->ouraddr != wo->ouraddr) {
warn("Local IP address changed to %I", go->ouraddr);
script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr));
@@ -1445,7 +1461,12 @@
/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
+#ifndef __linux__
if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
+#else
+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
+ wo->replace_default_route))
+#endif
default_route_set[f->unit] = 1;
/* Make a proxy ARP entry if requested. */
@@ -1492,7 +1513,12 @@
/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
+#ifndef __linux__
if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
+#else
+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
+ wo->replace_default_route))
+#endif
default_route_set[f->unit] = 1;
/* Make a proxy ARP entry if requested. */
@@ -1559,7 +1585,7 @@
sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
sifdown(f->unit);
ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
- ipcp_hisoptions[f->unit].hisaddr);
+ ipcp_hisoptions[f->unit].hisaddr, 0);
}
/* Execute the ip-down script */
@@ -1575,16 +1601,25 @@
* proxy arp entries, etc.
*/
static void
-ipcp_clear_addrs(unit, ouraddr, hisaddr)
+ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute)
int unit;
u_int32_t ouraddr; /* local address */
u_int32_t hisaddr; /* remote address */
+ bool replacedefaultroute;
{
if (proxy_arp_set[unit]) {
cifproxyarp(unit, hisaddr);
proxy_arp_set[unit] = 0;
}
- if (default_route_set[unit]) {
+ /* If replacedefaultroute, sifdefaultroute will be called soon
+ * with replacedefaultroute set and that will overwrite the current
+ * default route. This is the case only when doing demand, otherwise
+ * during demand, this cifdefaultroute would restore the old default
+ * route which is not what we want in this case. In the non-demand
+ * case, we'll delete the default route and restore the old if there
+ * is one saved by an sifdefaultroute with replacedefaultroute.
+ */
+ if (!replacedefaultroute && default_route_set[unit]) {
cifdefaultroute(unit, ouraddr, hisaddr);
default_route_set[unit] = 0;
}
--- ppp/pppd/ipcp.h Wed May 31 17:20:41 2000
+++ ppp/pppd/ipcp.h Wed May 31 15:56:17 2000
@@ -47,6 +47,7 @@
bool old_addrs; /* Use old (IP-Addresses) option? */
bool req_addr; /* Ask peer to send IP address? */
bool default_route; /* Assign default route through interface? */
+ bool replace_default_route; /* Replace default route through interface? */
bool proxy_arp; /* Make proxy ARP entry for peer? */
bool neg_vj; /* Van Jacobson Compression? */
bool old_vj; /* use old (short) form of VJ option? */
--- ppp/pppd/pppd.h Wed May 31 17:20:41 2000
+++ ppp/pppd/pppd.h Wed May 31 15:56:17 2000
@@ -416,7 +416,11 @@
int cif6addr __P((int, eui64_t, eui64_t));
/* Remove an IPv6 address from i/f */
#endif
+#ifndef __linux__
int sifdefaultroute __P((int, u_int32_t, u_int32_t));
+#else
+int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt));
+#endif
/* Create default route through i/f */
int cifdefaultroute __P((int, u_int32_t, u_int32_t));
/* Delete default route through i/f */
--- ppp/pppd/sys-linux.c Wed May 31 17:20:41 2000
+++ ppp/pppd/sys-linux.c Wed May 31 17:37:23 2000
@@ -143,6 +143,8 @@
static int if_is_up; /* Interface has been marked up */
static u_int32_t default_route_gateway; /* Gateway for default route added */
+static struct rtentry old_def_rt; /* Old default route */
+static int default_rt_repl_rest; /* replace and restore old default rt */
static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
static char proxy_arp_dev[16]; /* Device for proxy arp entry */
static u_int32_t our_old_addr; /* for detecting address changes */
@@ -1209,6 +1211,9 @@
p = NULL;
}
+ SET_SA_FAMILY (rt->rt_dst, AF_INET);
+ SET_SA_FAMILY (rt->rt_gateway, AF_INET);
+
SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
@@ -1278,19 +1283,53 @@
/********************************************************************
*
* sifdefaultroute - assign a default route through the address given.
+ *
+ * If the global default_rt_repl_rest flag is set, then this function
+ * already replaced the original system defaultroute with some other
+ * route and it should just replace the current defaultroute with
+ * another one, without saving the current route. Use: demand mode,
+ * when pppd sets first a defaultroute it it's temporary ppp0 addresses
+ * and then changes the temporary addresses to the addresses for the real
+ * ppp connection when it has come up.
*/
-int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
+int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
{
- struct rtentry rt;
-
- if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
- u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway);
+ struct rtentry rt, tmp_rt;
+ struct rtentry *del_rt = NULL;
- if (old_gateway != gateway)
- error("not replacing existing default route to %s [%I]",
- rt.rt_dev, old_gateway);
- return 0;
+
+ if (default_rt_repl_rest) {
+ /* We have already reclaced the original defaultroute, if we
+ * are called again, we will delete the current default route
+ * and set the new default route in this function.
+ * - this is normally only the case the doing demand: */
+ if (defaultroute_exists( &tmp_rt ))
+ del_rt = &tmp_rt;
+ } else if ( defaultroute_exists( &old_def_rt ) &&
+ strcmp( old_def_rt.rt_dev, ifname ) != 0) {
+ /* We did not yet replace an existing default route, let's
+ * check if we should save and replace a default route:
+ */
+ u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
+
+ if (old_gateway != gateway) {
+ if (!replace) {
+ error("not replacing default route to %s [%I]",
+ old_def_rt.rt_dev, old_gateway);
+ return 0;
+ } else {
+ // we need to copy rt_dev because we need it permanent too:
+ char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
+ strcpy(tmp_dev, old_def_rt.rt_dev);
+ old_def_rt.rt_dev = tmp_dev;
+
+ notice("replacing old default route to %s [%I]",
+ old_def_rt.rt_dev, old_gateway);
+ default_rt_repl_rest = 1;
+ del_rt = &old_def_rt;
+ }
+ }
}
memset (&rt, '\0', sizeof (rt));
@@ -1310,6 +1349,12 @@
error("default route ioctl(SIOCADDRT): %m(%d)", errno);
return 0;
}
+ if (default_rt_repl_rest && del_rt)
+ if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
+ if ( ! ok_error ( errno ))
+ error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
+ return 0;
+ }
default_route_gateway = gateway;
return 1;
@@ -1344,6 +1389,16 @@
error("default route ioctl(SIOCDELRT): %m (%d)", errno);
return 0;
}
+ }
+ if (default_rt_repl_rest) {
+ notice("restoring old default route to %s [%I]",
+ old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
+ if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
+ if ( ! ok_error ( errno ))
+ error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
+ return 0;
+ }
+ default_rt_repl_rest = 0;
}
return 1;

View File

@ -0,0 +1,172 @@
--- ppp/pppd/demand.c
+++ ppp/pppd/demand.c 2000/06/28 14:54:04
@@ -25,6 +25,8 @@
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
+#include <unistd.h>
+#include <syslog.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -32,6 +34,8 @@
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#ifdef PPP_FILTER
#include <net/if.h>
#include <net/bpf.h>
@@ -210,6 +214,14 @@
int c, rv;
rv = 0;
+
+/* check for synchronous connection... */
+
+ if ( (p[0] == 0xFF) && (p[1] == 0x03) ) {
+ rv = loop_frame(p,n);
+ return rv;
+ }
+
for (; n > 0; --n) {
c = *p++;
if (c == PPP_FLAG) {
@@ -288,17 +300,102 @@
* loopback, now that the real serial link is up.
*/
void
-demand_rexmit(proto)
+demand_rexmit(proto, newip)
int proto;
+ u_int32_t newip;
{
struct packet *pkt, *prev, *nextpkt;
+ unsigned short checksum;
+ unsigned short pkt_checksum = 0;
+ unsigned iphdr;
+ struct timeval tv;
+ char cv = 0;
+ char ipstr[16];
prev = NULL;
pkt = pend_q;
pend_q = NULL;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */
for (; pkt != NULL; pkt = nextpkt) {
nextpkt = pkt->next;
if (PPP_PROTOCOL(pkt->data) == proto) {
+ if ( (proto == PPP_IP) && newip ) {
+ /* Get old checksum */
+
+ iphdr = (pkt->data[4] & 15) << 2;
+ checksum = *((unsigned short *) (pkt->data+14));
+ if (checksum == 0xFFFF) {
+ checksum = 0;
+ }
+
+
+ if (pkt->data[13] == 17) {
+ pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr));
+ if (pkt_checksum) {
+ cv = 1;
+ if (pkt_checksum == 0xFFFF) {
+ pkt_checksum = 0;
+ }
+ }
+ else {
+ cv = 0;
+ }
+ }
+
+ if (pkt->data[13] == 6) {
+ pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr));
+ cv = 1;
+ if (pkt_checksum == 0xFFFF) {
+ pkt_checksum = 0;
+ }
+ }
+
+ /* Delete old Source-IP-Address */
+ checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ /* Change Source-IP-Address */
+ * ((u_int32_t *) (pkt->data + 16)) = newip;
+
+ /* Add new Source-IP-Address */
+ checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF;
+ pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF;
+
+ /* Write new checksum */
+ if (!checksum) {
+ checksum = 0xFFFF;
+ }
+ *((unsigned short *) (pkt->data+14)) = checksum;
+ if (pkt->data[13] == 6) {
+ *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum;
+ }
+ if (cv && (pkt->data[13] == 17) ) {
+ *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum;
+ }
+
+ /* Log Packet */
+ strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16))));
+ if (pkt->data[13] == 1) {
+ syslog(LOG_INFO,"Open ICMP %s -> %s\n",
+ ipstr,
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20))));
+ } else {
+ syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n",
+ pkt->data[13] == 6 ? "TCP" : "UDP",
+ ipstr,
+ ntohs(*( (short *) (pkt->data+iphdr+4))),
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20))),
+ ntohs(*( (short *) (pkt->data+iphdr+6))));
+ }
+ }
output(0, pkt->data, pkt->length);
free(pkt);
} else {
--- ppp/pppd/ipcp.c
+++ ppp/pppd/ipcp.c 2000/06/28 12:32:05
@@ -1454,7 +1454,7 @@
proxy_arp_set[f->unit] = 1;
}
- demand_rexmit(PPP_IP);
+ demand_rexmit(PPP_IP,go->ouraddr);
sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
} else {
--- ppp/pppd/ipv6cp.c
+++ ppp/pppd/ipv6cp.c 2000/06/28 12:32:06
@@ -1153,7 +1153,7 @@
}
}
- demand_rexmit(PPP_IPV6);
+ demand_rexmit(PPP_IPV6,0);
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
} else {
--- ppp/pppd/pppd.h
+++ ppp/pppd/pppd.h 2000/06/28 12:32:06
@@ -359,7 +359,7 @@
void demand_block __P((void)); /* set all NPs to queue up packets */
void demand_unblock __P((void)); /* set all NPs to pass packets */
void demand_discard __P((void)); /* set all NPs to discard packets */
-void demand_rexmit __P((int)); /* retransmit saved frames for an NP */
+void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/
int loop_chars __P((unsigned char *, int)); /* process chars from loopback */
int loop_frame __P((unsigned char *, int)); /* should we bring link up? */