--- iface.c.orig	2008-12-18 11:47:00.000000000 +0300
+++ iface.c	2008-12-19 11:23:33.000000000 +0300
@@ -172,6 +172,7 @@
     { 0,	IFACE_CONF_NETFLOW_IN,		"netflow-in"	},
     { 0,	IFACE_CONF_NETFLOW_OUT,		"netflow-out"	},
     { 0,	IFACE_CONF_IPACCT,		"ipacct"	},
+    { 0,	IFACE_EXEC_ENV,			"execenv"	},
     { 0,	0,				NULL		},
   };
 
@@ -817,11 +818,15 @@ IfaceIpIfaceUp(Bund b, int ready)
 	else
     	    ns2buf[0] = '\0';
 
-	res = ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' %s %s",
+	if(Enabled(&iface->options, IFACE_EXEC_ENV)){
+            res = ExecCmdEnv(LG_IFACE2, b, iface->up_script);
+        } else {
+	    res = ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' %s %s",
 	    iface->up_script, iface->ifname, u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)),
     	    u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), 
     	    *b->params.authname ? b->params.authname : "-", 
     	    ns1buf, ns2buf);
+	}
 	if (res != 0) {
 	    FsmFailure(&b->ipcp.fsm, FAIL_NEGOT_FAILURE);
 	    return (-1);
@@ -847,10 +852,14 @@ IfaceIpIfaceDown(Bund b)
     if (*iface->down_script) {
 	char	selfbuf[40],peerbuf[40];
 
-	ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s'",
-    	    iface->down_script, iface->ifname, u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)),
-    	    u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), 
-    	    *b->params.authname ? b->params.authname : "-");
+        if(Enabled(&iface->options, IFACE_EXEC_ENV)){
+           ExecCmdEnv(LG_IFACE2, b, iface->down_script);
+        } else {
+	   ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s'",
+    	   iface->down_script, iface->ifname, u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)),
+    	   u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), 
+    	   *b->params.authname ? b->params.authname : "-");
+	}
     }
 
     /* Delete dynamic routes */
--- iface.h.orig	2008-12-18 11:47:00.000000000 +0300
+++ iface.h	2008-12-15 12:12:08.000000000 +0300
@@ -58,7 +58,8 @@
     IFACE_CONF_NAT,
     IFACE_CONF_NETFLOW_IN,
     IFACE_CONF_NETFLOW_OUT,
-    IFACE_CONF_IPACCT
+    IFACE_CONF_IPACCT,
+    IFACE_EXEC_ENV
   };
 
   /* Dial-on-demand packet cache */
--- pppoe.h.orig	2008-12-18 11:47:00.000000000 +0300
+++ pppoe.h	2008-12-18 11:27:01.000000000 +0300
@@ -19,7 +19,6 @@
 
   extern const struct cmdtab	PppoeSetCmds[];
   extern const struct phystype	gPppoePhysType;
-
-
+  
 #endif
 
--- util.c.orig	2008-12-19 09:01:28.000000000 +0300
+++ util.c	2008-12-19 11:08:04.000000000 +0300
@@ -10,6 +10,7 @@
 #include "ppp.h"
 #include "util.h"
 #include <termios.h>
+#include <unistd.h>
 
 #include <netdb.h>
 #include <tcpd.h>
@@ -143,6 +144,134 @@ ExecCmd(int log, const char *label, cons
 }
 
 /*
+ * ExecCmdEnv()
+ * 
+ * NEW
+ * Seems to be more secure and provides additional information about peer.
+ *
+ */
+
+int
+ExecCmdEnv(int log, Bund  b, char * cmd)
+{
+  int           rtn;
+  char          selfbuf[40],peerbuf[40];
+  IfaceState    const iface = &b->iface;
+
+/* Log command on the console */
+
+  Log(log, ("[%s] execve: %s", b->name, iface->up_script));
+
+/* Set environment */
+  
+  char 		addrbuff[32];
+  char 		**envir = (char**) malloc (13*sizeof(char*));
+  char          **argv  = (char**) malloc (2*sizeof(char*));
+  int 		i;
+
+  for(i=0;i<12;i++) 
+      envir[i]=(char*) malloc (32*sizeof(char));
+  
+  argv[0]=(char*) malloc (strlen(cmd)*sizeof(char));
+  sprintf(argv[0], "%s", cmd);
+  argv[1]=NULL;
+
+  sprintf(envir[0],"%s=%s","MPD_SELF_IFACE",iface->ifname);
+
+  sprintf(envir[1],"%s=%s","MPD_SELF_IP",u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)));
+  
+  sprintf(envir[2],"%s=%s","MPD_PEER_AUTH_IP",u_addrtoa(&iface->peer_addr,peerbuf,sizeof(peerbuf)));
+
+  sprintf(envir[3],"%s=%s","MPD_PEER_NAME",b->params.authname?b->params.authname:"-");
+ 
+  PhysGetPeerMacAddr(b->links[0],addrbuff,sizeof(addrbuff));
+  sprintf(envir[4],"%s=%s","MPD_PEER_MAC",addrbuff[0]?addrbuff:"N/A");
+     
+  PhysGetPeerIface(b->links[0],addrbuff,sizeof(addrbuff));
+  sprintf(envir[5],"%s=%s","MPD_PEER_IFACE",addrbuff[0]?addrbuff:"N/A");
+
+  PhysGetPeerPort(b->links[0],addrbuff,sizeof(addrbuff));
+  sprintf(envir[6],"%s=%s","MPD_PEER_PORT",addrbuff[0]?addrbuff:"N/A");
+   
+  PhysGetCallingNum(b->links[0],addrbuff,sizeof(addrbuff));
+  sprintf(envir[7],"%s=%s","MPD_CALLING_NUM",addrbuff[0]?addrbuff:"N/A");
+
+  PhysGetCalledNum(b->links[0],addrbuff,sizeof(addrbuff));
+  sprintf(envir[8],"%s=%s","MPD_CALLED_NUM",addrbuff[0]?addrbuff:"N/A");
+
+  if(b->ipcp.want_dns[0].s_addr != 0) 
+	sprintf(addrbuff, "%s", inet_ntoa(b->ipcp.want_dns[0]));
+  else  sprintf(addrbuff, "%s", "N/A");
+  sprintf(envir[9],"%s=%s","MPD_PEER_NS0",addrbuff);
+
+  if(b->ipcp.want_dns[1].s_addr != 0) 
+	sprintf(addrbuff, "%s", inet_ntoa(b->ipcp.want_dns[1]));
+  else  sprintf(addrbuff, "%s", "N/A");
+  sprintf(envir[10],"%s=%s","MPD_PEER_NS1",addrbuff);
+
+  PhysGetPeerAddr(b->links[0],addrbuff,sizeof(addrbuff));
+  sprintf(envir[11], "%s=%s", "MPD_PEER_IP", addrbuff[0]?addrbuff:"N/A");
+
+  envir[12]=NULL;
+  
+/* Do command */  
+
+  pid_t pid, savedpid;
+  int pstat;
+  struct sigaction ign, intact, quitact;
+  sigset_t newsigblock, oldsigblock;
+  ign.sa_handler = SIG_IGN;
+ 
+  (void)sigemptyset(&ign.sa_mask);
+  ign.sa_flags = 0;
+  (void)sigaction(SIGINT, &ign, &intact);
+  (void)sigaction(SIGQUIT, &ign, &quitact);
+  (void)sigemptyset(&newsigblock);
+  (void)sigaddset(&newsigblock, SIGCHLD);
+  (void)sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
+  switch(pid = fork()) {
+  	case -1:                        /* error */
+                break;
+        case 0:                         /* child */
+                (void)sigaction(SIGINT, &intact, NULL);
+                (void)sigaction(SIGQUIT,  &quitact, NULL);
+                (void)sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+                close(1);
+                open("/dev/null", O_WRONLY);
+                close(2);
+                open("/dev/null", O_WRONLY);
+		execve(argv[0],argv,envir);
+                exit(1);
+        default:                        /* parent */
+                savedpid = pid;
+                do {
+                        pid = wait4(savedpid, &pstat, 0, (struct rusage *)0);
+                } while (pid == -1 && errno == EINTR);
+                break;
+   }
+  
+  (void)sigaction(SIGINT, &intact, NULL);
+  (void)sigaction(SIGQUIT,  &quitact, NULL);
+  (void)sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+
+  rtn = (pid == -1 ? -1 : pstat);
+  if (rtn)
+      Log(log|LG_ERR, ("[%s] execve: command \"%s\" returned %d", b->name, cmd, rtn));
+
+/* Releasing memory */
+
+  for(i=0;i<13;i++) free(envir[i]);
+  for(i=0;i<2;i++)  free(argv[i]);
+  free(envir);
+  free(argv);
+
+/* Return command's return value */
+
+  return(rtn);
+}
+
+
+/*
  * ExecCmdNosh()
  */
 
--- util.h.orig	2008-12-18 11:47:00.000000000 +0300
+++ util.h	2008-12-19 11:08:36.000000000 +0300
@@ -78,6 +78,7 @@
 
   extern int		ExecCmd(int log, const char *label, const char *fmt, ...)
 				__printflike(3, 4);
+  extern int 		ExecCmdEnv(int log, Bund b, char *cmd);
   extern int		ExecCmdNosh(int log, const char *label, const char *fmt, ...)
 				__printflike(3, 4);
   extern void		ShowMesg(int log, const char *pref, const char *buf, int len);
