changeset 175:129daaa502a1

Update MPD to current
author ray@terran.dlink.ua
date Tue, 05 Jul 2011 12:33:06 +0300
parents 14f555d30d12
children 4149d74d2449
files contrib/mpd/README contrib/mpd/doc/changes.sgml contrib/mpd/doc/l2tp.sgml contrib/mpd/doc/mpd.8 contrib/mpd/doc/pptp.sgml contrib/mpd/doc/tcp.sgml contrib/mpd/doc/udp.sgml contrib/mpd/doc/version.sgml contrib/mpd/src/Makefile contrib/mpd/src/chat.c contrib/mpd/src/chat.h contrib/mpd/src/command.c contrib/mpd/src/command.h contrib/mpd/src/config.h contrib/mpd/src/event.c contrib/mpd/src/l2tp.c contrib/mpd/src/l2tp_avp.c contrib/mpd/src/log.c contrib/mpd/src/log.h contrib/mpd/src/main.c contrib/mpd/src/mbuf.c contrib/mpd/src/mbuf.h contrib/mpd/src/modem.c contrib/mpd/src/ppp.h contrib/mpd/src/pptp.c contrib/mpd/src/radius.c contrib/mpd/src/radsrv.c contrib/mpd/src/tcp.c contrib/mpd/src/udp.c contrib/mpd/src/web.c target/usr.sbin/mpd/Makefile target/usr.sbin/mpd/config.h
diffstat 32 files changed, 501 insertions(+), 455 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/mpd/README	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/README	Tue Jul 05 12:33:06 2011 +0300
@@ -23,4 +23,4 @@
 	port.tgz		Updated port
 
 
-$Id: README,v 1.3 2007/02/06 19:17:19 amotin Exp $
+$Id: README,v 1.5 2011/06/21 07:38:17 amotin Exp $
--- a/contrib/mpd/doc/changes.sgml	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/doc/changes.sgml	Tue Jul 05 12:33:06 2011 +0300
@@ -1,4 +1,4 @@
-<!-- $Id: changes.sgml,v 1.262 2010/10/25 06:26:19 amotin Exp $ -->
+<!-- $Id: changes.sgml,v 1.265 2011/04/15 19:01:36 amotin Exp $ -->
 <!-- mpd netgraph enabled user mode PPP daemon -->
 
 <!-- <!DOCTYPE linuxdoc PUBLIC '-//FreeBSD//DTD linuxdoc//EN'> -->
@@ -8,6 +8,13 @@
   <p>
     Changes since version 5.5:
     <itemize>
+	<item> New features:
+	<itemize>
+	  <item> Added `set l2tp|pptp|tcp|udp resolve-once ...` command.
+		They allow to resolve peer address every time on reconnect.
+	  </item>
+	</itemize>
+	</item>
 	<item> Changes:
 	<itemize>
 	  <item> Remove dependency from libpdel library.
@@ -21,6 +28,10 @@
 	  </item>
 	  <item> Fix several memory leaks.
 	  </item>
+	  <item> Fix building without SYSLOG_FACILITY option.
+	  </item>
+	  <item> Fix byte order in ports in `set nat red-port`.
+	  </item>
 	</itemize>
 	</item>
     </itemize>
--- a/contrib/mpd/doc/l2tp.sgml	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/doc/l2tp.sgml	Tue Jul 05 12:33:06 2011 +0300
@@ -1,4 +1,4 @@
-<!-- $Id: l2tp.sgml,v 1.14 2008/01/06 01:18:31 amotin Exp $ -->
+<!-- $Id: l2tp.sgml,v 1.15 2011/03/25 11:47:43 amotin Exp $ -->
 <!-- mpd netgraph enabled user mode PPP daemon -->
 
 <!-- <!DOCTYPE linuxdoc PUBLIC '-//FreeBSD//DTD linuxdoc//EN'> -->
@@ -154,5 +154,11 @@
 
 The default is enable.
 
+<tag><tt>resolve-once</tt></tag>
+
+Enables resolving peer address only once, on startup, or on manual
+typing in CLI.
+
+The default is enable.
 </descrip>
 
--- a/contrib/mpd/doc/mpd.8	Tue Jul 05 12:30:56 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-.\"
-.\" Written by Archie Cobbs <[email protected]>
-.\" Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
-.\" See ``COPYRIGHT.whistle''
-.\"
-.Dd 2011-02-19
-.Dt MPD5 8
-.Os
-.Sh NAME
-.Nm mpd5
-.Nd netgraph multi-link PPP daemon
-.Sh SYNOPSIS
-.Nm
-.Op Fl bkov
-.Op Fl d Ar directory
-.Op Fl f Ar file
-.Op Fl p Ar pid-file
-.Op Fl s Ar ident
-.Op Ar configuration
-.Sh DESCRIPTION
-.Nm
-is a user mode PPP daemon using the
-.Xr netgraph 4
-networking system.
-By using Netgraph,
-.Nm
-combines the robustness and flexibility of a user-mode PPP implementation
-with the speed and reliability of kernel-mode packet forwarding.
-All PPP negotiation is handled in user level code, while all data
-intensive operations such as encryption, compression, and multi-link
-framing are handled strictly in the kernel.
-Mpd supports several link layer types, a fully event-driven modem chat
-scripting language, and other features.
-.Pp
-.Nm
-creates a
-.Xr ng_ppp 4
-netgraph node that is placed between a
-.Xr ng_iface 4
-netgraph interface one or more link layer devices,
-performing multi-link PPP negotiation and encapsulation. In multi-link PPP a
-.Ar bundle
-is a collection of one or more
-.Ar links 
-between two peers. Each link corresponds to some device (e.g.,
-a modem), and each bundle corresponds to one netgraph interface.
-The idea is to use all of the links, together connected to a remote
-peer also performing multi-link PPP, to utilize their combined
-bandwidth.  Packets routed through the netgraph interface travel in
-multi-link fragments over all of the links.
-Each link is a normal PPP link and can deliver complete packets
-as well, so redundancy is another benefit.
-Attempts to connect two links in the same bundle to different peers,
-or to a peer that is not configured for multi-link PPP, will fail.
-.Pp
-In general, everything is controlled by executing commands which are either
-entered via the console command line or read from a configuration file. If
-.Nm
-is running as a background daemon, the console can be made accessible via
-.Xr telnet 1
-Since commands may apply to a single link, the console prompt always shows the
-.Ar current bundle
-or the
-.Ar current link
-in that bundle. 
-.Sh ON-LINE MANUAL
-Mpd is fully documented in the mpd manual, which is available in HTML.
-The manual can be found in the directory
-.Pa @[email protected]/share/doc/mpd5 .
-.Sh OPTIONS
-Mpd supports the following command options:
-.Pp
-.Bl -tag -width Ds -compact
-.Pp
-.It Fl b
-.It Fl -background
-.Pp
-Detach from the terminal and run as a background deamon.
-.Pp
-.It Fl d Ar dirname
-.It Fl -directory Ar dirname
-.Pp
-Specify a configuration directory other than the default,
-.Pa @[email protected]/etc/mpd5 .
-.Pp
-.It Fl f Ar file
-.It Fl -file Ar file
-.Pp
-Specify an initial configuration file other than the default,
-.Pa mpd.conf .
-.Pp
-.It Fl o
-.It Fl -one-shot
-.Pp
-Terminate daemon after the last link shutdown.
-.Pp
-.It Fl p Ar file
-.It Fl -pidfile Ar file
-.Pp
-Specify an lock/process ID storage file other than the default
-.Pa /var/run/mpd.pid .
-.Pp
-.It Fl k
-.It Fl -kill
-.Pp
-Kill any existing
-.Nm
-daemon currently running. The same pidfile must be used.
-.Pp
-.It Fl s Ar ident
-.It Fl -syslog-ident Ar ident
-.Pp
-Identifier to use for
-.Xr syslog 3 .
-.Pp
-.It Fl v
-.It Fl -version
-.Pp
-Display the program version and exit.
-.Pp
-.It Fl h
-.It Fl -help
-.Pp
-Display invocation usage and exit.
-.El
-.Sh FILES
-.Bl -tag -width /usr/local/share/doc/mpdXX -compact
-.It Pa @[email protected]/share/doc/mpd5
-Directory containing the mpd manual
-.It Pa @[email protected]/etc/mpd5
-Default configuration file directory
-.It Pa mpd.conf
-Configuration file
-.It Pa mpd.script
-Modem chat scripts
-.It Pa mpd.secret
-Account name, password pairs
-.It Pa /var/run/mpd.pid
-Stored process ID and lock file
-.El
-.Sh SEE ALSO
-.Xr netgraph 4 ,
-.Xr ngctl 8 ,
-.Xr ng_ppp 4 ,
-.Xr ng_iface 4 ,
-.Xr ppp 8 ,
-.Xr pppd 8 .
-.Sh AUTHORS
-.An Archie Cobbs Aq [email protected]
-.An Alexander Motin Aq [email protected]
-.An based on ppp daemon written by Toshiharu OHNO Aq [email protected]
--- a/contrib/mpd/doc/pptp.sgml	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/doc/pptp.sgml	Tue Jul 05 12:33:06 2011 +0300
@@ -1,4 +1,4 @@
-<!-- $Id: pptp.sgml,v 1.18 2008/01/06 01:18:31 amotin Exp $ -->
+<!-- $Id: pptp.sgml,v 1.19 2011/03/25 11:47:43 amotin Exp $ -->
 <!-- mpd netgraph enabled user mode PPP daemon -->
 
 <!-- <!DOCTYPE linuxdoc PUBLIC '-//FreeBSD//DTD linuxdoc//EN'> -->
@@ -128,7 +128,14 @@
 mechanism is a design error in the PPTP protocol; L2TP, the successor 
 to PPTP, removes it.
 
-the default is disable.
+The default is disable.
+
+<tag><tt>resolve-once</tt></tag>
+
+Enables resolving peer address only once, on startup, or on manual
+typing in CLI.
+
+The default is enable.
 
 </descrip>
 
--- a/contrib/mpd/doc/tcp.sgml	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/doc/tcp.sgml	Tue Jul 05 12:33:06 2011 +0300
@@ -1,4 +1,4 @@
-<!-- $Id: tcp.sgml,v 1.7 2007/09/28 21:47:53 amotin Exp $ -->
+<!-- $Id: tcp.sgml,v 1.8 2011/03/25 11:47:43 amotin Exp $ -->
 <!-- mpd netgraph enabled user mode PPP daemon -->
 
 <!-- <!DOCTYPE linuxdoc PUBLIC '-//FreeBSD//DTD linuxdoc//EN'> -->
@@ -36,3 +36,17 @@
 For incoming connections it is not required, but can limit who can connect to us.
 
 </descrip>
+
+<p>
+The following options are supported:
+
+<descrip>
+
+<tag><tt>resolve-once</tt></tag>
+
+Enables resolving peer address only once, on startup, or on manual
+typing in CLI.
+
+The default is enable.
+
+</descrip>
--- a/contrib/mpd/doc/udp.sgml	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/doc/udp.sgml	Tue Jul 05 12:33:06 2011 +0300
@@ -1,4 +1,4 @@
-<!-- $Id: udp.sgml,v 1.5 2007/09/28 21:47:53 amotin Exp $ -->
+<!-- $Id: udp.sgml,v 1.6 2011/03/25 11:47:43 amotin Exp $ -->
 <!-- mpd netgraph enabled user mode PPP daemon -->
 
 <!-- <!DOCTYPE linuxdoc PUBLIC '-//FreeBSD//DTD linuxdoc//EN'> -->
@@ -42,3 +42,17 @@
 For incoming connections it is not required, but can limit who can connect to us.
 
 </descrip>
+
+<p>
+The following options are supported:
+
+<descrip>
+
+<tag><tt>resolve-once</tt></tag>
+
+Enables resolving peer address only once, on startup, or on manual
+typing in CLI.
+
+The default is enable.
+
+</descrip>
--- a/contrib/mpd/doc/version.sgml	Tue Jul 05 12:30:56 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-
-<!ENTITY version "5.6a1" >
-<!ENTITY date "2011-02-19" >
-
--- a/contrib/mpd/src/Makefile	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/Makefile	Tue Jul 05 12:33:06 2011 +0300
@@ -51,7 +51,7 @@
 USE_NG_TCPMSS=		yes
 USE_NG_VJC=		yes
 USE_IPFW=		yes
-USE_FETCH=		no	#yes
+USE_FETCH=		yes
 USE_TCP_WRAP=		yes
 #USE_AUTH_OPIE=		yes
 USE_AUTH_PAM=		yes
@@ -61,9 +61,6 @@
 
 NOLIBPDEL=		yes
 
-# Don`t build web server support
-NOWEB=			no
-
 # Set syslog logging facility. Change LOG_DAEMON to whatever you like.
 
 SYSLOG_FACILITY=	LOG_DAEMON
@@ -141,11 +138,7 @@
 		console.c command.c ecp.c event.c fsm.c iface.c input.c \
 		ip.c ipcp.c ipv6cp.c lcp.c link.c log.c main.c mbuf.c mp.c \
 		msg.c ngfunc.c pap.c phys.c proto.c radius.c radsrv.c timer.c \
-		util.c vars.c eap.c msoft.c ippool.c
-
-.if !defined ( NOWEB )
-STDSRCS+=	web.c
-.endif
+		util.c vars.c eap.c msoft.c web.c ippool.c
 
 .if defined ( NOLIBPDEL )
 COPTS+=		-DNOLIBPDEL -I./contrib/libpdel
@@ -166,12 +159,7 @@
 		structs_type_int.c \
 		structs_type_string.c \
 		structs_type_struct.c \
-		boundary_fp.c \
-		ssl_fp.c \
-		string_fp.c \
-		timeout_fp.c
-.if !defined ( NOWEB )
-PDELSRCS+=	http_connection.c \
+		http_connection.c \
 		http_head.c \
 		http_message.c \
 		http_mime.c \
@@ -180,12 +168,11 @@
 		http_server.c \
 		http_servlet_basicauth.c \
 		http_ssl.c \
-		http_status.c
-.endif
-.endif
-
-.if defined ( NOWEB )
-COPTS+=		-DNOWEB
+		http_status.c \
+		boundary_fp.c \
+		ssl_fp.c \
+		string_fp.c \
+		timeout_fp.c
 .endif
 
 # Add sources and flags for the various physical layer types
--- a/contrib/mpd/src/chat.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/chat.c	Tue Jul 05 12:33:06 2011 +0300
@@ -151,10 +151,7 @@
     char		lineBuf[CHAT_MAX_LINE];		/* line buffer */
     char		readBuf[CHAT_READBUF_SIZE];	/* read buffer */
     int			readBufLen;
-    chatlogfunc_t	log /*__printflike(2, 3)*/;
     chatbaudfunc_t	setBaudrate;
-    chatmallocfunc_t	malloc;
-    chatfreefunc_t	free;
     chatresultfunc_t	result;
   };
 
@@ -239,18 +236,13 @@
  */
 
 ChatInfo
-ChatInit(void *arg, chatbaudfunc_t setBaudrate,
-	chatlogfunc_t logger, chatmallocfunc_t malloc, chatfreefunc_t free)
+ChatInit(void *arg, chatbaudfunc_t setBaudrate)
 {
   ChatInfo	c;
 
-  c = (ChatInfo) (*malloc)(arg, sizeof(*c));
-  memset(c, 0, sizeof(*c));
+  c = (ChatInfo) Malloc(MB_CHAT, sizeof(*c));
   c->arg = arg;
   c->setBaudrate = setBaudrate;
-  c->log = logger;
-  c->malloc = malloc;
-  c->free = free;
   return(c);
 }
 
@@ -271,9 +263,11 @@
 void
 ChatPresetVar(ChatInfo c, const char *name, const char *value)
 {
+  Link	const l = (Link) c->arg;
+
   if (ChatVarSet(c, name, value, 1, 1) < 0)
   {
-    (*c->log)(c->arg, CHAT_LG_ERROR, "chat: invalid variable \"%s\"", name);
+    Log(LG_ERR, ("[%s] CHAT: chat: invalid variable \"%s\"", l->name, name));
     return;
   }
 }
@@ -289,9 +283,7 @@
 {
   ChatVar	const cv = ChatVarGet(c, var);
 
-  return cv ?
-    strcpy((char *) (*c->malloc)(c->arg, strlen(cv->value) + 1), cv->value) :
-    NULL;
+  return cv ? Mstrdup(MB_CHAT, cv->value) : NULL;
 }
 
 /*
@@ -307,6 +299,7 @@
 {
   ChatVar	baud;
   const char	*labelName;
+  Link	const l = (Link) c->arg;
 
 /* Sanity */
 
@@ -314,9 +307,9 @@
   assert(c->state == CHAT_IDLE);
 
   if (label)
-    (*c->log)(c->arg, CHAT_LG_DEBUG, "running script at label \"%s\"", label);
+    Log(LG_CHAT2, ("[%s] CHAT: running script at label \"%s\"", l->name, label));
   else
-    (*c->log)(c->arg, CHAT_LG_DEBUG, "running script from beginning");
+    Log(LG_CHAT2, ("[%s] CHAT: running script from beginning", l->name));
 
   c->result = result;
   c->fd = fd;
@@ -327,8 +320,7 @@
 
   assert(!c->scriptName);
   labelName = label ? label : "<default>";
-  c->scriptName =
-    strcpy((char *) (*c->malloc)(c->arg, strlen(labelName) + 1), labelName);
+  c->scriptName = Mstrdup(MB_CHAT, labelName);
 
 /* Jump to label, if any */
 
@@ -352,8 +344,10 @@
 void
 ChatAbort(ChatInfo c)
 {
+  Link	const l = (Link) c->arg;
+
   if (c->state != CHAT_IDLE)
-    (*c->log)(c->arg, CHAT_LG_DEBUG, "script halted");
+    Log(LG_CHAT2, ("[%s] CHAT: script halted", l->name));
   ChatStop(c);
 }
 
@@ -368,6 +362,7 @@
   ChatMatch	match;
   int		nread, lineBufLen;
   char		ch;
+  Link		const l = (Link) c->arg;
 
 /* Sanity */
 
@@ -384,12 +379,12 @@
     {
       if (errno == EAGAIN)
 	break;
-      (*c->log)(c->arg, CHAT_LG_ERROR, "read: %s", strerror(errno));
+      Log(LG_ERR, ("[%s] CHAT: read: %s", l->name, strerror(errno)));
       goto die;
     }
     else if (nread == 0)
     {
-      (*c->log)(c->arg, CHAT_LG_NORMAL, "detected EOF from device");
+      Log(LG_CHAT, ("[%s] CHAT: detected EOF from device", l->name));
 die:
       ChatFailure(c);
       return;
@@ -406,7 +401,7 @@
     if (lineBufLen < sizeof(c->lineBuf) - 1) {
       c->lineBuf[lineBufLen++] = ch;
     } else {
-      (*c->log)(c->arg, CHAT_LG_NORMAL, "warning: line buffer overflow");
+      Log(LG_CHAT, ("[%s] CHAT: warning: line buffer overflow", l->name));
     }
 
   /* Try to match a match pattern */
@@ -424,8 +419,7 @@
 
       /* Check for end of line */
 
-	pmatch = (*c->malloc)(c->arg, nmatch * sizeof(*pmatch));
-	memset(pmatch, 0, nmatch * sizeof(*pmatch));
+	pmatch = Malloc(MB_CHAT, nmatch * sizeof(*pmatch));
 	pmatch[0].rm_so = 0;
 	pmatch[0].rm_eo = lineBufLen;
 	if (pmatch[0].rm_eo > 0 && c->lineBuf[pmatch[0].rm_eo - 1] == '\n') {
@@ -440,14 +434,14 @@
 	switch ((r = regexec(&match->u.regex,
 		c->lineBuf, nmatch, pmatch, flags))) {
 	  default:
-	    (*c->log)(c->arg, CHAT_LG_ERROR, "regexec() returned %d?", r);
+	    Log(LG_ERR, ("[%s] CHAT: regexec() returned %d?", l->name, r));
 	    /* fall through */
 	  case REG_NOMATCH:
-	    (*c->free)(c->arg, pmatch);
+	    Freee(pmatch);
 	    continue;
 	  case 0:
 	    ChatSetMatchVars(c, 0, c->lineBuf, nmatch, pmatch);
-	    (*c->free)(c->arg, pmatch);
+	    Freee(pmatch);
 	    break;
 	}
 	break;
@@ -466,8 +460,8 @@
       int	numPop;
 
       ChatDumpReadBuf(c);
-      (*c->log)(c->arg, CHAT_LG_DEBUG, "matched set \"%s\", goto label \"%s\"", 
-    	    match->set, match->label);
+      Log(LG_CHAT2, ("[%s] CHAT: matched set \"%s\", goto label \"%s\"",
+         l->name, match->set, match->label));
       numPop = match->frameDepth;
       strlcpy(label, match->label, sizeof(label));
       ChatCancel(c, match->set);
@@ -498,6 +492,7 @@
   ChatTimer	*tp;
   char		label[CHAT_MAX_LABEL];
   int		numPop;
+  Link		const l = (Link) c->arg;
 
 /* Sanity */
 
@@ -507,7 +502,7 @@
 
   for (tp = &c->timers; *tp != timer; tp = &(*tp)->next);
   assert(*tp);
-  (*c->log)(c->arg, CHAT_LG_DEBUG, "timer in set \"%s\" expired", timer->set);
+  Log(LG_CHAT2, ("[%s] CHAT: timer in set \"%s\" expired", l->name, timer->set));
 
 /* Cancel set */
 
@@ -536,6 +531,7 @@
 ChatRun(ChatInfo c)
 {
   char	*line;
+  Link	const l = (Link) c->arg;
 
 /* Sanity */
 
@@ -557,20 +553,20 @@
 
     if (!isspace(*line))
     {
-      (*c->free)(c->arg, line);
+      Freee(line);
       continue;
     }
 
   /* Parse out line */
 
     ac = ChatParseLine(c, line, av, CHAT_MAX_ARGS);
-    (*c->free)(c->arg, line);
+    Freee(line);
 
   /* Do command */
 
     ChatDoCmd(c, ac, av);
     while (ac > 0)
-      (*c->free)(c->arg, av[--ac]);
+      Freee(av[--ac]);
   }
 
 /* What state are we in? */
@@ -578,7 +574,7 @@
   switch (c->state)
   {
     case CHAT_RUNNING:
-      (*c->log)(c->arg, CHAT_LG_ERROR, "EOF while reading script");
+      Log(LG_ERR, ("[%s] CHAT: EOF while reading script", l->name));
       ChatFailure(c);
       break;
     case CHAT_WAIT:
@@ -604,6 +600,7 @@
   char	buf[200];
   u_int	secs;
   int	j, k;
+  Link	const l = (Link) c->arg;
 
 /* Show command */
 
@@ -612,7 +609,7 @@
     snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
       !*av[k] || av[k][j] ? " \"%s\"" : " %s", av[k]);
   }
-  (*c->log)(c->arg, CHAT_LG_DEBUG, "line %d:%s", c->lineNum, buf);
+  Log(LG_CHAT2, ("[%s] CHAT: line %d:%s", l->name, c->lineNum, buf));
 
 /* Execute command */
 
@@ -627,8 +624,8 @@
     case CMD_SET:
       if (ChatVarSet(c, av[1], av[2], 1, 0) < 0)
       {
-	(*c->log)(c->arg, CHAT_LG_ERROR,
-	  "line %d: %s: invalid variable \"%s\"", c->lineNum, SET, av[1]);
+	Log(LG_ERR, ("[%s] CHAT: line %d: %s: invalid variable \"%s\"",
+	  l->name, c->lineNum, SET, av[1]));
 	ChatFailure(c);
       }
       break;
@@ -710,8 +707,8 @@
       {
 	if (!c->matches && !c->timers)
 	{
-	  (*c->log)(c->arg, CHAT_LG_ERROR,
-	    "line %d: %s with no events pending", c->lineNum, WAIT);
+	  Log(LG_ERR, ("[%s] CHAT: line %d: %s with no events pending",
+	    l->name, c->lineNum, WAIT));
 	  ChatFailure(c);
 	}
 	else
@@ -771,6 +768,7 @@
   char	*const arg1 = ChatExpandString(c, av[1]);
   char	*const arg2 = ChatExpandString(c, av[3]);
   int	proceed = 0, invert = 0;
+  Link	const l = (Link) c->arg;
 
 /* Check operator */
 
@@ -785,20 +783,19 @@
 
     if ((errcode = regcomp(&regex, arg2, REG_EXTENDED)) != 0) {
       regerror(errcode, &regex, errbuf, sizeof(errbuf));
-      (*c->log)(c->arg, CHAT_LG_ERROR,
-	"line %d: invalid regular expression \"%s\": %s",
-	c->lineNum, arg2, errbuf);
+      Log(LG_ERR, ("[%s] CHAT: line %d: invalid regular expression \"%s\": %s",
+        l->name, c->lineNum, arg2, errbuf));
     } else {
       proceed = ChatMatchRegex(c, &regex, arg1);
       regfree(&regex);
       invert = (*av[2] == '!');
     }
   } else {
-    (*c->log)(c->arg, CHAT_LG_ERROR,
-      "line %d: invalid operator \"%s\"", c->lineNum, av[2]);
+    Log(LG_ERR, ("[%s] CHAT: line %d: invalid operator \"%s\"",
+      l->name, c->lineNum, av[2]));
   }
-  (*c->free)(c->arg, arg1);
-  (*c->free)(c->arg, arg2);
+  Freee(arg1);
+  Freee(arg2);
 
 /* Do command */
 
@@ -830,7 +827,7 @@
   c->lastLog = NULL;
   ChatStop(c);
   (*c->result)(c->arg, 0, reason);
-  (*c->free)(c->arg, reason);
+  Freee(reason);
 }
 
 /*
@@ -847,9 +844,9 @@
   for (var = c->temps; var; var = next)
   {
     next = var->next;
-    (*c->free)(c->arg, var->name);
-    (*c->free)(c->arg, var->value);
-    (*c->free)(c->arg, var);
+    Freee(var->name);
+    Freee(var->value);
+    Freee(var);
   }
   c->temps = NULL;
 
@@ -863,7 +860,7 @@
 
 /* Forget active script name */
 
-  (*c->free)(c->arg, c->scriptName);
+  Freee(c->scriptName);
   c->scriptName = NULL;
 
 /* Cancel all sets */
@@ -875,7 +872,7 @@
   EventUnRegister(&c->rdEvent);
   EventUnRegister(&c->wrEvent);
   if (c->out != NULL) {
-    (*c->free)(c->arg, c->out);
+    Freee(c->out);
     c->out = NULL;
     c->outLen = 0;
   }
@@ -890,7 +887,7 @@
   c->readBufLen = 0;
   if (c->lastLog)
   {
-    (*c->free)(c->arg, c->lastLog);
+    Freee(c->lastLog);
     c->lastLog = NULL;
   }
 
@@ -908,13 +905,13 @@
 	char *pat, const char *label)
 {
   ChatMatch	match, *mp;
+  Link		const l = (Link) c->arg;
 
   /* Expand pattern */
   pat = ChatExpandString(c, pat);
 
   /* Create new match */
-  match = (ChatMatch) (*c->malloc)(c->arg, sizeof(*match));
-  memset(match, 0, sizeof(*match));
+  match = (ChatMatch) Malloc(MB_CHAT, sizeof(*match));
   match->exact = !!exact;
   if (exact) {
     match->u.exact.pat = pat;
@@ -926,16 +923,15 @@
 
     /* Convert pattern into compiled regular expression */
     errcode = regcomp(&match->u.regex, pat, REG_EXTENDED);
-    (*c->free)(c->arg, pat);
+    Freee(pat);
 
     /* Check for error */
     if (errcode != 0) {
       regerror(errcode, &match->u.regex, errbuf, sizeof(errbuf));
-      (*c->log)(c->arg, CHAT_LG_ERROR,
-	"line %d: invalid regular expression \"%s\": %s",
-	c->lineNum, pat, errbuf);
+      Log(LG_ERR, ("[%s] CHAT: line %d: invalid regular expression \"%s\": %s",
+        l->name, c->lineNum, pat, errbuf));
       ChatFailure(c);
-      (*c->free)(c->arg, match);
+      Freee(match);
       return;
     }
   }
@@ -960,8 +956,7 @@
 
 /* Add new timer */
 
-  timer = (ChatTimer) (*c->malloc)(c->arg, sizeof(*timer));
-  memset(timer, 0, sizeof(*timer));
+  timer = (ChatTimer) Malloc(MB_CHAT, sizeof(*timer));
   timer->c = c;
   timer->set = ChatExpandString(c, set);
   timer->label = ChatExpandString(c, label);
@@ -1013,7 +1008,7 @@
 
 /* Done */
 
-  (*c->free)(c->arg, set);
+  Freee(set);
 }
 
 /*
@@ -1026,6 +1021,7 @@
   const int	lineNum = c->lineNum;
   char		*label;
   int		rtn;
+  Link		const l = (Link) c->arg;
 
 /* Expand label */
 
@@ -1035,7 +1031,7 @@
 
   if (!strcmp(label, DEFAULT_LABEL))
   {
-    (*c->free)(c->arg, label);
+    Freee(label);
     return(0);
   }
 
@@ -1043,11 +1039,11 @@
 
   if ((rtn = ChatSeekToLabel(c, label)) < 0)
   {
-    (*c->log)(c->arg, CHAT_LG_ERROR,
-      "line %d: label \"%s\" not found", lineNum, label);
+    Log(LG_ERR, ("[%s] CHAT: line %d: label \"%s\" not found",
+      l->name, lineNum, label));
     ChatFailure(c);
   }
-  (*c->free)(c->arg, label);
+  Freee(label);
   return(rtn);
 }
 
@@ -1062,6 +1058,7 @@
   ChatMatch	match;
   ChatTimer	timer;
   char		*label;
+  Link		const l = (Link) c->arg;
 
 /* Expand label */
 
@@ -1069,8 +1066,7 @@
 
 /* Adjust stack */
 
-  frame = (ChatFrame) (*c->malloc)(c->arg, sizeof(*frame));
-  memset(frame, 0, sizeof(*frame));
+  frame = (ChatFrame) Malloc(MB_CHAT, sizeof(*frame));
   fgetpos(c->fp, &frame->posn);
   frame->lineNum = c->lineNum;
   frame->up = c->stack;
@@ -1080,11 +1076,11 @@
 
   if (ChatSeekToLabel(c, label) < 0)
   {
-    (*c->log)(c->arg, CHAT_LG_ERROR,
-      "line %d: %s: label \"%s\" not found", frame->lineNum, CALL, label);
+    Log(LG_ERR, ("[%s] CHAT: line %d: %s: label \"%s\" not found",
+      l->name, frame->lineNum, CALL, label));
     ChatFailure(c);
   }
-  (*c->free)(c->arg, label);
+  Freee(label);
 
 /* Increment call depth for timer and match events */
 
@@ -1104,11 +1100,12 @@
   ChatFrame	frame;
   ChatMatch	*mp, match;
   ChatTimer	*tp, timer;
+  Link		const l = (Link) c->arg;
 
   if (c->stack == NULL)
   {
-    (*c->log)(c->arg, CHAT_LG_ERROR,
-      "line %d: %s without corresponding %s", c->lineNum, RETURN, CALL);
+    Log(LG_ERR, ("[%s] CHAT: line %d: %s without corresponding %s",
+      l->name, c->lineNum, RETURN, CALL));
     ChatFailure(c);
     return;
   }
@@ -1121,7 +1118,7 @@
     c->lineNum = frame->lineNum;
   }
   c->stack = frame->up;
-  (*c->free)(c->arg, frame);
+  Freee(frame);
 
 /* Decrement call depth for timer and match events */
 
@@ -1149,11 +1146,12 @@
 ChatLog(ChatInfo c, int code, const char *string)
 {
   char	*exp_string;
+  Link	const l = (Link) c->arg;
 
   exp_string = ChatExpandString(c, string);
-  (*c->log)(c->arg, CHAT_LG_NORMAL, "%s", exp_string);
+  Log(LG_CHAT, ("[%s] CHAT: %s", l->name, exp_string));
   if (c->lastLog)
-    (*c->free)(c->arg, c->lastLog);
+    Freee(c->lastLog);
   c->lastLog = exp_string;
 }
 
@@ -1170,10 +1168,10 @@
 /* Add variable-expanded string to output queue */
 
   exp_len = strlen(exp_string = ChatExpandString(c, string));
-  buf = (*c->malloc)(c->arg, c->outLen + exp_len);
+  buf = Malloc(MB_CHAT, c->outLen + exp_len);
   if (c->out != NULL) {
     memcpy(buf, c->out, c->outLen);
-    (*c->free)(c->arg, c->out);
+    Freee(c->out);
   } else
     assert(c->outLen == 0);
   memcpy(buf + c->outLen, exp_string, exp_len);
@@ -1183,7 +1181,7 @@
 /* Debugging dump */
 
   ChatDumpBuf(c, exp_string, exp_len, "sending");
-  (*c->free)(c->arg, exp_string);
+  Freee(exp_string);
 
 /* Simulate a writable event to get things going */
 
@@ -1199,6 +1197,7 @@
 {
   ChatInfo	const c = (ChatInfo) cookie;
   int		nw;
+  Link		const l = (Link) c->arg;
 
 /* Write as much as we can */
 
@@ -1206,7 +1205,7 @@
   if ((nw = write(c->fd, c->out, c->outLen)) < 0) {
     if (errno == EAGAIN)
       return;
-    (*c->log)(c->arg, CHAT_LG_ERROR, "write: %s", strerror(errno));
+    Log(LG_ERR, ("[%s] CHAT: write: %s", l->name, strerror(errno)));
     ChatFailure(c);
     return;
   }
@@ -1215,7 +1214,7 @@
 
   c->outLen -= nw;
   if (c->outLen <= 0) {
-    (*c->free)(c->arg, c->out);
+    Freee(c->out);
     c->out = NULL;
     c->outLen = 0;
   } else {
@@ -1233,11 +1232,12 @@
 {
   char	*endptr;
   int	rate = strtoul(new, &endptr, 0);
+  Link	const l = (Link) c->arg;
 
   if (!*new || *endptr || (*c->setBaudrate)(c->arg, rate) < 0)
   {
-    (*c->log)(c->arg, CHAT_LG_NORMAL,
-      "line %d: invalid baudrate \"%s\"", c->lineNum, new);
+    Log(LG_CHAT, ("[%s] CHAT: line %d: invalid baudrate \"%s\"",
+       l->name, c->lineNum, new));
     ChatFailure(c);
     return(-1);
   }
@@ -1268,8 +1268,7 @@
     new = ChatExpandString(c, value);
   else
   {
-    new = (*c->malloc)(c->arg, strlen(value) + 1);
-    strcpy(new, value);
+    new = Mstrdup(MB_CHAT, value);
   }
 
 /* Check for special variable names */
@@ -1278,7 +1277,7 @@
   {
     if (!pre && ChatSetBaudrate(c, new) < 0)
     {
-      (*c->free)(c->arg, new);
+      Freee(new);
       return(0);
     }
   }
@@ -1293,17 +1292,15 @@
 
     ovalue = var->value;
     var->value = new;
-    (*c->free)(c->arg, ovalue);
+    Freee(ovalue);
   }
   else
   {
 
   /* Create new struct and add to list */
 
-    var = (*c->malloc)(c->arg, sizeof(*var));
-    memset(var, 0, sizeof(*var));
-    var->name = (*c->malloc)(c->arg, strlen(name) + 1);
-    strcpy(var->name, name);
+    var = Malloc(MB_CHAT, sizeof(*var));
+    var->name = Mstrdup(MB_CHAT, name);
     var->value = new;
     var->next = *head;
     *head = var;
@@ -1380,15 +1377,15 @@
 static void
 ChatFreeMatch(ChatInfo c, ChatMatch match)
 {
-  (*c->free)(c->arg, match->set);
-  (*c->free)(c->arg, match->label);
+  Freee(match->set);
+  Freee(match->label);
   if (match->exact) {
-    (*c->free)(c->arg, match->u.exact.pat);
-    (*c->free)(c->arg, match->u.exact.fail);
+    Freee(match->u.exact.pat);
+    Freee(match->u.exact.fail);
   } else {
     regfree(&match->u.regex);
   }
-  (*c->free)(c->arg, match);
+  Freee(match);
 }
 
 /*
@@ -1399,9 +1396,9 @@
 ChatFreeTimer(ChatInfo c, ChatTimer timer)
 {
   EventUnRegister(&timer->event);
-  (*c->free)(c->arg, timer->set);
-  (*c->free)(c->arg, timer->label);
-  (*c->free)(c->arg, timer);
+  Freee(timer->set);
+  Freee(timer->label);
+  Freee(timer);
 }
 
 /*
@@ -1428,6 +1425,7 @@
 ChatGetCmd(ChatInfo c, const char *token, int n_args)
 {
   int	k;
+  Link	const l = (Link) c->arg;
 
   for (k = 0; k < CHAT_NUM_COMMANDS; k++)
     if (!strcasecmp(gCmds[k].name, token))
@@ -1435,15 +1433,15 @@
       if ((gCmds[k].min && n_args < gCmds[k].min)
 	|| (gCmds[k].max && n_args > gCmds[k].max))
       {
-	(*c->log)(c->arg, CHAT_LG_ERROR,
-	  "line %d: %s: bad argument count", c->lineNum, token);
+	Log(LG_ERR, ("[%s] CHAT: line %d: %s: bad argument count",
+	  l->name, c->lineNum, token));
 	return(-1);
       }
       else
 	return(gCmds[k].id);
     }
-  (*c->log)(c->arg, CHAT_LG_ERROR,
-    "line %d: unknown command \"%s\"", c->lineNum, token);
+  Log(LG_ERR, ("[%s] CHAT: line %d: unknown command \"%s\"",
+    l->name, c->lineNum, token));
   return(-1);
 }
 
@@ -1501,7 +1499,7 @@
 
   if (!doit)
   {
-    new = (*c->malloc)(c->arg, new_len + 1);
+    new = Malloc(MB_CHAT, new_len + 1);
     doit = 1;
     goto rescan;
   }
@@ -1541,9 +1539,9 @@
       continue;
     }
     *vp = var->next;
-    (*c->free)(c->arg, var->name);
-    (*c->free)(c->arg, var->value);
-    (*c->free)(c->arg, var);
+    Freee(var->name);
+    Freee(var->value);
+    Freee(var);
   }
 
   /* Set new match variables */
@@ -1553,7 +1551,7 @@
   } else {
     const int	nmatch = va_arg(args, int);
     regmatch_t	*const pmatch = va_arg(args, regmatch_t *);
-    char	*const value = (*c->malloc)(c->arg, strlen(input) + 1);
+    char	*const value = Malloc(MB_CHAT, strlen(input) + 1);
     int		k;
 
     for (k = 0; k < nmatch; k++) {
@@ -1567,7 +1565,7 @@
 	ChatVarSet(c, CHAT_VAR_MATCHED, value, 0, 0);
       ChatVarSet(c, name, value, 0, 0);
     }
-    (*c->free)(c->arg, value);
+    Freee(value);
   }
   va_end(args);
 }
@@ -1610,13 +1608,13 @@
 ChatMatchRegex(ChatInfo c, regex_t *reg, const char *input)
 {
   const int	nmatch = reg->re_nsub + 1;
-  regmatch_t	*pmatch = (*c->malloc)(c->arg, nmatch * sizeof(*pmatch));
+  regmatch_t	*pmatch = Malloc(MB_CHAT, nmatch * sizeof(*pmatch));
   int		rtn, match;
+  Link		const l = (Link) c->arg;
 
-  memset(pmatch, 0, nmatch * sizeof(*pmatch));
   switch ((rtn = regexec(reg, input, nmatch, pmatch, 0))) {
     default:
-      (*c->log)(c->arg, CHAT_LG_ERROR, "regexec() returned %d?", rtn);
+      Log(LG_ERR, ("[%s] CHAT: regexec() returned %d?", l->name, rtn));
       /* fall through */
     case REG_NOMATCH:
       match = 0;
@@ -1626,7 +1624,7 @@
       match = 1;
       break;
   }
-  (*c->free)(c->arg, pmatch);
+  Freee(pmatch);
   return match;
 }
 
@@ -1647,8 +1645,7 @@
   const int	len = strlen(ex->pat);
   int		i, j, k;
 
-  ex->fail = (u_short *) (*c->malloc)(c->arg, len * sizeof(*ex->fail));
-  memset(ex->fail, 0, len * sizeof(*ex->fail));
+  ex->fail = (u_short *) Malloc(MB_CHAT, len * sizeof(*ex->fail));
   for (i = 1; i < len; i++) {
     for (j = i - 1; j > 0; j--) {
       for (k = 0; k < j && ex->pat[k] == ex->pat[i - j + k]; k++);
@@ -1669,13 +1666,14 @@
 {
   u_long	secs;
   char		*secstr, *mark;
+  Link		const l = (Link) c->arg;
 
   secstr = ChatExpandString(c, string);
   secs = strtoul(secstr, &mark, 0);
-  (*c->free)(c->arg, secstr);
+  Freee(secstr);
   if (mark == secstr) {
-    (*c->log)(c->arg, CHAT_LG_ERROR,
-      "line %d: illegal value \"%s\"", c->lineNum, string);
+    Log(LG_ERR, ("[%s] CHAT: line %d: illegal value \"%s\"",
+      l->name, c->lineNum, string));
     return(0);
   }
   *secsp = (u_int) secs;
@@ -1724,12 +1722,13 @@
   va_list	args;
   char		cbuf[128];
   int		k, pos;
+  Link		const l = (Link) c->arg;
 
   /* Do label */
   va_start(args, fmt);
   vsnprintf(cbuf, sizeof(cbuf), fmt, args);
   va_end(args);
-  (*c->log)(c->arg, CHAT_LG_DEBUG, "%s", cbuf);
+  Log(LG_CHAT2, ("[%s] CHAT: %s", l->name, cbuf));
 
   /* Do bytes */
   for (pos = 0; pos < len; pos += DUMP_BYTES_PER_LINE) {
@@ -1753,8 +1752,6 @@
 		" ");
 	}
     }
-    (*c->log)(c->arg, CHAT_LG_DEBUG, "%s", cbuf);
+    Log(LG_CHAT2, ("[%s] CHAT: %s", l->name, cbuf));
   }
 }
-
-
--- a/contrib/mpd/src/chat.h	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/chat.h	Tue Jul 05 12:33:06 2011 +0300
@@ -42,19 +42,14 @@
 
 /* Callback function types */
 
-  typedef void	(*chatlogfunc_t)(void *arg, int level, const char *fmt, ...);
   typedef int	(*chatbaudfunc_t)(void *arg, int rate);
   typedef void	(*chatresultfunc_t)(void *arg, int r, const char *msg);
-  typedef void	*(*chatmallocfunc_t)(void *arg, size_t size);
-  typedef void	(*chatfreefunc_t)(void *arg, void *mem);
 
 /*
  * FUNCTIONS
  */
 
-  extern ChatInfo	ChatInit(void *arg, chatbaudfunc_t setBaudrate,
-			  chatlogfunc_t logger, chatmallocfunc_t mallocer,
-			  chatfreefunc_t freer);
+  extern ChatInfo	ChatInit(void *arg, chatbaudfunc_t setBaudrate);
   extern void		ChatPresetVar(ChatInfo c,
 			  const char *var, const char *value);
   extern char		*ChatGetVar(ChatInfo c, const char *var);
--- a/contrib/mpd/src/command.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/command.c	Tue Jul 05 12:33:06 2011 +0300
@@ -66,16 +66,30 @@
     SET_PIPE,
     SET_TABLE,
 #endif
+#ifdef PHYSTYPE_PPTP
     SET_PPTPTO,
     SET_PPTPLIMIT,
+#endif
+#ifdef PHYSTYPE_L2TP
     SET_L2TPTO,
     SET_L2TPLIMIT,
+#endif
     SET_MAX_CHILDREN,
 #ifdef USE_NG_BPF
     SET_FILTER
 #endif
   };
 
+  enum {
+    SHOW_IFACE,
+    SHOW_IP,
+    SHOW_USER,
+    SHOW_SESSION,
+    SHOW_MSESSION,
+    SHOW_BUNDLE,
+    SHOW_LINK,
+    SHOW_PEER
+  };
 
 /*
  * INTERNAL FUNCTIONS
@@ -120,14 +134,18 @@
     { "starttable {num}", 		"Initial ipfw table number" ,
        	GlobalSetCommand, NULL, 2, (void *) SET_TABLE },
 #endif /* USE_IPFW */
+#ifdef PHYSTYPE_L2TP
     { "l2tptimeout {sec}", 		"L2TP tunnel unused timeout" ,
        	GlobalSetCommand, NULL, 2, (void *) SET_L2TPTO },
     { "l2tplimit {num}", 		"Calls per L2TP tunnel limit" ,
        	GlobalSetCommand, NULL, 2, (void *) SET_L2TPLIMIT },
+#endif
+#ifdef PHYSTYPE_PPTP
     { "pptptimeout {sec}", 		"PPTP tunnel unused timeout" ,
        	GlobalSetCommand, NULL, 2, (void *) SET_PPTPTO },
     { "pptplimit {num}", 		"Calls per PPTP tunnel limit" ,
        	GlobalSetCommand, NULL, 2, (void *) SET_PPTPLIMIT },
+#endif
     { "max-children {num}",		"Max number of children",
 	GlobalSetCommand, NULL, 2, (void *) SET_MAX_CHILDREN },
 #ifdef USE_NG_BPF
@@ -138,7 +156,7 @@
   };
 
   static const struct confinfo	gGlobalConfList[] = {
-#ifdef USE_SYSTEM
+#ifdef USE_WRAP
     { 0,	GLOBAL_CONF_TCPWRAPPER,	"tcp-wrapper"	},
 #endif
     { 0,	GLOBAL_CONF_ONESHOT,	"one-shot"	},
@@ -161,6 +179,26 @@
     { NULL },
   };
 
+  static const struct cmdtab ShowSessCmds[] = {
+    { "iface {name}",			"Filter by iface name",
+	ShowSessions, NULL, 2, (void *) SHOW_IFACE },
+    { "ip {ip}",			"Filter by IP address",
+	ShowSessions, NULL, 2, (void *) SHOW_IP },
+    { "user {name}",			"Filter by user name",
+	ShowSessions, NULL, 2, (void *) SHOW_USER },
+    { "session {ID}",			"Filter by session ID",
+	ShowSessions, NULL, 2, (void *) SHOW_SESSION },
+    { "msession {ID}",			"Filter by msession ID",
+	ShowSessions, NULL, 2, (void *) SHOW_MSESSION },
+    { "bundle {name}",			"Filter by bundle name",
+	ShowSessions, NULL, 2, (void *) SHOW_BUNDLE },
+    { "link {name}",			"Filter by link name",
+	ShowSessions, NULL, 2, (void *) SHOW_LINK },
+    { "peer {name}",			"Filter by peer name",
+	ShowSessions, NULL, 2, (void *) SHOW_PEER },
+    { NULL },
+  };
+
   static const struct cmdtab ShowCommands[] = {
     { "bundle [{name}]",		"Bundle status",
 	BundStat, AdmitBund, 0, NULL },
@@ -177,7 +215,7 @@
     { "ecp",				"ECP status",
 	EcpStat, AdmitBund, 0, NULL },
     { "eap",				"EAP status",
-	EapStat, AdmitBund, 0, NULL },
+	EapStat, AdmitLink, 0, NULL },
     { "events",				"Current events",
 	ShowEvents, NULL, 0, NULL },
     { "ipcp",				"IPCP status",
@@ -235,7 +273,7 @@
     { "version",			"Version string",
 	ShowVersion, NULL, 0, NULL },
     { "sessions [ {param} {value} ]",	"Active sessions",
-	ShowSessions, NULL, 0, NULL },
+	CMD_SUBMENU, NULL, 2, (void *) ShowSessCmds},
     { "summary",			"Daemon status summary",
 	ShowSummary, NULL, 0, NULL },
     { NULL },
@@ -485,9 +523,15 @@
 	return(CMD_ERR_NOCTX);
 
     /* Find command and either execute or recurse into a submenu */
-    if (cmd->func == CMD_SUBMENU)
-	rtn = DoCommandTab(ctx, (CmdTab) cmd->arg, ac - 1, av + 1);
-    else
+    if (cmd->func == CMD_SUBMENU) {
+        if ((intptr_t)cmd->arg == (intptr_t)ShowSessCmds) {
+            if (ac > 1)
+	        rtn = DoCommandTab(ctx, (CmdTab) cmd->arg, ac - 1, av + 1);
+            else
+                rtn = ShowSessions(ctx, 0, NULL, NULL);
+        } else
+            rtn = DoCommandTab(ctx, (CmdTab) cmd->arg, ac - 1, av + 1);
+    } else
 	rtn = (cmd->func)(ctx, ac - 1, av + 1, cmd->arg);
 
     return(rtn);
@@ -594,6 +638,7 @@
       break;
 #endif /* USE_IPFW */
 
+#ifdef PHYSTYPE_L2TP
     case SET_L2TPTO:
 	val = atoi(*av);
 	if (val < 0 || val > 1000000)
@@ -609,7 +654,9 @@
 	else
 	    gL2TPtunlimit = val;
       break;
+#endif
 
+#ifdef PHYSTYPE_PPTP
     case SET_PPTPTO:
 	val = atoi(*av);
 	if (val < 0 || val > 1000000)
@@ -625,6 +672,7 @@
 	else
 	    gPPTPtunlimit = val;
       break;
+#endif
 
     case SET_MAX_CHILDREN:
 	val = atoi(*av);
@@ -786,6 +834,21 @@
 {
   Printf("MPD version: %s\r\n", gVersion);
   Printf("  Available features:\r\n");
+#ifdef	USE_IPFW
+  Printf("	ipfw rules	: yes\r\n");
+#else
+  Printf("	ipfw rules	: no\r\n");
+#endif
+#ifdef	USE_FETCH
+  Printf("	config fetch	: yes\r\n");
+#else
+  Printf("	config fetch	: no\r\n");
+#endif
+#ifdef	USE_NG_BPF
+  Printf("	ng_bpf		: yes\r\n");
+#else
+  Printf("	ng_bpf		: no\r\n");
+#endif
 #ifdef	USE_NG_CAR
   Printf("	ng_car		: yes\r\n");
 #else
@@ -810,6 +873,11 @@
 #endif
 #ifdef	USE_NG_NAT
   Printf("	ng_nat		: yes\r\n");
+#ifdef NG_NAT_DESC_LENGTH
+  Printf("	nat redirect	: yes\r\n");
+#else
+  Printf("	nat redirect	: no\r\n");
+#endif
 #else
   Printf("	ng_nat		: no\r\n");
 #endif
@@ -860,10 +928,14 @@
     Printf("	startqueue	: %d\r\n", queue_pool_start);
     Printf("	starttable	: %d\r\n", table_pool_start);
 #endif
+#ifdef PHYSTYPE_L2TP
     Printf("	l2tptimeout	: %d\r\n", gL2TPto);
     Printf("	l2tplimit	: %d\r\n", gL2TPtunlimit);
+#endif
+#ifdef PHYSTYPE_PPTP
     Printf("	pptptimeout	: %d\r\n", gPPTPto);
     Printf("	pptplimit	: %d\r\n", gPPTPtunlimit);
+#endif
     Printf("	max-children	: %d\r\n", gMaxChildren);
     Printf("Global options:\r\n");
     OptStat(ctx, &gGlobalConf.options, gGlobalConfList);
@@ -960,7 +1032,9 @@
 #endif
 		strlcpy(filename, av[0], sizeof(filename));
 	}
-	ReadFile(filename, av[ac - 1], DoCommand, ctx);
+	if (ReadFile(filename, av[ac - 1], DoCommand, ctx) < 0)
+	    Printf("can't read configuration for \"%s\" from \"%s\"\r\n",
+		av[ac -1], filename);
 #ifdef USE_FETCH
 out:	if (fetch)
 	    unlink(filename);
@@ -1067,6 +1141,7 @@
   int	k;
 
   Printf("\tName\t\tDescription\r\n");
+  Printf("\t----\t\t-----------\r\n");
   for (k = 0; k < NUM_LAYERS; k++)
     Printf("\t%s\t\t%s\r\n", gLayers[k].name, gLayers[k].desc);
   return(0);
@@ -1083,6 +1158,7 @@
   int		k;
 
   Printf("\tName\t\tDescription\r\n");
+  Printf("\t----\t\t-----------\r\n");
   for (k = 0; (pt = gPhysTypes[k]); k++)
     Printf("\t%s\t\t%s\r\n", pt->name, pt->descr);
   return(0);
@@ -1186,7 +1262,7 @@
     Link  	L;
     char	peer[64], addr[64];
 
-    if (ac != 0 && ac != 2)
+    if (ac != 0 && ac != 1)
 	return (-1);
 
     for (l = 0; l < gNumLinks; l++) {
@@ -1194,29 +1270,37 @@
 	    B = L->bund;
 	    u_addrtoa(&B->iface.peer_addr, addr, sizeof(addr));
 	    PhysGetPeerAddr(L, peer, sizeof(peer));
-	    if (ac == 2) {
-		if (!strcmp(av[0], "iface")) {
-		    if (strcmp(av[1], B->iface.ifname))
+	    if (ac == 0)
+	        goto out;
+	    switch ((intptr_t)arg) {
+		case SHOW_IFACE:
+		    if (strcmp(av[0], B->iface.ifname))
 			continue;
-		} else if (!strcmp(av[0], "ip")) {
-		    if (strcmp(av[1], addr))
+		    break;
+		case SHOW_IP:
+		    if (strcmp(av[0], addr))
 			continue;
-		} else if (!strcmp(av[0], "user")) {
-		    if (strcmp(av[1], L->lcp.auth.params.authname))
+		    break;
+		case SHOW_USER:
+		    if (strcmp(av[0], L->lcp.auth.params.authname))
 			continue;
-		} else if (!strcmp(av[0], "msession")) {
-		    if (strcmp(av[1], B->msession_id))
+		    break;
+		case SHOW_MSESSION:
+		    if (strcmp(av[0], B->msession_id))
 			continue;
-		} else if (!strcmp(av[0], "session")) {
-		    if (strcmp(av[1], L->session_id))
+		    break;
+		case SHOW_SESSION:
+		    if (strcmp(av[0], L->session_id))
 			continue;
-		} else if (!strcmp(av[0], "bundle")) {
-		    if (strcmp(av[1], B->name))
+		    break;
+		case SHOW_BUNDLE:
+		    if (strcmp(av[0], B->name))
 			continue;
-		} else if (!strcmp(av[0], "link")) {
-		    if (av[1][0] == '[') {
+		    break;
+		case SHOW_LINK:
+		    if (av[0][0] == '[') {
 			int k;
-			if (sscanf(av[1], "[%x]", &k) != 1)
+			if (sscanf(av[0], "[%x]", &k) != 1)
 			    return (-1);
 			else {
 			    if (L->id != k)
@@ -1226,12 +1310,15 @@
 			if (strcmp(av[1], L->name))
 			    continue;
 		    }
-		} else if (!strcmp(av[0], "peer")) {
-		    if (strcmp(av[1], peer))
+		    break;
+		case SHOW_PEER:
+		    if (strcmp(av[0], peer))
 			continue;
-		} else
+			break;
+		default:
 		    return (-1);
 	    }
+out:
 	    Printf("%s\t%s\t%s\t%s\t", B->iface.ifname,
 		addr, B->name, B->msession_id);
 	    Printf("%s\t%d\t%s\t%s\t%s", 
--- a/contrib/mpd/src/command.h	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/command.h	Tue Jul 05 12:33:06 2011 +0300
@@ -28,7 +28,9 @@
 
   /* Configuration options */
   enum {
+#ifdef USE_WRAP
     GLOBAL_CONF_TCPWRAPPER,	/* enable tcp-wrapper */
+#endif
     GLOBAL_CONF_ONESHOT		/* enable OneShot mode */
   };
 
--- a/contrib/mpd/src/config.h	Tue Jul 05 12:30:56 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-/* System features detected by configure */
-#define	HAVE_NG_BPF	1
-#define	HAVE_NG_CAR	1
-#define	HAVE_NG_DEFLATE	1
-#define	HAVE_NG_MPPC	1
-#define	HAVE_NG_NAT	1
-#define	HAVE_NG_NETFLOW	1
-#define	HAVE_NG_PRED1	1
-#define	HAVE_NG_TCPMSS	1
-#define	HAVE_NG_VJC	1
-#define	HAVE_IPFW	1
--- a/contrib/mpd/src/event.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/event.c	Tue Jul 05 12:33:06 2011 +0300
@@ -1,7 +1,7 @@
 /*
  * See ``COPYRIGHT.mpd''
  *
- * $Id: event.c,v 1.19 2008/03/11 14:26:55 amotin Exp $
+ * $Id: event.c,v 1.20 2011/06/30 09:17:28 dmitryluhtionov Exp $
  *
  */
 
@@ -60,7 +60,7 @@
   u_int	n;
 
   n = pevent_ctx_count(gPeventCtx);
-  Printf("%d Events registered\n", n);
+  Printf("%d Events registered\r\n", n);
 }
 
 /*
--- a/contrib/mpd/src/l2tp.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/l2tp.c	Tue Jul 05 12:33:06 2011 +0300
@@ -72,6 +72,7 @@
 	char		callednum[64];	/* L2TP phone number to use */
 	char 		hostname[MAXHOSTNAMELEN]; /* L2TP local hostname */
 	char		secret[64];	/* L2TP tunnel secret */
+	char		*fqdn_peer_addr;	/* FQDN Peer address */
     } conf;
     u_char		opened;		/* L2TP opened by phys */
     u_char		incoming;	/* Call is incoming vs. outgoing */
@@ -102,7 +103,8 @@
     L2TP_CONF_OUTCALL,		/* when originating, calls are "outgoing" */
     L2TP_CONF_HIDDEN,		/* enable AVP hidding */
     L2TP_CONF_LENGTH,		/* enable Length field in data packets */
-    L2TP_CONF_DATASEQ		/* enable sequence fields in data packets */
+    L2TP_CONF_DATASEQ,		/* enable sequence fields in data packets */
+    L2TP_CONF_RESOLVE_ONCE	/* Only once resolve peer_addr */
   };
 
 /*
@@ -224,6 +226,7 @@
     { 0,	L2TP_CONF_HIDDEN,	"hidden"	},
     { 0,	L2TP_CONF_LENGTH,	"length"	},
     { 0,	L2TP_CONF_DATASEQ,	"dataseq"	},
+    { 0,	L2TP_CONF_RESOLVE_ONCE,	"resolve-once"	},
     { 0,	0,			NULL		},
   };
 
@@ -293,8 +296,10 @@
     l2tp->conf.peer_addr.addr.family = AF_INET;
     l2tp->conf.peer_addr.width = 0;
     l2tp->conf.peer_port = 0;
+    l2tp->conf.fqdn_peer_addr = NULL;
 
     Enable(&l2tp->conf.options, L2TP_CONF_DATASEQ);
+    Enable(&l2tp->conf.options, L2TP_CONF_RESOLVE_ONCE);
   
     return(0);
 }
@@ -399,6 +404,13 @@
 	strlcpy(pi->callingnum, pi->conf.callingnum, sizeof(pi->callingnum));
 	strlcpy(pi->callednum, pi->conf.callednum, sizeof(pi->callednum));
 
+	if ((!Enabled(&pi->conf.options, L2TP_CONF_RESOLVE_ONCE)) &&
+	    (pi->conf.fqdn_peer_addr != NULL)) {
+	    struct u_range	rng;
+	    if (ParseRange(pi->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
+		pi->conf.peer_addr = rng;
+	}
+
 	ghash_walk_init(gL2tpTuns, &walk);
 	while ((tun = ghash_walk_next(gL2tpTuns, &walk)) != NULL) {
 	    if (tun->ctrl && tun->alive && tun->active_sessions < gL2TPtunlimit &&
@@ -673,6 +685,11 @@
 static void
 L2tpShutdown(Link l)
 {
+    L2tpInfo const pi = (L2tpInfo) l->info;
+
+    if (pi->conf.fqdn_peer_addr)
+        Freee(pi->conf.fqdn_peer_addr);
+
     L2tpUnListen(l);
     Freee(l->info);
 }
@@ -899,6 +916,7 @@
     Printf("\tSelf addr    : %s, port %u",
 	u_addrtoa(&l2tp->conf.self_addr, buf, sizeof(buf)), l2tp->conf.self_port);
     Printf("\r\n");
+    Printf("\tPeer FQDN    : %s\r\n", l2tp->conf.fqdn_peer_addr);
     Printf("\tPeer range   : %s",
 	u_rangetoa(&l2tp->conf.peer_addr, buf, sizeof(buf)));
     if (l2tp->conf.peer_port)
@@ -1706,12 +1724,18 @@
 L2tpSetCommand(Context ctx, int ac, char *av[], void *arg)
 {
     L2tpInfo		const l2tp = (L2tpInfo) ctx->lnk->info;
+    char		**fqdn_peer_addr = &l2tp->conf.fqdn_peer_addr;
     struct u_range	rng;
     int			port;
 
     switch ((intptr_t)arg) {
 	case SET_SELFADDR:
 	case SET_PEERADDR:
+	    if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
+		if (*fqdn_peer_addr)
+		    Freee(*fqdn_peer_addr);
+		*fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
+	    }
     	    if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
 		return(-1);
     	    if (ac > 1) {
--- a/contrib/mpd/src/l2tp_avp.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/l2tp_avp.c	Tue Jul 05 12:33:06 2011 +0300
@@ -164,7 +164,7 @@
 	struct ppp_l2tp_avp *elem;
 	struct ppp_l2tp_avp *avp;
 
-	if (index < 0 || index >= list->length) {
+	if (index >= list->length) {
 		errno = EINVAL;
 		return (NULL);
 	}
@@ -182,7 +182,7 @@
 int
 ppp_l2tp_avp_list_remove(struct ppp_l2tp_avp_list *list, u_int index)
 {
-	if (index < 0 || index >= list->length) {
+	if (index >= list->length) {
 		errno = EINVAL;
 		return (-1);
 	}
--- a/contrib/mpd/src/log.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/log.c	Tue Jul 05 12:33:06 2011 +0300
@@ -178,7 +178,8 @@
 int
 LogCommand(Context ctx, int ac, char *av[], void *arg)
 {
-    int	k, bits, add;
+    u_int	k;
+    int		bits, add;
 
     if (ac == 0) {
 #define LG_FMT	"    %-12s  %-10s  %s\r\n"
@@ -280,16 +281,10 @@
     va_list       args;
 
     va_start(args, fmt);
-    vLogPrintf2(fmt, args);
-    va_end(args);
-}
-
-void
-vLogPrintf2(const char *fmt, va_list args)
-{
 #ifdef SYSLOG_FACILITY
     vsyslog(LOG_INFO, fmt, args);
 #endif
+    va_end(args);
 }
 
 /*
--- a/contrib/mpd/src/log.h	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/log.h	Tue Jul 05 12:33:06 2011 +0300
@@ -137,7 +137,6 @@
 #ifdef SYSLOG_FACILITY
   extern char	gSysLogIdent[32];
 #endif
-  extern int	gLogInfo;
 
 /*
  * FUNCTIONS
@@ -148,7 +147,6 @@
   extern void	LogPrintf(const char *fmt, ...) __printflike(1, 2);
   extern void	vLogPrintf(const char *fmt, va_list args);
   extern void	LogPrintf2(const char *fmt, ...) __printflike(1, 2);
-  extern void	vLogPrintf2(const char *fmt, va_list args);
   extern int	LogCommand(Context ctx, int ac, char *av[], void *arg);
   extern void	LogDumpBuf2(const u_char *buf, int len,
 			const char *fmt, ...) __printflike(3, 4);
--- a/contrib/mpd/src/main.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/main.c	Tue Jul 05 12:33:06 2011 +0300
@@ -97,14 +97,18 @@
   pid_t          	gPid;
   int			gRouteSeq = 0;
 
+#ifdef PHYSTYPE_PPTP
   int			gPPTPto = 10;
   int			gPPTPtunlimit = 100;
+#endif
+#ifdef PHYSTYPE_L2TP
   int			gL2TPto = 10;
 #if ((__FreeBSD_version > 603100 && __FreeBSD_version < 700000) || __FreeBSD_version >= 700055)
   int			gL2TPtunlimit = 100;
 #else
   int			gL2TPtunlimit = 10;
 #endif
+#endif
   int			gChildren = 0;		/* Current number of children links */
   int			gMaxChildren = 10000;	/* Maximal number of children links */
 
@@ -634,7 +638,7 @@
 OptDecode(char *arg, int longform)
 {
     Option	opt;
-    int		k;
+    size_t	k;
 
     for (k = 0; k < OPTLIST_SIZE; k++) {
 	opt = OptList + k;
@@ -654,7 +658,7 @@
 {
     Option		opt;
     char		buf[100];
-    int			k;
+    size_t		k;
 
     fprintf(stderr, "Usage: mpd %s\n", UsageStr);
     fprintf(stderr, "Options:\n");
--- a/contrib/mpd/src/mbuf.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/mbuf.c	Tue Jul 05 12:33:06 2011 +0300
@@ -318,7 +318,7 @@
 MemStat(Context ctx, int ac, char *av[], void *arg)
 {
     struct typed_mem_stats stats;
-    int		i;
+    u_int	i;
     u_int	total_allocs = 0;
     u_int	total_bytes = 0;
 
--- a/contrib/mpd/src/mbuf.h	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/mbuf.h	Tue Jul 05 12:33:06 2011 +0300
@@ -54,6 +54,7 @@
   #define MB_PHYS	"PHYS"
   #define MB_PPTP	"PPTP"
   #define MB_RADIUS	"RADIUS"
+  #define MB_RADSRV	"RADSRV"
   #define MB_UTIL	"UTIL"
   #define MB_VJCOMP	"VJCOMP"
   #define MB_IPPOOL	"IPPOOL"
--- a/contrib/mpd/src/modem.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/modem.c	Tue Jul 05 12:33:06 2011 +0300
@@ -111,10 +111,6 @@
 
   /* Chat callbacks */
   static int		ModemChatSetBaudrate(void *arg, int baud);
-  static void		ModemChatLog(void *arg,
-				int level, const char *fmt, ...);
-  static void		*ModemChatMalloc(void *arg, size_t size);
-  static void		ModemChatFree(void *arg, void *mem);
   static void		ModemChatConnectResult(void *arg,
 				int rslt, const char *msg);
   static void		ModemChatIdleResult(void *arg, int rslt,
@@ -192,8 +188,7 @@
 
     m = (ModemInfo) (l->info = Malloc(MB_PHYS, sizeof(*m)));
     m->watch = TIOCM_CAR;
-    m->chat = ChatInit(l, ModemChatSetBaudrate,
-		ModemChatLog, ModemChatMalloc, ModemChatFree);
+    m->chat = ChatInit(l, ModemChatSetBaudrate);
     m->fd = -1;
     m->opened = FALSE;
 
@@ -260,8 +255,10 @@
     }
 
     /* Open and configure serial port */
-    if ((m->fd = OpenSerialDevice(l->name, m->device, m->speed)) < 0)
+    if ((m->fd = OpenSerialDevice(l->name, m->device, m->speed)) < 0) {
+	m->opened = FALSE;
         goto fail;
+    }
 
     /* If connecting, but no connect script, then skip chat altogether */
     if (m->opened && !*m->connScript) {
@@ -690,70 +687,6 @@
 }
 
 /*
- * ModemChatLog()
- */
-
-static void
-ModemChatLog(void *arg, int level, const char *fmt, ...)
-{
-    Link	const l = (Link) arg;
-    char	buf[128];
-    va_list	args;
-    int		logLevel;
-
-    /* Convert level */
-    switch (level) {
-	default:
-	case CHAT_LG_NORMAL:
-    	    logLevel = LG_CHAT;
-    	    break;
-	case CHAT_LG_ERROR:
-    	    logLevel = LG_ERR;
-    	    break;
-	case CHAT_LG_DEBUG:
-    	    logLevel = LG_CHAT2;
-    	    break;
-    }
-    if ((gLogOptions & logLevel) == 0)
-	return;
-
-    /* Concat prefix and message */
-    va_start(args, fmt);
-    vsnprintf(buf, sizeof(buf), fmt, args);
-    va_end(args);
-    if (*buf != ' ')
-	snprintf(buf, sizeof(buf), "[%s] chat: ", l->name);
-    else
-	*buf = '\0';
-    va_start(args, fmt);
-    vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, args);
-    va_end(args);
-
-    /* Log it */
-    LogPrintf("%s", buf);
-}
-
-/*
- * ModemChatMalloc()
- */
-
-static void *
-ModemChatMalloc(void *arg, size_t size)
-{
-    return Malloc(MB_CHAT, size);
-}
-
-/*
- * ModemChatFree()
- */
-
-static void
-ModemChatFree(void *arg, void *mem)
-{
-    Freee(mem);
-}
-
-/*
  * ModemGetVar()
  */
 
--- a/contrib/mpd/src/ppp.h	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/ppp.h	Tue Jul 05 12:33:06 2011 +0300
@@ -196,10 +196,14 @@
   extern pid_t		gPid;
   extern int		gRouteSeq;
 
+#ifdef PHYSTYPE_PPTP
   extern int		gPPTPto;
   extern int		gPPTPtunlimit;
+#endif
+#ifdef PHYSTYPE_L2TP
   extern int		gL2TPto;
   extern int		gL2TPtunlimit;
+#endif
   extern int		gChildren;
   extern int		gMaxChildren;
 
--- a/contrib/mpd/src/pptp.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/pptp.c	Tue Jul 05 12:33:06 2011 +0300
@@ -48,6 +48,7 @@
 	struct optinfo	options;
 	char		callingnum[64];	/* PPTP phone number to use */
 	char		callednum[64];	/* PPTP phone number to use */
+	char		*fqdn_peer_addr;	/* FQDN Peer address */
     } conf;
     void		*listener;	/* Listener pointer */
     struct u_addr	self_addr;	/* Current self IP address */
@@ -81,6 +82,7 @@
     PPTP_CONF_OUTCALL,		/* when originating, calls are "outgoing" */
     PPTP_CONF_DELAYED_ACK,	/* enable delayed receive ack algorithm */
     PPTP_CONF_ALWAYS_ACK,	/* include ack with all outgoing data packets */
+    PPTP_CONF_RESOLVE_ONCE,	/* Only once resolve peer_addr */
 #if NGM_PPTPGRE_COOKIE >= 1082548365
     PPTP_CONF_WINDOWING		/* control (stupid) windowing algorithm */
 #endif
@@ -204,6 +206,7 @@
     { 0,	PPTP_CONF_OUTCALL,	"outcall"	},
     { 0,	PPTP_CONF_DELAYED_ACK,	"delayed-ack"	},
     { 0,	PPTP_CONF_ALWAYS_ACK,	"always-ack"	},
+    { 0,	PPTP_CONF_RESOLVE_ONCE,	"resolve-once"	},
 #if NGM_PPTPGRE_COOKIE >= 1082548365
     { 0,	PPTP_CONF_WINDOWING,	"windowing"	},
 #endif
@@ -249,8 +252,10 @@
     pptp = (PptpInfo) (l->info = Malloc(MB_PHYS, sizeof(*pptp)));
 
     pptp->conf.self_addr.family = AF_INET;
+    pptp->conf.fqdn_peer_addr = NULL;
     Enable(&pptp->conf.options, PPTP_CONF_OUTCALL);
     Enable(&pptp->conf.options, PPTP_CONF_DELAYED_ACK);
+    Enable(&pptp->conf.options, PPTP_CONF_RESOLVE_ONCE);
 
     return(0);
 }
@@ -354,6 +359,12 @@
     linfo.cancel = PptpCancel;
     strlcpy(pptp->callingnum, pptp->conf.callingnum, sizeof(pptp->callingnum));
     strlcpy(pptp->callednum, pptp->conf.callednum, sizeof(pptp->callednum));
+    if ((!Enabled(&pptp->conf.options, PPTP_CONF_RESOLVE_ONCE)) &&
+	(pptp->conf.fqdn_peer_addr != NULL)) {
+	struct u_range	rng;
+	if (ParseRange(pptp->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
+	    pptp->conf.peer_addr = rng;
+    }
     if (!pptp->outcall) {
 	int frameType = PPTP_FRAMECAP_SYNC;
 	if (l->rep && !RepIsSync(l))
@@ -397,6 +408,9 @@
 {
     PptpInfo      const pptp = (PptpInfo) l->info;
 
+
+    if (pptp->conf.fqdn_peer_addr)
+        Freee(pptp->conf.fqdn_peer_addr);
     if (pptp->listener) {
 	PptpCtrlUnListen(pptp->listener);
 	pptp->listener = NULL;
@@ -630,6 +644,7 @@
     if (pptp->conf.self_port)
 	Printf(", port %u", pptp->conf.self_port);
     Printf("\r\n");
+    Printf("\tPeer FQDN    : %s\r\n", pptp->conf.fqdn_peer_addr);
     Printf("\tPeer range   : %s",
 	u_rangetoa(&pptp->conf.peer_addr, buf, sizeof(buf)));
     if (pptp->conf.peer_port)
@@ -1165,12 +1180,18 @@
 PptpSetCommand(Context ctx, int ac, char *av[], void *arg)
 {
     PptpInfo		const pi = (PptpInfo) ctx->lnk->info;
+    char		**fqdn_peer_addr = &pi->conf.fqdn_peer_addr;
     struct u_range	rng;
     int			port;
 
     switch ((intptr_t)arg) {
 	case SET_SELFADDR:
 	case SET_PEERADDR:
+	    if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
+		if (*fqdn_peer_addr)
+		    Freee(*fqdn_peer_addr);
+		*fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
+	    }
     	    if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
 		return(-1);
     	    if (ac > 1) {
--- a/contrib/mpd/src/radius.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/radius.c	Tue Jul 05 12:33:06 2011 +0300
@@ -1,7 +1,7 @@
 /*
  * See ``COPYRIGHT.mpd''
  *
- * $Id: radius.c,v 1.153 2010/12/29 12:13:27 amotin Exp $
+ * $Id: radius.c,v 1.155 2011/07/01 06:51:48 dmitryluhtionov Exp $
  *
  */
 
@@ -1427,7 +1427,7 @@
       case RAD_USER_NAME:
 	tmpval = rad_cvt_string(data, len);
 	/* copy it into the persistent data struct */
-	strcpy(auth->params.authname, tmpval);
+	strlcpy(auth->params.authname, tmpval, sizeof(auth->params.authname));
 	free(tmpval);
 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_USER_NAME: %s ",
 	  auth->info.lnkname, auth->params.authname));
@@ -1569,7 +1569,7 @@
       case RAD_FRAMED_POOL:
 	tmpval = rad_cvt_string(data, len);
 	/* copy it into the persistent data struct */
-	strcpy(auth->params.ippool, tmpval);
+	strlcpy(auth->params.ippool, tmpval, sizeof(auth->params.ippool));
 	free(tmpval);
 	Log(LG_RADIUS2, ("[%s] RADIUS: Get RAD_FRAMED_POOL: %s ",
 	  auth->info.lnkname, auth->params.ippool));
--- a/contrib/mpd/src/radsrv.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/radsrv.c	Tue Jul 05 12:33:06 2011 +0300
@@ -180,7 +180,7 @@
 		state_len = len;
 		if (state != NULL)
 		    Freee(state);
-		state = Mdup(MB_AUTH, data, len);
+		state = Mdup(MB_RADSRV, data, len);
 		break;
 	    case RAD_CALLED_STATION_ID:
 		anysesid = 1;
@@ -774,14 +774,14 @@
 	  Error("cannot configure more than %d peers",
 	    RADSRV_MAX_SERVERS);
 	}
-	if (strlen(av[0]) > 255)
-	    Error("Hostname too long. > 255 char.");
+	if (strlen(av[0]) > MAXHOSTNAMELEN-1)
+	    Error("Hostname too long. > %d char.", MAXHOSTNAMELEN-1);
 	if (strlen(av[1]) > 127)
 	    Error("Shared Secret too long. > 127 char.");
 
-	peer = Malloc(MB_RADIUS, sizeof(*peer));
-	peer->hostname = Mstrdup(MB_RADIUS, av[0]);
-	peer->sharedsecret = Mstrdup(MB_RADIUS, av[1]);
+	peer = Malloc(MB_RADSRV, sizeof(*peer));
+	peer->hostname = Mstrdup(MB_RADSRV, av[0]);
+	peer->sharedsecret = Mstrdup(MB_RADSRV, av[1]);
 	peer->next = w->clients;
 	w->clients = peer;
 	break;
--- a/contrib/mpd/src/tcp.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/tcp.c	Tue Jul 05 12:33:06 2011 +0300
@@ -36,6 +36,7 @@
 	    struct u_range	peer_addr;
 	    in_port_t		self_port;
 	    in_port_t		peer_port;
+	    char		*fqdn_peer_addr; /* FQDN Peer address */
 	} conf;
 
 	/* State */
@@ -54,9 +55,16 @@
 /* Set menu options */
 enum {
 	SET_PEERADDR,
-	SET_SELFADDR
+	SET_SELFADDR,
+	SET_ENABLE,
+	SET_DISABLE
 };
 
+  /* Binary options */
+  enum {
+    TCP_CONF_RESOLVE_ONCE	/* Only once resolve peer_addr */
+  };
+
 /*
  * INTERNAL FUNCTIONS
  */
@@ -115,6 +123,10 @@
 	TcpSetCommand, NULL, 2, (void *) SET_SELFADDR },
     { "peer {ip} [{port}]",		"Set remote IP address",
 	TcpSetCommand, NULL, 2, (void *) SET_PEERADDR },
+    { "enable [opt ...]",		"Enable option",
+	TcpSetCommand, NULL, 2, (void *) SET_ENABLE },
+    { "disable [opt ...]",		"Disable option",
+	TcpSetCommand, NULL, 2, (void *) SET_DISABLE },
     { NULL },
 };
 
@@ -127,6 +139,15 @@
 };
 struct TcpIf TcpIfs[TCP_MAXPARENTIFS];
 
+ /*
+ * INTERNAL VARIABLES
+ */
+
+  static struct confinfo	gConfList[] = {
+    { 0,	TCP_CONF_RESOLVE_ONCE,	"resolve-once"	},
+    { 0,	0,			NULL		},
+  };
+
 /*
  * TcpInit()
  */
@@ -149,6 +170,8 @@
 
 	u_addrclear(&pi->peer_addr);
 	pi->peer_port=0;
+	pi->conf.fqdn_peer_addr = NULL;
+	Enable(&pi->conf.options, TCP_CONF_RESOLVE_ONCE);
 
 	return (0);
 }
@@ -260,6 +283,12 @@
 		PhysUp(l);
 		return;
 	}
+	if ((!Enabled(&pi->conf.options, TCP_CONF_RESOLVE_ONCE)) &&
+	    (pi->conf.fqdn_peer_addr != NULL)) {
+	    struct u_range	rng;
+	    if (ParseRange(pi->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
+		pi->conf.peer_addr = rng;
+	}
 
 	u_addrcopy(&pi->conf.peer_addr.addr,&pi->peer_addr);
 	pi->peer_port = pi->conf.peer_port;
@@ -515,6 +544,11 @@
 static void
 TcpShutdown(Link l)
 {
+    TcpInfo const pi = (TcpInfo) l->info;
+
+    if (pi->conf.fqdn_peer_addr)
+        Freee(pi->conf.fqdn_peer_addr);
+
 	TcpDoClose(l);
 	TcpUnListen(l);
 	Freee(l->info);
@@ -661,6 +695,7 @@
 	char	buf[48];
 
 	Printf("TCP configuration:\r\n");
+	Printf("\tPeer FQDN    : %s\r\n", pi->conf.fqdn_peer_addr);
 	Printf("\tSelf address : %s, port %u\r\n",
 	    u_addrtoa(&pi->conf.self_addr, buf, sizeof(buf)), pi->conf.self_port);
 	Printf("\tPeer address : %s, port %u\r\n",
@@ -836,12 +871,18 @@
 TcpSetCommand(Context ctx, int ac, char *av[], void *arg)
 {
     TcpInfo		const pi = (TcpInfo) ctx->lnk->info;
+    char		**fqdn_peer_addr = &pi->conf.fqdn_peer_addr;
     struct u_range	rng;
     int			port;
 
     switch ((intptr_t)arg) {
 	case SET_PEERADDR:
 	case SET_SELFADDR:
+	    if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
+		if (*fqdn_peer_addr)
+		    Freee(*fqdn_peer_addr);
+		*fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
+	    }
     	    if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
 		return(-1);
 	    if (ac > 1) {
@@ -862,6 +903,14 @@
 		TcpListen(ctx->lnk);
 	    }
 	    break;
+	case SET_ENABLE:
+	    EnableCommand(ac, av, &pi->conf.options, gConfList);
+	    TcpNodeUpdate(ctx->lnk);
+	    break;
+	case SET_DISABLE:
+	    DisableCommand(ac, av, &pi->conf.options, gConfList);
+	    TcpNodeUpdate(ctx->lnk);
+	    break;
 	default:
 		assert(0);
     }
--- a/contrib/mpd/src/udp.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/udp.c	Tue Jul 05 12:33:06 2011 +0300
@@ -40,6 +40,7 @@
 	struct u_range	peer_addr;	/* Configured peer IP address */
 	in_port_t	self_port;	/* Configured local port */
 	in_port_t	peer_port;	/* Configured peer port */
+	char		*fqdn_peer_addr; /* FQDN Peer address */
     } conf;
 
     /* State */
@@ -55,7 +56,14 @@
 
   enum {
     SET_PEERADDR,
-    SET_SELFADDR
+    SET_SELFADDR,
+    SET_ENABLE,
+    SET_DISABLE
+  };
+
+  /* Binary options */
+  enum {
+    UDP_CONF_RESOLVE_ONCE	/* Only once resolve peer_addr */
   };
 
 /*
@@ -113,6 +121,10 @@
 	UdpSetCommand, NULL, 2, (void *) SET_SELFADDR },
     { "peer {ip} [{port}]",		"Set remote IP address",
 	UdpSetCommand, NULL, 2, (void *) SET_PEERADDR },
+    { "enable [opt ...]",		"Enable option",
+	UdpSetCommand, NULL, 2, (void *) SET_ENABLE },
+    { "disable [opt ...]",		"Disable option",
+	UdpSetCommand, NULL, 2, (void *) SET_DISABLE },
     { NULL },
   };
 
@@ -128,6 +140,16 @@
 int UdpListenUpdateSheduled=0;
 struct pppTimer UdpListenUpdateTimer;
 
+ /*
+ * INTERNAL VARIABLES
+ */
+
+  static struct confinfo	gConfList[] = {
+    { 0,	UDP_CONF_RESOLVE_ONCE,	"resolve-once"	},
+    { 0,	0,			NULL		},
+  };
+
+
 /*
  * UdpInit()
  */
@@ -149,6 +171,8 @@
 
     u_addrclear(&pi->peer_addr);
     pi->peer_port=0;
+    pi->conf.fqdn_peer_addr = NULL;
+    Enable(&pi->conf.options, UDP_CONF_RESOLVE_ONCE);
 
     return(0);
 }
@@ -248,6 +272,13 @@
 	    goto fail;
 	}
 
+	if ((!Enabled(&pi->conf.options, UDP_CONF_RESOLVE_ONCE)) &&
+	    (pi->conf.fqdn_peer_addr != NULL)) {
+	    struct u_range	rng;
+	    if (ParseRange(pi->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
+		pi->conf.peer_addr = rng;
+	}
+
 	/* Bind socket */
 	u_addrtosockaddr(&pi->conf.self_addr, pi->conf.self_port, &addr);
 	if (NgSendMsg(csock, path, NGM_KSOCKET_COOKIE,
@@ -321,6 +352,11 @@
 static void
 UdpShutdown(Link l)
 {
+    UdpInfo const pi = (UdpInfo) l->info;
+
+    if (pi->conf.fqdn_peer_addr)
+        Freee(pi->conf.fqdn_peer_addr);
+
 	UdpDoClose(l);
 	UdpUnListen(l);
 	Freee(l->info);
@@ -463,6 +499,7 @@
 	char	buf[48];
 
 	Printf("UDP configuration:\r\n");
+	Printf("\tPeer FQDN    : %s\r\n", pi->conf.fqdn_peer_addr);
 	Printf("\tSelf address : %s, port %u\r\n",
 	    u_addrtoa(&pi->conf.self_addr, buf, sizeof(buf)), pi->conf.self_port);
 	Printf("\tPeer address : %s, port %u\r\n",
@@ -696,12 +733,18 @@
 UdpSetCommand(Context ctx, int ac, char *av[], void *arg)
 {
     UdpInfo		const pi = (UdpInfo) ctx->lnk->info;
+    char		**fqdn_peer_addr = &pi->conf.fqdn_peer_addr;
     struct u_range	rng;
     int			port;
 	
     switch ((intptr_t)arg) {
 	case SET_PEERADDR:
 	case SET_SELFADDR:
+	    if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
+		if (*fqdn_peer_addr)
+		    Freee(*fqdn_peer_addr);
+		*fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
+	    }
     	    if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
 		return(-1);
     	    if (ac > 1) {
@@ -722,6 +765,14 @@
 		UdpListen(ctx->lnk);
 	    }
     	    break;
+	case SET_ENABLE:
+	    EnableCommand(ac, av, &pi->conf.options, gConfList);
+	    UdpNodeUpdate(ctx->lnk);
+	    break;
+	case SET_DISABLE:
+	    DisableCommand(ac, av, &pi->conf.options, gConfList);
+	    UdpNodeUpdate(ctx->lnk);
+	    break;
 	default:
     	    assert(0);
     }
--- a/contrib/mpd/src/web.c	Tue Jul 05 12:30:56 2011 +0300
+++ b/contrib/mpd/src/web.c	Tue Jul 05 12:33:06 2011 +0300
@@ -216,8 +216,9 @@
 static void
 WebShowCSS(FILE *f)
 {
-  fprintf(f, "body {font : Arial, Helvetica, sans-serif; background-color: #EEEEEE; }\n");
+  fprintf(f, "body {font-family: Arial, Helvetica, Sans-Serif; background-color: #EEEEEE; }\n");
   fprintf(f, "table {background-color: #FFFFFF; }\n");
+  fprintf(f, "th, td {padding: 0 2pt 0 2pt; }\n");
   fprintf(f, "th {background-color: #00B000; }\n");
   fprintf(f, "td {background-color: #EEEEEE; }\n");
   fprintf(f, "td.r {background-color: #EECCCC; }\n");
@@ -254,9 +255,9 @@
 	        L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, FsmStateName(L->lcp.fsm.state));
 	    fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20auth\">%s</a></TD>\n", 
 	        L->tmpl?"d":FSM_COLOR(L->lcp.fsm.state), L->name, L->lcp.auth.params.authname);
-	    fprintf(f, "<TD class=\"L=%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
+	    fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
 	        L->tmpl?"d":PHYS_COLOR(L->state), L->name, L->type?L->type->name:"");
-	    fprintf(f, "<TD class=\"L=%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
+	    fprintf(f, "<TD class=\"%s\"><A href=\"/cmd?link%%20%s&amp;show%%20device\">%s</a></TD>\n", 
 	        L->tmpl?"d":PHYS_COLOR(L->state), L->name, gPhysStateNames[L->state]);
 	    if (L->state != PHYS_STATE_DOWN) {
 		PhysGetPeerAddr(L, buf, sizeof(buf));
@@ -276,7 +277,7 @@
 	    }
 	    if (priv) {
 		if (!L->tmpl) {
-		    fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</a><A href=\"/cmd?link%%20%s&amp;close\">[Close]</a></TD>\n", 
+		    fprintf(f, "<TD><A href=\"/cmd?link%%20%s&amp;open\">[Open]</a>&nbsp;<A href=\"/cmd?link%%20%s&amp;close\">[Close]</a></TD>\n", 
 	    		L->name, L->name);
 		} else {
 		    fprintf(f, "<TD></TD>\n");
--- a/target/usr.sbin/mpd/Makefile	Tue Jul 05 12:30:56 2011 +0300
+++ b/target/usr.sbin/mpd/Makefile	Tue Jul 05 12:33:06 2011 +0300
@@ -5,7 +5,7 @@
 MPDDIR=${.CURDIR}/../../../contrib/mpd
 .PATH: ${MPDDIR}/src/
 
-CFLAGS+=	-I${MPDDIR}
+CFLAGS+=	-I${MPDDIR} -I${.CURDIR}
 
 PROG=		mpd
 NO_MAN=		mpd.8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/target/usr.sbin/mpd/config.h	Tue Jul 05 12:33:06 2011 +0300
@@ -0,0 +1,11 @@
+/* System features detected by configure */
+#define	HAVE_NG_BPF	1
+#define	HAVE_NG_CAR	1
+#define	HAVE_NG_DEFLATE	1
+#define	HAVE_NG_MPPC	1
+#define	HAVE_NG_NAT	1
+#define	HAVE_NG_NETFLOW	1
+#define	HAVE_NG_PRED1	1
+#define	HAVE_NG_TCPMSS	1
+#define	HAVE_NG_VJC	1
+#define	HAVE_IPFW	1