Solve the ``first connection'' problem that occurs on
demand-dial links with dynamic IP numbers where the program that causes the dial bind()s to an interface address that is subsequently changed after ppp negotiation. The problem is defeated by adding negotiated addresses to the tun interface as additional alias addresses and providing a set of ``iface'' commands for managing the interface. Libalias is also required (and what a name clash!) - it happily IP-aliases the address so that the source is that of the primary (negotiated) interface and un-IP-aliases it on the way back. An ``enable iface-alias'' is done implicitly by the -alias command line switch. If -alias isn't given, iface-aliasing is disabled by default and can't be enabled 'till an ``alias enable yes'' is done. ``alias enable no'' silently disables iface-alias. So, for dynamic-IP-type-connections, running ``ppp -alias -auto blah'' will work for the first connection, although existing bindings will not survive a disconnect/connect as the TCP peer will be trying to send to the old IP address - the packets won't route. It's now a lot easier to add IPXCP to ppp with minor updates to the new iface.[ch] (if anyone ever gets 'round to it). It's also now possible to manually add interface aliases with something like ``iface add 1.2.3.4/24 5.6.7.8''. This allows multi-homed ppp links :-)
This commit is contained in:
parent
0b10ba9822
commit
8fa6ebe47d
@ -1,8 +1,8 @@
|
||||
# $Id: Makefile,v 1.47 1998/08/31 12:14:31 brian Exp $
|
||||
# $Id: Makefile,v 1.49 1998/10/20 00:19:38 brian Exp $
|
||||
|
||||
PROG= ppp
|
||||
SRCS= arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chat.c command.c \
|
||||
datalink.c deflate.c defs.c filter.c fsm.c hdlc.c id.c ip.c \
|
||||
datalink.c deflate.c defs.c filter.c fsm.c hdlc.c id.c iface.c ip.c \
|
||||
ipcp.c iplist.c lcp.c link.c log.c lqr.c main.c mbuf.c modem.c \
|
||||
mp.c pap.c physical.c pred.c probe.c prompt.c route.c server.c \
|
||||
sig.c slcompress.c systems.c throughput.c timer.c tun.c vjcomp.c
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: bundle.c,v 1.34 1998/08/26 17:39:36 brian Exp $
|
||||
* $Id: bundle.c,v 1.35 1998/09/17 00:45:25 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -89,6 +89,7 @@
|
||||
#include "cbcp.h"
|
||||
#include "datalink.h"
|
||||
#include "ip.h"
|
||||
#include "iface.h"
|
||||
|
||||
#define SCATTER_SEGMENTS 4 /* version, datalink, name, physical */
|
||||
#define SOCKET_OVERHEAD 100 /* additional buffer space for large */
|
||||
@ -148,49 +149,6 @@ bundle_NewPhase(struct bundle *bundle, u_int new)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bundle_CleanInterface(const struct bundle *bundle)
|
||||
{
|
||||
int s;
|
||||
struct ifreq ifrq;
|
||||
struct ifaliasreq ifra;
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
log_Printf(LogERROR, "bundle_CleanInterface: socket(): %s\n",
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
strncpy(ifrq.ifr_name, bundle->ifp.Name, sizeof ifrq.ifr_name - 1);
|
||||
ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
|
||||
while (ID0ioctl(s, SIOCGIFADDR, &ifrq) == 0) {
|
||||
memset(&ifra.ifra_mask, '\0', sizeof ifra.ifra_mask);
|
||||
strncpy(ifra.ifra_name, bundle->ifp.Name, sizeof ifra.ifra_name - 1);
|
||||
ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
|
||||
ifra.ifra_addr = ifrq.ifr_addr;
|
||||
if (ID0ioctl(s, SIOCGIFDSTADDR, &ifrq) < 0) {
|
||||
if (ifra.ifra_addr.sa_family == AF_INET)
|
||||
log_Printf(LogERROR, "Can't get dst for %s on %s !\n",
|
||||
inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr),
|
||||
bundle->ifp.Name);
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
ifra.ifra_broadaddr = ifrq.ifr_dstaddr;
|
||||
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
|
||||
if (ifra.ifra_addr.sa_family == AF_INET)
|
||||
log_Printf(LogERROR, "Can't delete %s address on %s !\n",
|
||||
inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr),
|
||||
bundle->ifp.Name);
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
close(s);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
bundle_LayerStart(void *v, struct fsm *fp)
|
||||
{
|
||||
@ -387,14 +345,14 @@ bundle_LayerUp(void *v, struct fsm *fp)
|
||||
if (bundle->ncp.mp.active) {
|
||||
struct datalink *dl;
|
||||
|
||||
bundle->ifp.Speed = 0;
|
||||
bundle->ifSpeed = 0;
|
||||
for (dl = bundle->links; dl; dl = dl->next)
|
||||
if (dl->state == DATALINK_OPEN)
|
||||
bundle->ifp.Speed += modem_Speed(dl->physical);
|
||||
bundle->ifSpeed += modem_Speed(dl->physical);
|
||||
tun_configure(bundle, bundle->ncp.mp.peer_mrru);
|
||||
bundle->autoload.running = 1;
|
||||
} else {
|
||||
bundle->ifp.Speed = modem_Speed(p);
|
||||
bundle->ifSpeed = modem_Speed(p);
|
||||
tun_configure(bundle, fsm2lcp(fp)->his_mru);
|
||||
}
|
||||
} else if (fp->proto == PROTO_IPCP) {
|
||||
@ -424,15 +382,15 @@ bundle_LayerDown(void *v, struct fsm *fp)
|
||||
struct datalink *dl;
|
||||
struct datalink *lost;
|
||||
|
||||
bundle->ifp.Speed = 0;
|
||||
bundle->ifSpeed = 0;
|
||||
lost = NULL;
|
||||
for (dl = bundle->links; dl; dl = dl->next)
|
||||
if (fp == &dl->physical->link.lcp.fsm)
|
||||
lost = dl;
|
||||
else if (dl->state == DATALINK_OPEN)
|
||||
bundle->ifp.Speed += modem_Speed(dl->physical);
|
||||
bundle->ifSpeed += modem_Speed(dl->physical);
|
||||
|
||||
if (bundle->ifp.Speed)
|
||||
if (bundle->ifSpeed)
|
||||
/* Don't configure down to a speed of 0 */
|
||||
tun_configure(bundle, bundle->ncp.mp.link.lcp.his_mru);
|
||||
|
||||
@ -769,10 +727,11 @@ struct bundle *
|
||||
bundle_Create(const char *prefix, int type, const char **argv)
|
||||
{
|
||||
int s, enoentcount, err;
|
||||
const char *ifname;
|
||||
struct ifreq ifrq;
|
||||
static struct bundle bundle; /* there can be only one */
|
||||
|
||||
if (bundle.ifp.Name != NULL) { /* Already allocated ! */
|
||||
if (bundle.iface != NULL) { /* Already allocated ! */
|
||||
log_Printf(LogALERT, "bundle_Create: There's only one BUNDLE !\n");
|
||||
return NULL;
|
||||
}
|
||||
@ -811,24 +770,32 @@ bundle_Create(const char *prefix, int type, const char **argv)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bundle.ifp.Name = strrchr(bundle.dev.Name, '/');
|
||||
if (bundle.ifp.Name == NULL)
|
||||
bundle.ifp.Name = bundle.dev.Name;
|
||||
ifname = strrchr(bundle.dev.Name, '/');
|
||||
if (ifname == NULL)
|
||||
ifname = bundle.dev.Name;
|
||||
else
|
||||
bundle.ifp.Name++;
|
||||
ifname++;
|
||||
|
||||
bundle.iface = iface_Create(ifname);
|
||||
if (bundle.iface == NULL) {
|
||||
close(s);
|
||||
close(bundle.dev.fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, bring up the interface.
|
||||
*/
|
||||
memset(&ifrq, '\0', sizeof ifrq);
|
||||
strncpy(ifrq.ifr_name, bundle.ifp.Name, sizeof ifrq.ifr_name - 1);
|
||||
strncpy(ifrq.ifr_name, ifname, sizeof ifrq.ifr_name - 1);
|
||||
ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
|
||||
if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
|
||||
log_Printf(LogERROR, "bundle_Create: ioctl(SIOCGIFFLAGS): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
iface_Destroy(bundle.iface);
|
||||
bundle.iface = NULL;
|
||||
close(bundle.dev.fd);
|
||||
bundle.ifp.Name = NULL;
|
||||
return NULL;
|
||||
}
|
||||
ifrq.ifr_flags |= IFF_UP;
|
||||
@ -836,22 +803,17 @@ bundle_Create(const char *prefix, int type, const char **argv)
|
||||
log_Printf(LogERROR, "bundle_Create: ioctl(SIOCSIFFLAGS): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
iface_Destroy(bundle.iface);
|
||||
bundle.iface = NULL;
|
||||
close(bundle.dev.fd);
|
||||
bundle.ifp.Name = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
||||
if ((bundle.ifp.Index = GetIfIndex(bundle.ifp.Name)) < 0) {
|
||||
log_Printf(LogERROR, "Can't find interface index.\n");
|
||||
close(bundle.dev.fd);
|
||||
bundle.ifp.Name = NULL;
|
||||
return NULL;
|
||||
}
|
||||
log_Printf(LogPHASE, "Using interface: %s\n", bundle.ifp.Name);
|
||||
log_Printf(LogPHASE, "Using interface: %s\n", ifname);
|
||||
|
||||
bundle.ifp.Speed = 0;
|
||||
bundle.ifSpeed = 0;
|
||||
|
||||
bundle.routing_seq = 0;
|
||||
bundle.phase = PHASE_DEAD;
|
||||
@ -882,8 +844,9 @@ bundle_Create(const char *prefix, int type, const char **argv)
|
||||
bundle.links = datalink_Create("deflink", &bundle, type);
|
||||
if (bundle.links == NULL) {
|
||||
log_Printf(LogALERT, "Cannot create data link: %s\n", strerror(errno));
|
||||
iface_Destroy(bundle.iface);
|
||||
bundle.iface = NULL;
|
||||
close(bundle.dev.fd);
|
||||
bundle.ifp.Name = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -917,7 +880,7 @@ bundle_Create(const char *prefix, int type, const char **argv)
|
||||
memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer);
|
||||
|
||||
/* Clean out any leftover crud */
|
||||
bundle_CleanInterface(&bundle);
|
||||
iface_Clear(bundle.iface, IFACE_CLEAR_ALL);
|
||||
|
||||
bundle_LockTun(&bundle);
|
||||
|
||||
@ -939,7 +902,7 @@ bundle_DownInterface(struct bundle *bundle)
|
||||
}
|
||||
|
||||
memset(&ifrq, '\0', sizeof ifrq);
|
||||
strncpy(ifrq.ifr_name, bundle->ifp.Name, sizeof ifrq.ifr_name - 1);
|
||||
strncpy(ifrq.ifr_name, bundle->iface->name, sizeof ifrq.ifr_name - 1);
|
||||
ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
|
||||
if (ID0ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
|
||||
log_Printf(LogERROR, "bundle_DownInterface: ioctl(SIOCGIFFLAGS): %s\n",
|
||||
@ -985,7 +948,8 @@ bundle_Destroy(struct bundle *bundle)
|
||||
/* In case we never made PHASE_NETWORK */
|
||||
bundle_Notify(bundle, EX_ERRDEAD);
|
||||
|
||||
bundle->ifp.Name = NULL;
|
||||
iface_Destroy(bundle->iface);
|
||||
bundle->iface = NULL;
|
||||
}
|
||||
|
||||
struct rtmsg {
|
||||
@ -1032,24 +996,10 @@ bundle_SetRoute(struct bundle *bundle, int cmd, struct in_addr dst,
|
||||
cp += rtdata.sin_len;
|
||||
if (cmd == RTM_ADD) {
|
||||
if (gateway.s_addr == INADDR_ANY) {
|
||||
/* Add a route through the interface */
|
||||
struct sockaddr_dl dl;
|
||||
const char *iname;
|
||||
int ilen;
|
||||
|
||||
iname = Index2Nam(bundle->ifp.Index);
|
||||
ilen = strlen(iname);
|
||||
dl.sdl_len = sizeof dl - sizeof dl.sdl_data + ilen;
|
||||
dl.sdl_family = AF_LINK;
|
||||
dl.sdl_index = bundle->ifp.Index;
|
||||
dl.sdl_type = 0;
|
||||
dl.sdl_nlen = ilen;
|
||||
dl.sdl_alen = 0;
|
||||
dl.sdl_slen = 0;
|
||||
strncpy(dl.sdl_data, iname, sizeof dl.sdl_data);
|
||||
memcpy(cp, &dl, dl.sdl_len);
|
||||
cp += dl.sdl_len;
|
||||
rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
|
||||
log_Printf(LogERROR, "bundle_SetRoute: Cannot add a route with"
|
||||
" destination 0.0.0.0\n");
|
||||
close(s);
|
||||
return result;
|
||||
} else {
|
||||
rtdata.sin_addr = gateway;
|
||||
memcpy(cp, &rtdata, rtdata.sin_len);
|
||||
@ -1241,7 +1191,7 @@ bundle_ShowStatus(struct cmdargs const *arg)
|
||||
prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle));
|
||||
prompt_Printf(arg->prompt, " Device: %s\n", arg->bundle->dev.Name);
|
||||
prompt_Printf(arg->prompt, " Interface: %s @ %lubps\n",
|
||||
arg->bundle->ifp.Name, arg->bundle->ifp.Speed);
|
||||
arg->bundle->iface->name, arg->bundle->ifSpeed);
|
||||
|
||||
prompt_Printf(arg->prompt, "\nDefaults:\n");
|
||||
prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label);
|
||||
@ -1294,6 +1244,8 @@ bundle_ShowStatus(struct cmdargs const *arg)
|
||||
optval(arg->bundle, OPT_THROUGHPUT));
|
||||
prompt_Printf(arg->prompt, " Utmp Logging: %s\n",
|
||||
optval(arg->bundle, OPT_UTMP));
|
||||
prompt_Printf(arg->prompt, " Iface-Alias: %s\n",
|
||||
optval(arg->bundle, OPT_IFACEALIAS));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1636,11 +1588,6 @@ bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
|
||||
/* Regenerate phys_type and adjust autoload & idle timers */
|
||||
bundle_LinksRemoved(bundle);
|
||||
|
||||
if (omode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) &&
|
||||
bundle->phase != PHASE_NETWORK)
|
||||
/* No auto links left */
|
||||
ipcp_CleanInterface(&bundle->ncp.ipcp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: bundle.h,v 1.12 1998/08/07 18:42:47 brian Exp $
|
||||
* $Id: bundle.h,v 1.13 1998/08/25 17:48:42 brian Exp $
|
||||
*/
|
||||
|
||||
#define PHASE_DEAD 0 /* Link is dead */
|
||||
@ -40,6 +40,7 @@
|
||||
#define OPT_SROUTES 0x10
|
||||
#define OPT_THROUGHPUT 0x20
|
||||
#define OPT_UTMP 0x40
|
||||
#define OPT_IFACEALIAS 0x80
|
||||
|
||||
#define MAX_ENDDISC_CLASS 5
|
||||
|
||||
@ -51,6 +52,7 @@ struct physical;
|
||||
struct link;
|
||||
struct server;
|
||||
struct prompt;
|
||||
struct iface;
|
||||
|
||||
struct bundle {
|
||||
struct descriptor desc; /* really all our datalinks */
|
||||
@ -62,11 +64,15 @@ struct bundle {
|
||||
int fd; /* The /dev/XXXX descriptor */
|
||||
} dev;
|
||||
|
||||
#if 0
|
||||
struct {
|
||||
u_long Speed; /* struct tuninfo speed */
|
||||
int Index; /* The interface index */
|
||||
char *Name; /* The interface name */
|
||||
} ifp;
|
||||
#endif
|
||||
|
||||
u_long ifSpeed; /* struct tuninfo speed */
|
||||
struct iface *iface; /* Interface information */
|
||||
|
||||
int routing_seq; /* The current routing sequence number */
|
||||
u_int phase; /* Curent phase */
|
||||
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: command.c,v 1.166 1998/09/17 00:45:26 brian Exp $
|
||||
* $Id: command.c,v 1.167 1998/10/17 12:28:05 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
@ -83,6 +83,7 @@
|
||||
#include "chap.h"
|
||||
#include "cbcp.h"
|
||||
#include "datalink.h"
|
||||
#include "iface.h"
|
||||
|
||||
/* ``set'' values */
|
||||
#define VAR_AUTHKEY 0
|
||||
@ -131,7 +132,7 @@
|
||||
#define NEG_DNS 50
|
||||
|
||||
const char Version[] = "2.0";
|
||||
const char VersionDate[] = "$Date: 1998/09/17 00:45:26 $";
|
||||
const char VersionDate[] = "$Date: 1998/10/17 12:28:05 $";
|
||||
|
||||
static int ShowCommand(struct cmdargs const *);
|
||||
static int TerminalCommand(struct cmdargs const *);
|
||||
@ -139,15 +140,17 @@ static int QuitCommand(struct cmdargs const *);
|
||||
static int OpenCommand(struct cmdargs const *);
|
||||
static int CloseCommand(struct cmdargs const *);
|
||||
static int DownCommand(struct cmdargs const *);
|
||||
static int AllowCommand(struct cmdargs const *);
|
||||
static int SetCommand(struct cmdargs const *);
|
||||
static int LinkCommand(struct cmdargs const *);
|
||||
static int AddCommand(struct cmdargs const *);
|
||||
static int DeleteCommand(struct cmdargs const *);
|
||||
static int NegotiateCommand(struct cmdargs const *);
|
||||
static int ClearCommand(struct cmdargs const *);
|
||||
static int RunListCommand(struct cmdargs const *);
|
||||
static int IfaceAddCommand(struct cmdargs const *);
|
||||
static int IfaceDeleteCommand(struct cmdargs const *);
|
||||
static int IfaceClearCommand(struct cmdargs const *);
|
||||
#ifndef NOALIAS
|
||||
static int AliasCommand(struct cmdargs const *);
|
||||
static int AliasEnable(struct cmdargs const *);
|
||||
static int AliasOption(struct cmdargs const *);
|
||||
#endif
|
||||
@ -386,7 +389,7 @@ expand(char **nargv, int argc, char const *const *oargv, struct bundle *bundle)
|
||||
nargv[arg] = subst(nargv[arg], "HISADDR",
|
||||
inet_ntoa(bundle->ncp.ipcp.peer_ip));
|
||||
nargv[arg] = subst(nargv[arg], "AUTHNAME", bundle->cfg.auth.name);
|
||||
nargv[arg] = subst(nargv[arg], "INTERFACE", bundle->ifp.Name);
|
||||
nargv[arg] = subst(nargv[arg], "INTERFACE", bundle->iface->name);
|
||||
nargv[arg] = subst(nargv[arg], "MYADDR", inet_ntoa(bundle->ncp.ipcp.my_ip));
|
||||
nargv[arg] = subst(nargv[arg], "USER", bundle->ncp.mp.peer.authname);
|
||||
nargv[arg] = subst(nargv[arg], "PEER_ENDDISC",
|
||||
@ -513,6 +516,69 @@ FgShellCommand(struct cmdargs const *arg)
|
||||
return ShellCommand(arg, 0);
|
||||
}
|
||||
|
||||
#ifndef NOALIAS
|
||||
static struct cmdtab const AliasCommands[] =
|
||||
{
|
||||
{"addr", NULL, alias_RedirectAddr, LOCAL_AUTH,
|
||||
"static address translation", "alias addr [addr_local addr_alias]"},
|
||||
{"deny_incoming", NULL, AliasOption, LOCAL_AUTH,
|
||||
"stop incoming connections", "alias deny_incoming [yes|no]",
|
||||
(const void *) PKT_ALIAS_DENY_INCOMING},
|
||||
{"enable", NULL, AliasEnable, LOCAL_AUTH,
|
||||
"enable IP aliasing", "alias enable [yes|no]"},
|
||||
{"log", NULL, AliasOption, LOCAL_AUTH,
|
||||
"log aliasing link creation", "alias log [yes|no]",
|
||||
(const void *) PKT_ALIAS_LOG},
|
||||
{"port", NULL, alias_RedirectPort, LOCAL_AUTH,
|
||||
"port redirection", "alias port [proto addr_local:port_local port_alias]"},
|
||||
{"same_ports", NULL, AliasOption, LOCAL_AUTH,
|
||||
"try to leave port numbers unchanged", "alias same_ports [yes|no]",
|
||||
(const void *) PKT_ALIAS_SAME_PORTS},
|
||||
{"unregistered_only", NULL, AliasOption, LOCAL_AUTH,
|
||||
"alias unregistered (private) IP address space only",
|
||||
"alias unregistered_only [yes|no]",
|
||||
(const void *) PKT_ALIAS_UNREGISTERED_ONLY},
|
||||
{"use_sockets", NULL, AliasOption, LOCAL_AUTH,
|
||||
"allocate host sockets", "alias use_sockets [yes|no]",
|
||||
(const void *) PKT_ALIAS_USE_SOCKETS},
|
||||
{"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
|
||||
"Display this message", "alias help|? [command]", AliasCommands},
|
||||
{NULL, NULL, NULL},
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct cmdtab const AllowCommands[] = {
|
||||
{"modes", "mode", AllowModes, LOCAL_AUTH,
|
||||
"Only allow certain ppp modes", "allow modes mode..."},
|
||||
{"users", "user", AllowUsers, LOCAL_AUTH,
|
||||
"Only allow ppp access to certain users", "allow users logname..."},
|
||||
{"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
|
||||
"Display this message", "allow help|? [command]", AllowCommands},
|
||||
{NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
static struct cmdtab const IfaceCommands[] =
|
||||
{
|
||||
{"add", NULL, IfaceAddCommand, LOCAL_AUTH,
|
||||
"Add iface address", "iface add addr[/bits| mask] peer", NULL},
|
||||
{NULL, "add!", IfaceAddCommand, LOCAL_AUTH,
|
||||
"Add or change an iface address", "iface add! addr[/bits| mask] peer",
|
||||
(void *)1},
|
||||
{"clear", NULL, IfaceClearCommand, LOCAL_AUTH,
|
||||
"Clear iface address(es)", "iface clear"},
|
||||
{"delete", "rm", IfaceDeleteCommand, LOCAL_AUTH,
|
||||
"Delete iface address", "iface delete addr", NULL},
|
||||
{NULL, "rm!", IfaceDeleteCommand, LOCAL_AUTH,
|
||||
"Delete iface address", "iface delete addr", (void *)1},
|
||||
{NULL, "delete!", IfaceDeleteCommand, LOCAL_AUTH,
|
||||
"Delete iface address", "iface delete addr", (void *)1},
|
||||
{"show", NULL, iface_Show, LOCAL_AUTH,
|
||||
"Show iface address(es)", "iface show"},
|
||||
{"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
|
||||
"Display this message", "alias help|? [command]", IfaceCommands},
|
||||
{NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
static struct cmdtab const Commands[] = {
|
||||
{"accept", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
"accept option request", "accept option .."},
|
||||
@ -521,11 +587,11 @@ static struct cmdtab const Commands[] = {
|
||||
{NULL, "add!", AddCommand, LOCAL_AUTH,
|
||||
"add or change route", "add! dest mask gateway", (void *)1},
|
||||
#ifndef NOALIAS
|
||||
{"alias", NULL, AliasCommand, LOCAL_AUTH,
|
||||
"alias control", "alias option [yes|no]"},
|
||||
{"alias", NULL, RunListCommand, LOCAL_AUTH,
|
||||
"alias control", "alias option [yes|no]", AliasCommands},
|
||||
#endif
|
||||
{"allow", "auth", AllowCommand, LOCAL_AUTH,
|
||||
"Allow ppp access", "allow users|modes ...."},
|
||||
{"allow", "auth", RunListCommand, LOCAL_AUTH,
|
||||
"Allow ppp access", "allow users|modes ....", AllowCommands},
|
||||
{"bg", "!bg", BgShellCommand, LOCAL_AUTH,
|
||||
"Run a background command", "[!]bg command"},
|
||||
{"clear", NULL, ClearCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
@ -548,6 +614,8 @@ static struct cmdtab const Commands[] = {
|
||||
"Generate a down event", "down"},
|
||||
{"enable", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
"Enable option", "enable option .."},
|
||||
{"iface", "interface", RunListCommand, LOCAL_AUTH,
|
||||
"interface control", "iface option ...", IfaceCommands},
|
||||
{"link", "datalink", LinkCommand, LOCAL_AUTH,
|
||||
"Link specific commands", "link name command ..."},
|
||||
{"load", NULL, LoadCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
@ -655,6 +723,8 @@ static struct cmdtab const ShowCommands[] = {
|
||||
"packet filters", "show filter [in|out|dial|alive]"},
|
||||
{"hdlc", NULL, hdlc_ReportStatus, LOCAL_AUTH | LOCAL_CX,
|
||||
"HDLC errors", "show hdlc"},
|
||||
{"iface", "interface", iface_Show, LOCAL_AUTH,
|
||||
"Interface status", "show iface"},
|
||||
{"ipcp", NULL, ipcp_Show, LOCAL_AUTH,
|
||||
"IPCP status", "show ipcp"},
|
||||
{"lcp", NULL, lcp_ReportStatus, LOCAL_AUTH | LOCAL_CX,
|
||||
@ -1200,13 +1270,12 @@ SetInterfaceAddr(struct cmdargs const *arg)
|
||||
struct ipcp *ipcp = &arg->bundle->ncp.ipcp;
|
||||
const char *hisaddr;
|
||||
|
||||
hisaddr = NULL;
|
||||
ipcp->cfg.my_range.ipaddr.s_addr = INADDR_ANY;
|
||||
ipcp->cfg.peer_range.ipaddr.s_addr = INADDR_ANY;
|
||||
|
||||
if (arg->argc > arg->argn + 4)
|
||||
return -1;
|
||||
|
||||
hisaddr = NULL;
|
||||
ipcp->cfg.my_range.ipaddr.s_addr = INADDR_ANY;
|
||||
ipcp->cfg.peer_range.ipaddr.s_addr = INADDR_ANY;
|
||||
ipcp->cfg.HaveTriggerAddress = 0;
|
||||
ipcp->cfg.netmask.s_addr = INADDR_ANY;
|
||||
iplist_reset(&ipcp->cfg.peer_list);
|
||||
@ -1228,20 +1297,13 @@ SetInterfaceAddr(struct cmdargs const *arg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For backwards compatibility, 0.0.0.0 means any address.
|
||||
*/
|
||||
/* 0.0.0.0 means any address (0 bits) */
|
||||
if (ipcp->cfg.my_range.ipaddr.s_addr == INADDR_ANY) {
|
||||
ipcp->cfg.my_range.mask.s_addr = INADDR_ANY;
|
||||
ipcp->cfg.my_range.width = 0;
|
||||
}
|
||||
ipcp->my_ip.s_addr = ipcp->cfg.my_range.ipaddr.s_addr;
|
||||
|
||||
if (ipcp->cfg.peer_range.ipaddr.s_addr == INADDR_ANY) {
|
||||
ipcp->cfg.peer_range.mask.s_addr = INADDR_ANY;
|
||||
ipcp->cfg.peer_range.width = 0;
|
||||
}
|
||||
|
||||
if (hisaddr && !ipcp_UseHisaddr(arg->bundle, hisaddr,
|
||||
arg->bundle->phys_type.all & PHYS_AUTO))
|
||||
return 4;
|
||||
@ -1717,7 +1779,6 @@ SetCommand(struct cmdargs const *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
AddCommand(struct cmdargs const *arg)
|
||||
{
|
||||
@ -1759,9 +1820,7 @@ AddCommand(struct cmdargs const *arg)
|
||||
if (strcasecmp(arg->argv[arg->argn+gw], "HISADDR") == 0) {
|
||||
gateway = arg->bundle->ncp.ipcp.peer_ip;
|
||||
addrs |= ROUTE_GWHISADDR;
|
||||
} else if (strcasecmp(arg->argv[arg->argn+gw], "INTERFACE") == 0)
|
||||
gateway.s_addr = INADDR_ANY;
|
||||
else
|
||||
} else
|
||||
gateway = GetIpAddr(arg->argv[arg->argn+gw]);
|
||||
|
||||
if (bundle_SetRoute(arg->bundle, RTM_ADD, dest, gateway, netmask,
|
||||
@ -1808,51 +1867,6 @@ DeleteCommand(struct cmdargs const *arg)
|
||||
}
|
||||
|
||||
#ifndef NOALIAS
|
||||
static struct cmdtab const AliasCommands[] =
|
||||
{
|
||||
{"addr", NULL, alias_RedirectAddr, LOCAL_AUTH,
|
||||
"static address translation", "alias addr [addr_local addr_alias]"},
|
||||
{"deny_incoming", NULL, AliasOption, LOCAL_AUTH,
|
||||
"stop incoming connections", "alias deny_incoming [yes|no]",
|
||||
(const void *) PKT_ALIAS_DENY_INCOMING},
|
||||
{"enable", NULL, AliasEnable, LOCAL_AUTH,
|
||||
"enable IP aliasing", "alias enable [yes|no]"},
|
||||
{"log", NULL, AliasOption, LOCAL_AUTH,
|
||||
"log aliasing link creation", "alias log [yes|no]",
|
||||
(const void *) PKT_ALIAS_LOG},
|
||||
{"port", NULL, alias_RedirectPort, LOCAL_AUTH,
|
||||
"port redirection", "alias port [proto addr_local:port_local port_alias]"},
|
||||
{"same_ports", NULL, AliasOption, LOCAL_AUTH,
|
||||
"try to leave port numbers unchanged", "alias same_ports [yes|no]",
|
||||
(const void *) PKT_ALIAS_SAME_PORTS},
|
||||
{"unregistered_only", NULL, AliasOption, LOCAL_AUTH,
|
||||
"alias unregistered (private) IP address space only",
|
||||
"alias unregistered_only [yes|no]",
|
||||
(const void *) PKT_ALIAS_UNREGISTERED_ONLY},
|
||||
{"use_sockets", NULL, AliasOption, LOCAL_AUTH,
|
||||
"allocate host sockets", "alias use_sockets [yes|no]",
|
||||
(const void *) PKT_ALIAS_USE_SOCKETS},
|
||||
{"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
|
||||
"Display this message", "alias help|? [command]", AliasCommands},
|
||||
{NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
AliasCommand(struct cmdargs const *arg)
|
||||
{
|
||||
if (arg->argc > arg->argn)
|
||||
FindExec(arg->bundle, AliasCommands, arg->argc, arg->argn, arg->argv,
|
||||
arg->prompt, arg->cx);
|
||||
else if (arg->prompt)
|
||||
prompt_Printf(arg->prompt, "Use `alias help' to get a list or `alias help"
|
||||
" <option>' for syntax help.\n");
|
||||
else
|
||||
log_Printf(LogWARN, "alias command must have arguments\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
AliasEnable(struct cmdargs const *arg)
|
||||
{
|
||||
@ -1862,6 +1876,8 @@ AliasEnable(struct cmdargs const *arg)
|
||||
return 0;
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "no") == 0) {
|
||||
arg->bundle->AliasEnabled = 0;
|
||||
arg->bundle->cfg.opt &= ~OPT_IFACEALIAS;
|
||||
/* Don't iface_Clear() - there may be manually configured addresses */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1894,32 +1910,6 @@ AliasOption(struct cmdargs const *arg)
|
||||
}
|
||||
#endif /* #ifndef NOALIAS */
|
||||
|
||||
static struct cmdtab const AllowCommands[] = {
|
||||
{"modes", "mode", AllowModes, LOCAL_AUTH,
|
||||
"Only allow certain ppp modes", "allow modes mode..."},
|
||||
{"users", "user", AllowUsers, LOCAL_AUTH,
|
||||
"Allow users access to ppp", "allow users logname..."},
|
||||
{"help", "?", HelpCommand, LOCAL_AUTH | LOCAL_NO_AUTH,
|
||||
"Display this message", "allow help|? [command]", AllowCommands},
|
||||
{NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
static int
|
||||
AllowCommand(struct cmdargs const *arg)
|
||||
{
|
||||
/* arg->bundle may be NULL (see system_IsValid()) ! */
|
||||
if (arg->argc > arg->argn)
|
||||
FindExec(arg->bundle, AllowCommands, arg->argc, arg->argn, arg->argv,
|
||||
arg->prompt, arg->cx);
|
||||
else if (arg->prompt)
|
||||
prompt_Printf(arg->prompt, "Use `allow ?' to get a list or `allow ? <cmd>'"
|
||||
" for syntax help.\n");
|
||||
else
|
||||
log_Printf(LogWARN, "allow command must have arguments\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
LinkCommand(struct cmdargs const *arg)
|
||||
{
|
||||
@ -2046,6 +2036,22 @@ OptSet(struct cmdargs const *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
IfaceAliasOptSet(struct cmdargs const *arg)
|
||||
{
|
||||
unsigned save = arg->bundle->cfg.opt;
|
||||
int result = OptSet(arg);
|
||||
|
||||
if (result == 0)
|
||||
if (Enabled(arg->bundle, OPT_IFACEALIAS) && !arg->bundle->AliasEnabled) {
|
||||
arg->bundle->cfg.opt = save;
|
||||
log_Printf(LogWARN, "Cannot enable iface-alias without IP aliasing\n");
|
||||
result = 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
NegotiateSet(struct cmdargs const *arg)
|
||||
{
|
||||
@ -2138,8 +2144,11 @@ static struct cmdtab const NegotiateCommands[] = {
|
||||
"disable|enable", (const void *)OPT_THROUGHPUT},
|
||||
{"utmp", NULL, OptSet, LOCAL_AUTH, "Log connections in utmp",
|
||||
"disable|enable", (const void *)OPT_UTMP},
|
||||
{"iface-alias", NULL, IfaceAliasOptSet, LOCAL_AUTH,
|
||||
"maintain interface addresses", "disable|enable",
|
||||
(const void *)OPT_IFACEALIAS},
|
||||
|
||||
#define OPT_MAX 7 /* accept/deny allowed below and not above */
|
||||
#define OPT_MAX 8 /* accept/deny allowed below and not above */
|
||||
|
||||
{"acfcomp", NULL, NegotiateSet, LOCAL_AUTH | LOCAL_CX,
|
||||
"Address & Control field compression", "accept|deny|disable|enable",
|
||||
@ -2258,3 +2267,96 @@ ClearCommand(struct cmdargs const *arg)
|
||||
throughput_clear(t, clear_type, arg->prompt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
RunListCommand(struct cmdargs const *arg)
|
||||
{
|
||||
const char *cmd = arg->argc ? arg->argv[arg->argc - 1] : "???";
|
||||
|
||||
if (arg->argc > arg->argn)
|
||||
FindExec(arg->bundle, arg->cmd->args, arg->argc, arg->argn, arg->argv,
|
||||
arg->prompt, arg->cx);
|
||||
else if (arg->prompt)
|
||||
prompt_Printf(arg->prompt, "Use `%s help' to get a list or `%s help"
|
||||
" <option>' for syntax help.\n", cmd, cmd);
|
||||
else
|
||||
log_Printf(LogWARN, "%s command must have arguments\n", cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
IfaceAddCommand(struct cmdargs const *arg)
|
||||
{
|
||||
int bits, n, how;
|
||||
struct in_addr ifa, mask, brd;
|
||||
|
||||
if (arg->argc == arg->argn + 2) {
|
||||
if (!ParseAddr(NULL, 1, arg->argv + arg->argn, &ifa, &mask, &bits))
|
||||
return -1;
|
||||
n = 1;
|
||||
} else if (arg->argc == arg->argn + 3) {
|
||||
if (!ParseAddr(NULL, 1, arg->argv + arg->argn, &ifa, NULL, NULL))
|
||||
return -1;
|
||||
if (!ParseAddr(NULL, 1, arg->argv + arg->argn + 1, &mask, NULL, NULL))
|
||||
return -1;
|
||||
n = 2;
|
||||
} else
|
||||
return -1;
|
||||
|
||||
if (!ParseAddr(NULL, 1, arg->argv + arg->argn + n, &brd, NULL, NULL))
|
||||
return -1;
|
||||
|
||||
how = IFACE_ADD_LAST;
|
||||
if (arg->cmd->args)
|
||||
how |= IFACE_FORCE_ADD;
|
||||
|
||||
return !iface_inAdd(arg->bundle->iface, ifa, mask, brd, how);
|
||||
}
|
||||
|
||||
static int
|
||||
IfaceDeleteCommand(struct cmdargs const *arg)
|
||||
{
|
||||
struct in_addr ifa;
|
||||
int ok;
|
||||
|
||||
if (arg->argc != arg->argn + 1)
|
||||
return -1;
|
||||
|
||||
if (!ParseAddr(NULL, 1, arg->argv + arg->argn, &ifa, NULL, NULL))
|
||||
return -1;
|
||||
|
||||
if (arg->bundle->ncp.ipcp.fsm.state == ST_OPENED &&
|
||||
arg->bundle->ncp.ipcp.my_ip.s_addr == ifa.s_addr) {
|
||||
log_Printf(LogWARN, "%s: Cannot remove active interface address\n",
|
||||
inet_ntoa(ifa));
|
||||
return 1;
|
||||
}
|
||||
|
||||
ok = iface_inDelete(arg->bundle->iface, ifa);
|
||||
if (!ok) {
|
||||
if (arg->cmd->args)
|
||||
ok = 1;
|
||||
else if (arg->prompt)
|
||||
prompt_Printf(arg->prompt, "%s: No such address\n", inet_ntoa(ifa));
|
||||
else
|
||||
log_Printf(LogWARN, "%s: No such address\n", inet_ntoa(ifa));
|
||||
}
|
||||
|
||||
return !ok;
|
||||
}
|
||||
|
||||
static int
|
||||
IfaceClearCommand(struct cmdargs const *arg)
|
||||
{
|
||||
int how;
|
||||
|
||||
if (arg->argc != arg->argn)
|
||||
return -1;
|
||||
|
||||
how = arg->bundle->ncp.ipcp.fsm.state == ST_OPENED ?
|
||||
IFACE_CLEAR_ALIASES : IFACE_CLEAR_ALL;
|
||||
iface_Clear(arg->bundle->iface, how);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: filter.c,v 1.24 1998/06/15 19:06:07 brian Exp $
|
||||
* $Id: filter.c,v 1.25 1998/06/27 12:03:48 brian Exp $
|
||||
*
|
||||
* TODO: Shoud send ICMP error message when we discard packets.
|
||||
*/
|
||||
@ -90,9 +90,9 @@ ParseAddr(struct ipcp *ipcp, int argc, char const *const *argv,
|
||||
cp = pmask || pwidth ? strchr(*argv, '/') : NULL;
|
||||
len = cp ? cp - *argv : strlen(*argv);
|
||||
|
||||
if (strncasecmp(*argv, "HISADDR", len) == 0)
|
||||
if (ipcp && strncasecmp(*argv, "HISADDR", len) == 0)
|
||||
*paddr = ipcp->peer_ip;
|
||||
else if (strncasecmp(*argv, "MYADDR", len) == 0)
|
||||
else if (ipcp && strncasecmp(*argv, "MYADDR", len) == 0)
|
||||
*paddr = ipcp->my_ip;
|
||||
else if (len > 15)
|
||||
log_Printf(LogWARN, "ParseAddr: %s: Bad address\n", *argv);
|
||||
@ -121,8 +121,12 @@ ParseAddr(struct ipcp *ipcp, int argc, char const *const *argv,
|
||||
if (pwidth)
|
||||
*pwidth = bits;
|
||||
|
||||
if (pmask)
|
||||
pmask->s_addr = htonl(netmasks[bits]);
|
||||
if (pmask) {
|
||||
if (paddr->s_addr == INADDR_ANY)
|
||||
pmask->s_addr = INADDR_ANY;
|
||||
else
|
||||
pmask->s_addr = htonl(netmasks[bits]);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
431
usr.sbin/ppp/iface.c
Normal file
431
usr.sbin/ppp/iface.c
Normal file
@ -0,0 +1,431 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "id.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "iplist.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "slcompress.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "ipcp.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "prompt.h"
|
||||
#include "iface.h"
|
||||
|
||||
|
||||
static int
|
||||
bitsinmask(struct in_addr mask)
|
||||
{
|
||||
u_int32_t bitmask, maskaddr;
|
||||
int bits;
|
||||
|
||||
bitmask = 0xffffffff;
|
||||
maskaddr = ntohl(mask.s_addr);
|
||||
for (bits = 32; bits >= 0; bits--) {
|
||||
if (maskaddr == bitmask)
|
||||
break;
|
||||
bitmask &= ~(1 << (32 - bits));
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
struct iface *
|
||||
iface_Create(const char *name)
|
||||
{
|
||||
int mib[6], i, s;
|
||||
size_t needed;
|
||||
char *buf, *ptr, *end, *cp, *lim;
|
||||
struct if_msghdr *ifm;
|
||||
struct ifa_msghdr *ifam;
|
||||
struct sockaddr_dl *dl;
|
||||
struct rt_addrinfo rti;
|
||||
struct iface *iface;
|
||||
struct iface_addr *addr;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
fprintf(stderr, "iface_Create: socket(): %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = 0;
|
||||
mib[4] = NET_RT_IFLIST;
|
||||
mib[5] = 0;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
|
||||
fprintf(stderr, "clean: sysctl: estimate: %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((buf = (char *)malloc(needed)) == NULL) {
|
||||
close(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
|
||||
free(buf);
|
||||
close(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = buf;
|
||||
end = buf + needed;
|
||||
iface = NULL;
|
||||
|
||||
while (ptr < end && iface == NULL) {
|
||||
ifm = (struct if_msghdr *)ptr; /* On if_msghdr */
|
||||
if (ifm->ifm_type != RTM_IFINFO)
|
||||
break;
|
||||
dl = (struct sockaddr_dl *)(ifm + 1); /* Single _dl at end */
|
||||
if (!strncmp(name, dl->sdl_data, dl->sdl_nlen)) {
|
||||
iface = (struct iface *)malloc(sizeof *iface);
|
||||
if (iface == NULL) {
|
||||
fprintf(stderr, "iface_Create: malloc: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
iface->name = strdup(name);
|
||||
iface->flags = ifm->ifm_flags;
|
||||
iface->index = ifm->ifm_index;
|
||||
iface->in_addrs = 0;
|
||||
iface->in_addr = NULL;
|
||||
}
|
||||
ptr += ifm->ifm_msglen; /* First ifa_msghdr */
|
||||
for (; ptr < end; ptr += ifam->ifam_msglen) {
|
||||
ifam = (struct ifa_msghdr *)ptr; /* Next if address */
|
||||
|
||||
if (ifam->ifam_type != RTM_NEWADDR) /* finished this if */
|
||||
break;
|
||||
|
||||
if (iface == NULL) /* Keep wading */
|
||||
continue;
|
||||
|
||||
/* Found an address ! */
|
||||
|
||||
if (ifam->ifam_addrs & (1 << RTAX_IFA)) {
|
||||
/* *And* it's configured ! */
|
||||
rti.rti_addrs = ifam->ifam_addrs;
|
||||
lim = (char *)ifam + ifam->ifam_msglen;
|
||||
cp = (char *)(ifam + 1);
|
||||
memset(rti.rti_info, '\0', sizeof(rti.rti_info));
|
||||
for (i = 0; i < RTAX_MAX && cp < lim; i++) {
|
||||
if ((rti.rti_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
rti.rti_info[i] = (struct sockaddr *)cp;
|
||||
#define ROUNDUP(x) \
|
||||
((x) > 0 ? (1 + (((x) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
cp += ROUNDUP(rti.rti_info[i]->sa_len);
|
||||
}
|
||||
|
||||
if (rti.rti_info[RTAX_IFA] &&
|
||||
rti.rti_info[RTAX_IFA]->sa_family == AF_INET) {
|
||||
/* Record the iface address rti */
|
||||
|
||||
addr = (struct iface_addr *)realloc
|
||||
(iface->in_addr, (iface->in_addrs + 1) * sizeof iface->in_addr[0]);
|
||||
if (addr == NULL)
|
||||
break;
|
||||
iface->in_addr = addr;
|
||||
|
||||
addr += iface->in_addrs;
|
||||
iface->in_addrs++;
|
||||
|
||||
addr->ifa.s_addr = ((struct sockaddr_in *)rti.rti_info[RTAX_IFA])->
|
||||
sin_addr.s_addr;
|
||||
addr->brd.s_addr = rti.rti_info[RTAX_BRD] ?
|
||||
((struct sockaddr_in *)rti.rti_info[RTAX_BRD])->sin_addr.s_addr :
|
||||
INADDR_ANY;
|
||||
addr->mask.s_addr = rti.rti_info[RTAX_NETMASK] ?
|
||||
((struct sockaddr_in *)rti.rti_info[RTAX_NETMASK])->sin_addr.s_addr:
|
||||
INADDR_ANY;
|
||||
|
||||
addr->bits = bitsinmask(addr->mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
close(s);
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
static void
|
||||
iface_addr_Zap(const char *name, struct iface_addr *addr)
|
||||
{
|
||||
struct ifaliasreq ifra;
|
||||
struct sockaddr_in *me, *peer;
|
||||
int s;
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0)
|
||||
log_Printf(LogERROR, "iface_addr_Zap: socket(): %s\n", strerror(errno));
|
||||
else {
|
||||
memset(&ifra, '\0', sizeof ifra);
|
||||
strncpy(ifra.ifra_name, name, sizeof ifra.ifra_name - 1);
|
||||
me = (struct sockaddr_in *)&ifra.ifra_addr;
|
||||
peer = (struct sockaddr_in *)&ifra.ifra_broadaddr;
|
||||
me->sin_family = peer->sin_family = AF_INET;
|
||||
me->sin_len = peer->sin_len = sizeof(struct sockaddr_in);
|
||||
me->sin_addr = addr->ifa;
|
||||
peer->sin_addr = addr->brd;
|
||||
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0)
|
||||
log_Printf(LogWARN, "iface_addr_Zap: ioctl(SIOCDIFADDR, %s): %s\n",
|
||||
inet_ntoa(addr->ifa), strerror(errno));
|
||||
close(s);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iface_inClear(struct iface *iface, int how)
|
||||
{
|
||||
int n, addrs;
|
||||
|
||||
addrs = n = how == IFACE_CLEAR_ALL ? 0 : 1;
|
||||
for (; n < iface->in_addrs; n++)
|
||||
iface_addr_Zap(iface->name, iface->in_addr + n);
|
||||
|
||||
iface->in_addrs = addrs;
|
||||
/* Don't bother realloc()ing - we have little to gain */
|
||||
}
|
||||
|
||||
int
|
||||
iface_inAdd(struct iface *iface, struct in_addr ifa, struct in_addr mask,
|
||||
struct in_addr brd, int how)
|
||||
{
|
||||
int slot, s;
|
||||
struct ifaliasreq ifra;
|
||||
struct sockaddr_in *me, *peer, *msk;
|
||||
struct iface_addr *addr;
|
||||
|
||||
for (slot = 0; slot < iface->in_addrs; slot++)
|
||||
if (iface->in_addr[slot].ifa.s_addr == ifa.s_addr) {
|
||||
if (how & IFACE_FORCE_ADD)
|
||||
break;
|
||||
else
|
||||
/* errno = EEXIST; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr = (struct iface_addr *)realloc
|
||||
(iface->in_addr, (iface->in_addrs + 1) * sizeof iface->in_addr[0]);
|
||||
if (addr == NULL) {
|
||||
log_Printf(LogERROR, "iface_inAdd: realloc: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
iface->in_addr = addr;
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
log_Printf(LogERROR, "iface_inAdd: socket(): %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&ifra, '\0', sizeof ifra);
|
||||
strncpy(ifra.ifra_name, iface->name, sizeof ifra.ifra_name - 1);
|
||||
|
||||
me = (struct sockaddr_in *)&ifra.ifra_addr;
|
||||
msk = (struct sockaddr_in *)&ifra.ifra_mask;
|
||||
peer = (struct sockaddr_in *)&ifra.ifra_broadaddr;
|
||||
|
||||
me->sin_family = msk->sin_family = peer->sin_family = AF_INET;
|
||||
me->sin_len = msk->sin_len = peer->sin_len = sizeof(struct sockaddr_in);
|
||||
|
||||
me->sin_addr = ifa;
|
||||
msk->sin_addr = mask;
|
||||
peer->sin_addr = brd;
|
||||
|
||||
/*
|
||||
* Note: EEXIST is sometimes returned, despite the route actually being
|
||||
* added !
|
||||
*/
|
||||
if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0 && errno != EEXIST) {
|
||||
log_Printf(LogERROR, "iface_inAdd: ioctl(SIOCAIFADDR): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
close(s);
|
||||
|
||||
if (slot == iface->in_addrs) {
|
||||
/* We're adding a new interface address */
|
||||
|
||||
if (how & IFACE_ADD_FIRST) {
|
||||
/* Stuff it at the start of our list */
|
||||
slot = 0;
|
||||
bcopy(iface->in_addr, iface->in_addr + 1,
|
||||
iface->in_addrs * sizeof iface->in_addr[0]);
|
||||
}
|
||||
|
||||
iface->in_addrs++;
|
||||
} else if (how & IFACE_ADD_FIRST) {
|
||||
/* Shift it up to the first slot */
|
||||
bcopy(iface->in_addr, iface->in_addr + 1, slot * sizeof iface->in_addr[0]);
|
||||
slot = 0;
|
||||
}
|
||||
|
||||
iface->in_addr[slot].ifa = ifa;
|
||||
iface->in_addr[slot].mask = mask;
|
||||
iface->in_addr[slot].brd = brd;
|
||||
iface->in_addr[slot].bits = bitsinmask(iface->in_addr[slot].mask);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
iface_inDelete(struct iface *iface, struct in_addr ip)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < iface->in_addrs; n++)
|
||||
if (iface->in_addr[n].ifa.s_addr == ip.s_addr) {
|
||||
iface_addr_Zap(iface->name, iface->in_addr + n);
|
||||
bcopy(iface->in_addr + n + 1, iface->in_addr + n,
|
||||
(iface->in_addrs - n - 1) * sizeof iface->in_addr[0]);
|
||||
iface->in_addrs--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
iface_Destroy(struct iface *iface)
|
||||
{
|
||||
/*
|
||||
* iface_Clear(iface, IFACE_CLEAR_ALL) must be called manually
|
||||
* if that's what the user wants. It's better to leave the interface
|
||||
* allocated so that existing connections can continue to work.
|
||||
*/
|
||||
|
||||
if (iface != NULL) {
|
||||
free(iface->name);
|
||||
free(iface->in_addr);
|
||||
free(iface);
|
||||
}
|
||||
}
|
||||
|
||||
#define if_entry(x) { IFF_##x, #x }
|
||||
|
||||
struct {
|
||||
int flag;
|
||||
const char *value;
|
||||
} if_flags[] = {
|
||||
if_entry(UP),
|
||||
if_entry(BROADCAST),
|
||||
if_entry(DEBUG),
|
||||
if_entry(LOOPBACK),
|
||||
if_entry(POINTOPOINT),
|
||||
if_entry(RUNNING),
|
||||
if_entry(NOARP),
|
||||
if_entry(PROMISC),
|
||||
if_entry(ALLMULTI),
|
||||
if_entry(OACTIVE),
|
||||
if_entry(SIMPLEX),
|
||||
if_entry(LINK0),
|
||||
if_entry(LINK1),
|
||||
if_entry(LINK2),
|
||||
if_entry(MULTICAST),
|
||||
{ 0, "???" }
|
||||
};
|
||||
|
||||
int
|
||||
iface_Show(struct cmdargs const *arg)
|
||||
{
|
||||
struct iface *iface = arg->bundle->iface, *current;
|
||||
int f, flags;
|
||||
|
||||
current = iface_Create(iface->name);
|
||||
flags = iface->flags = current->flags;
|
||||
iface_Destroy(current);
|
||||
|
||||
prompt_Printf(arg->prompt, "%s (idx %d) <", iface->name, iface->index);
|
||||
for (f = 0; f < sizeof if_flags / sizeof if_flags[0]; f++)
|
||||
if ((if_flags[f].flag & flags) || (!if_flags[f].flag && flags)) {
|
||||
prompt_Printf(arg->prompt, "%s%s", flags == iface->flags ? "" : ",",
|
||||
if_flags[f].value);
|
||||
flags &= ~if_flags[f].flag;
|
||||
}
|
||||
prompt_Printf(arg->prompt, "> has %d address%s:\n", iface->in_addrs,
|
||||
iface->in_addrs == 1 ? "" : "es");
|
||||
|
||||
for (f = 0; f < iface->in_addrs; f++) {
|
||||
prompt_Printf(arg->prompt, " %s", inet_ntoa(iface->in_addr[f].ifa));
|
||||
if (iface->in_addr[f].bits >= 0)
|
||||
prompt_Printf(arg->prompt, "/%d", iface->in_addr[f].bits);
|
||||
if (iface->flags & IFF_POINTOPOINT)
|
||||
prompt_Printf(arg->prompt, " -> %s", inet_ntoa(iface->in_addr[f].brd));
|
||||
else if (iface->flags & IFF_BROADCAST)
|
||||
prompt_Printf(arg->prompt, " broadcast %s",
|
||||
inet_ntoa(iface->in_addr[f].brd));
|
||||
if (iface->in_addr[f].bits < 0)
|
||||
prompt_Printf(arg->prompt, " (mask %s)",
|
||||
inet_ntoa(iface->in_addr[f].mask));
|
||||
prompt_Printf(arg->prompt, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
60
usr.sbin/ppp/iface.h
Normal file
60
usr.sbin/ppp/iface.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
struct iface_addr {
|
||||
struct in_addr ifa; /* local address */
|
||||
struct in_addr mask; /* netmask */
|
||||
int bits; /* netmask bits - -1 if not contiguous */
|
||||
struct in_addr brd; /* peer address */
|
||||
};
|
||||
|
||||
struct iface {
|
||||
char *name; /* Interface name (malloc'd) */
|
||||
int index; /* Interface index */
|
||||
int flags; /* Interface flags (IFF_*) */
|
||||
|
||||
int in_addrs; /* How many in_addr's */
|
||||
struct iface_addr *in_addr; /* Array of addresses (malloc'd) */
|
||||
};
|
||||
|
||||
#define IFACE_CLEAR_ALL 0 /* Nuke 'em all */
|
||||
#define IFACE_CLEAR_ALIASES 1 /* Leave the IPCP address */
|
||||
|
||||
#define IFACE_ADD_LAST 0 /* Just another alias */
|
||||
#define IFACE_ADD_FIRST 1 /* The IPCP address */
|
||||
#define IFACE_FORCE_ADD 2 /* OR'd with IFACE_ADD_{FIRST,LAST} */
|
||||
|
||||
#define iface_Clear iface_inClear /* Same for now */
|
||||
|
||||
extern struct iface *iface_Create(const char *name);
|
||||
extern void iface_inClear(struct iface *, int);
|
||||
extern int iface_inAdd(struct iface *, struct in_addr, struct in_addr,
|
||||
struct in_addr, int);
|
||||
extern int iface_inDelete(struct iface *, struct in_addr);
|
||||
extern int iface_Show(struct cmdargs const *);
|
||||
extern void iface_Destroy(struct iface *);
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipcp.c,v 1.65 1998/09/04 18:25:59 brian Exp $
|
||||
* $Id: ipcp.c,v 1.66 1998/09/17 00:45:26 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o More RFC1772 backward compatibility
|
||||
@ -77,6 +77,7 @@
|
||||
#include "systems.h"
|
||||
#include "prompt.h"
|
||||
#include "route.h"
|
||||
#include "iface.h"
|
||||
|
||||
#undef REJECTED
|
||||
#define REJECTED(p, x) ((p)->peer_reject & (1<<(x)))
|
||||
@ -354,11 +355,8 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l,
|
||||
memset(&ipcp->cfg.my_range, '\0', sizeof ipcp->cfg.my_range);
|
||||
if (gethostname(name, sizeof name) == 0) {
|
||||
hp = gethostbyname(name);
|
||||
if (hp && hp->h_addrtype == AF_INET) {
|
||||
if (hp && hp->h_addrtype == AF_INET)
|
||||
memcpy(&ipcp->cfg.my_range.ipaddr.s_addr, hp->h_addr, hp->h_length);
|
||||
ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
|
||||
ipcp->cfg.peer_range.width = 32;
|
||||
}
|
||||
}
|
||||
ipcp->cfg.netmask.s_addr = INADDR_ANY;
|
||||
memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range);
|
||||
@ -376,9 +374,6 @@ ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l,
|
||||
|
||||
memset(&ipcp->vj, '\0', sizeof ipcp->vj);
|
||||
|
||||
ipcp->my_ifip.s_addr = INADDR_ANY;
|
||||
ipcp->peer_ifip.s_addr = INADDR_ANY;
|
||||
|
||||
throughput_init(&ipcp->throughput);
|
||||
memset(ipcp->Queue, '\0', sizeof ipcp->Queue);
|
||||
ipcp_Setup(ipcp);
|
||||
@ -393,17 +388,26 @@ ipcp_SetLink(struct ipcp *ipcp, struct link *l)
|
||||
void
|
||||
ipcp_Setup(struct ipcp *ipcp)
|
||||
{
|
||||
int pos;
|
||||
struct iface *iface = ipcp->fsm.bundle->iface;
|
||||
int pos, n;
|
||||
|
||||
ipcp->fsm.open_mode = 0;
|
||||
ipcp->fsm.maxconfig = 10;
|
||||
|
||||
if (iplist_isvalid(&ipcp->cfg.peer_list)) {
|
||||
if (ipcp->my_ifip.s_addr != INADDR_ANY &&
|
||||
(pos = iplist_ip2pos(&ipcp->cfg.peer_list, ipcp->my_ifip)) != -1)
|
||||
ipcp->cfg.peer_range.ipaddr = iplist_setcurpos(&ipcp->cfg.peer_list, pos);
|
||||
else
|
||||
/* Try to give the peer a previously configured IP address */
|
||||
for (n = 0; n < iface->in_addrs; n++) {
|
||||
pos = iplist_ip2pos(&ipcp->cfg.peer_list, iface->in_addr[n].brd);
|
||||
if (pos != -1) {
|
||||
ipcp->cfg.peer_range.ipaddr =
|
||||
iplist_setcurpos(&ipcp->cfg.peer_list, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n == iface->in_addrs)
|
||||
/* Ok, so none of 'em fit.... pick a random one */
|
||||
ipcp->cfg.peer_range.ipaddr = iplist_setrandpos(&ipcp->cfg.peer_list);
|
||||
|
||||
ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
|
||||
ipcp->cfg.peer_range.width = 32;
|
||||
}
|
||||
@ -422,17 +426,23 @@ ipcp_Setup(struct ipcp *ipcp)
|
||||
ipcp->my_ip = ipcp->cfg.TriggerAddress;
|
||||
log_Printf(LogIPCP, "Using trigger address %s\n",
|
||||
inet_ntoa(ipcp->cfg.TriggerAddress));
|
||||
} else if ((ipcp->my_ifip.s_addr & ipcp->cfg.my_range.mask.s_addr) ==
|
||||
(ipcp->cfg.my_range.ipaddr.s_addr &
|
||||
ipcp->cfg.my_range.mask.s_addr))
|
||||
} else {
|
||||
/*
|
||||
* Otherwise, if we've been assigned an IP number before, we really
|
||||
* want to keep the same IP number so that we can keep any existing
|
||||
* connections that are bound to that IP.
|
||||
* Otherwise, if we've used an IP number before and it's still within
|
||||
* the network specified on the ``set ifaddr'' line, we really
|
||||
* want to keep that IP number so that we can keep any existing
|
||||
* connections that are bound to that IP (assuming we're not
|
||||
* ``iface-alias''ing).
|
||||
*/
|
||||
ipcp->my_ip = ipcp->my_ifip;
|
||||
else
|
||||
ipcp->my_ip = ipcp->cfg.my_range.ipaddr;
|
||||
for (n = 0; n < iface->in_addrs; n++)
|
||||
if ((iface->in_addr[n].ifa.s_addr & ipcp->cfg.my_range.mask.s_addr) ==
|
||||
(ipcp->cfg.my_range.ipaddr.s_addr & ipcp->cfg.my_range.mask.s_addr)) {
|
||||
ipcp->my_ip = iface->in_addr[n].ifa;
|
||||
break;
|
||||
}
|
||||
if (n == iface->in_addrs)
|
||||
ipcp->my_ip = ipcp->cfg.my_range.ipaddr;
|
||||
}
|
||||
|
||||
if (IsEnabled(ipcp->cfg.vj.neg))
|
||||
ipcp->my_compproto = (PROTO_VJCOMP << 16) +
|
||||
@ -450,81 +460,51 @@ static int
|
||||
ipcp_SetIPaddress(struct bundle *bundle, struct in_addr myaddr,
|
||||
struct in_addr hisaddr, int silent)
|
||||
{
|
||||
struct sockaddr_in *sock_in;
|
||||
int s;
|
||||
u_int32_t mask, addr;
|
||||
struct ifaliasreq ifra;
|
||||
struct in_addr mask, oaddr;
|
||||
u_int32_t addr;
|
||||
|
||||
/* If given addresses are alreay set, then ignore this request */
|
||||
if (bundle->ncp.ipcp.my_ifip.s_addr == myaddr.s_addr &&
|
||||
bundle->ncp.ipcp.peer_ifip.s_addr == hisaddr.s_addr)
|
||||
return 0;
|
||||
|
||||
ipcp_CleanInterface(&bundle->ncp.ipcp);
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
log_Printf(LogERROR, "SetIPaddress: socket(): %s\n", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
memset(&ifra, '\0', sizeof ifra);
|
||||
strncpy(ifra.ifra_name, bundle->ifp.Name, sizeof ifra.ifra_name - 1);
|
||||
ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
|
||||
|
||||
/* Set interface address */
|
||||
sock_in = (struct sockaddr_in *)&ifra.ifra_addr;
|
||||
sock_in->sin_family = AF_INET;
|
||||
sock_in->sin_addr = myaddr;
|
||||
sock_in->sin_len = sizeof *sock_in;
|
||||
|
||||
/* Set destination address */
|
||||
sock_in = (struct sockaddr_in *)&ifra.ifra_broadaddr;
|
||||
sock_in->sin_family = AF_INET;
|
||||
sock_in->sin_addr = hisaddr;
|
||||
sock_in->sin_len = sizeof *sock_in;
|
||||
|
||||
addr = ntohl(myaddr.s_addr);
|
||||
addr = htonl(myaddr.s_addr);
|
||||
if (IN_CLASSA(addr))
|
||||
mask = IN_CLASSA_NET;
|
||||
mask.s_addr = htonl(IN_CLASSA_NET);
|
||||
else if (IN_CLASSB(addr))
|
||||
mask = IN_CLASSB_NET;
|
||||
mask.s_addr = htonl(IN_CLASSB_NET);
|
||||
else
|
||||
mask = IN_CLASSC_NET;
|
||||
mask.s_addr = htonl(IN_CLASSC_NET);
|
||||
|
||||
/* if subnet mask is given, use it instead of class mask */
|
||||
if (bundle->ncp.ipcp.cfg.netmask.s_addr != INADDR_ANY &&
|
||||
(ntohl(bundle->ncp.ipcp.cfg.netmask.s_addr) & mask) == mask)
|
||||
mask = ntohl(bundle->ncp.ipcp.cfg.netmask.s_addr);
|
||||
(ntohl(bundle->ncp.ipcp.cfg.netmask.s_addr) & mask.s_addr) == mask.s_addr)
|
||||
mask.s_addr = htonl(bundle->ncp.ipcp.cfg.netmask.s_addr);
|
||||
|
||||
sock_in = (struct sockaddr_in *)&ifra.ifra_mask;
|
||||
sock_in->sin_family = AF_INET;
|
||||
sock_in->sin_addr.s_addr = htonl(mask);
|
||||
sock_in->sin_len = sizeof *sock_in;
|
||||
oaddr.s_addr = bundle->iface->in_addrs ?
|
||||
bundle->iface->in_addr[0].ifa.s_addr : INADDR_ANY;
|
||||
if (!iface_inAdd(bundle->iface, myaddr, mask, hisaddr,
|
||||
IFACE_ADD_FIRST|IFACE_FORCE_ADD))
|
||||
return -1;
|
||||
|
||||
if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0) {
|
||||
if (!silent)
|
||||
log_Printf(LogERROR, "SetIPaddress: ioctl(SIOCAIFADDR): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
if (!Enabled(bundle, OPT_IFACEALIAS) && bundle->iface->in_addrs > 1
|
||||
&& myaddr.s_addr != oaddr.s_addr)
|
||||
/* Nuke the old one */
|
||||
iface_inDelete(bundle->iface, oaddr);
|
||||
|
||||
if (Enabled(bundle, OPT_SROUTES))
|
||||
route_Change(bundle, bundle->ncp.ipcp.route, myaddr, hisaddr);
|
||||
|
||||
bundle->ncp.ipcp.peer_ifip.s_addr = hisaddr.s_addr;
|
||||
bundle->ncp.ipcp.my_ifip.s_addr = myaddr.s_addr;
|
||||
if (Enabled(bundle, OPT_PROXY)) {
|
||||
int s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0)
|
||||
log_Printf(LogERROR, "ipcp_SetIPaddress: socket(): %s\n",
|
||||
strerror(errno));
|
||||
else {
|
||||
arp_SetProxy(bundle, hisaddr, s);
|
||||
close(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (Enabled(bundle, OPT_PROXY))
|
||||
arp_SetProxy(bundle, bundle->ncp.ipcp.peer_ifip, s);
|
||||
|
||||
close(s);
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct in_addr
|
||||
ChooseHisAddr(struct bundle *bundle, const struct in_addr gw)
|
||||
ChooseHisAddr(struct bundle *bundle, struct in_addr gw)
|
||||
{
|
||||
struct in_addr try;
|
||||
u_long f;
|
||||
@ -639,40 +619,22 @@ IpcpLayerFinish(struct fsm *fp)
|
||||
void
|
||||
ipcp_CleanInterface(struct ipcp *ipcp)
|
||||
{
|
||||
struct ifaliasreq ifra;
|
||||
struct sockaddr_in *me, *peer;
|
||||
int s;
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
log_Printf(LogERROR, "ipcp_CleanInterface: socket: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
struct iface *iface = ipcp->fsm.bundle->iface;
|
||||
|
||||
route_Clean(ipcp->fsm.bundle, ipcp->route);
|
||||
|
||||
if (Enabled(ipcp->fsm.bundle, OPT_PROXY))
|
||||
arp_ClearProxy(ipcp->fsm.bundle, ipcp->peer_ifip, s);
|
||||
|
||||
if (ipcp->my_ifip.s_addr != INADDR_ANY ||
|
||||
ipcp->peer_ifip.s_addr != INADDR_ANY) {
|
||||
memset(&ifra, '\0', sizeof ifra);
|
||||
strncpy(ifra.ifra_name, ipcp->fsm.bundle->ifp.Name,
|
||||
sizeof ifra.ifra_name - 1);
|
||||
ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
|
||||
me = (struct sockaddr_in *)&ifra.ifra_addr;
|
||||
peer = (struct sockaddr_in *)&ifra.ifra_broadaddr;
|
||||
me->sin_family = peer->sin_family = AF_INET;
|
||||
me->sin_len = peer->sin_len = sizeof(struct sockaddr_in);
|
||||
me->sin_addr = ipcp->my_ifip;
|
||||
peer->sin_addr = ipcp->peer_ifip;
|
||||
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0)
|
||||
log_Printf(LogERROR, "ipcp_CleanInterface: ioctl(SIOCDIFADDR): %s\n",
|
||||
strerror(errno));
|
||||
ipcp->my_ifip.s_addr = ipcp->peer_ifip.s_addr = INADDR_ANY;
|
||||
if (iface->in_addrs && Enabled(ipcp->fsm.bundle, OPT_PROXY)) {
|
||||
int s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0)
|
||||
log_Printf(LogERROR, "ipcp_CleanInterface: socket: %s\n",
|
||||
strerror(errno));
|
||||
else {
|
||||
arp_ClearProxy(ipcp->fsm.bundle, iface->in_addr[0].brd, s);
|
||||
close(s);
|
||||
}
|
||||
}
|
||||
|
||||
close(s);
|
||||
iface_inClear(ipcp->fsm.bundle->iface, IFACE_CLEAR_ALL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -682,7 +644,10 @@ IpcpLayerDown(struct fsm *fp)
|
||||
struct ipcp *ipcp = fsm2ipcp(fp);
|
||||
const char *s;
|
||||
|
||||
s = inet_ntoa(ipcp->peer_ifip);
|
||||
if (ipcp->fsm.bundle->iface->in_addrs)
|
||||
s = inet_ntoa(ipcp->fsm.bundle->iface->in_addr[0].ifa);
|
||||
else
|
||||
s = "Interface configuration error !";
|
||||
log_Printf(LogIPCP, "%s: LayerDown: %s\n", fp->link->name, s);
|
||||
|
||||
/*
|
||||
@ -698,9 +663,6 @@ IpcpLayerDown(struct fsm *fp)
|
||||
system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL);
|
||||
}
|
||||
|
||||
if (!(ipcp->fsm.bundle->phys_type.all & PHYS_AUTO))
|
||||
ipcp_CleanInterface(ipcp);
|
||||
|
||||
ipcp_Setup(ipcp);
|
||||
}
|
||||
|
||||
@ -725,11 +687,12 @@ IpcpLayerUp(struct fsm *fp)
|
||||
{
|
||||
/* We're now up */
|
||||
struct ipcp *ipcp = fsm2ipcp(fp);
|
||||
char tbuff[100];
|
||||
char tbuff[16];
|
||||
|
||||
log_Printf(LogIPCP, "%s: LayerUp.\n", fp->link->name);
|
||||
snprintf(tbuff, sizeof tbuff, "myaddr = %s ", inet_ntoa(ipcp->my_ip));
|
||||
log_Printf(LogIPCP, " %s hisaddr = %s\n", tbuff, inet_ntoa(ipcp->peer_ip));
|
||||
snprintf(tbuff, sizeof tbuff, "%s", inet_ntoa(ipcp->my_ip));
|
||||
log_Printf(LogIPCP, "myaddr %s hisaddr = %s\n",
|
||||
tbuff, inet_ntoa(ipcp->peer_ip));
|
||||
|
||||
if (ipcp->peer_compproto >> 16 == PROTO_VJCOMP)
|
||||
sl_compress_init(&ipcp->vj.cslc, (ipcp->peer_compproto >> 8) & 255);
|
||||
@ -741,8 +704,7 @@ IpcpLayerUp(struct fsm *fp)
|
||||
* XXX this stuff should really live in the FSM. Our config should
|
||||
* associate executable sections in files with events.
|
||||
*/
|
||||
if (system_Select(fp->bundle, inet_ntoa(ipcp->my_ifip), LINKUPFILE,
|
||||
NULL, NULL) < 0) {
|
||||
if (system_Select(fp->bundle, tbuff, LINKUPFILE, NULL, NULL) < 0) {
|
||||
if (bundle_GetLabel(fp->bundle)) {
|
||||
if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle),
|
||||
LINKUPFILE, NULL, NULL) < 0)
|
||||
@ -756,7 +718,7 @@ IpcpLayerUp(struct fsm *fp)
|
||||
}
|
||||
|
||||
static int
|
||||
AcceptableAddr(struct in_range *prange, struct in_addr ipaddr)
|
||||
AcceptableAddr(const struct in_range *prange, struct in_addr ipaddr)
|
||||
{
|
||||
/* Is the given IP in the given range ? */
|
||||
return (prange->ipaddr.s_addr & prange->mask.s_addr) ==
|
||||
@ -768,13 +730,13 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
struct fsm_decode *dec)
|
||||
{
|
||||
/* Deal with incoming PROTO_IPCP */
|
||||
struct iface *iface = fp->bundle->iface;
|
||||
struct ipcp *ipcp = fsm2ipcp(fp);
|
||||
int type, length;
|
||||
int type, length, gotdns, gotdnsnak, n;
|
||||
u_int32_t compproto;
|
||||
struct compreq *pcomp;
|
||||
struct in_addr ipaddr, dstipaddr, have_ip, dns[2], dnsnak[2];
|
||||
char tbuff[100], tbuff2[100];
|
||||
int gotdns, gotdnsnak;
|
||||
|
||||
gotdns = 0;
|
||||
gotdnsnak = 0;
|
||||
@ -810,14 +772,19 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
ipaddr, 1)) {
|
||||
log_Printf(LogIPCP, "%s: Address invalid or already in use\n",
|
||||
inet_ntoa(ipaddr));
|
||||
if (iplist_ip2pos(&ipcp->cfg.peer_list, ipcp->peer_ifip) >= 0)
|
||||
/*
|
||||
* If we've already got a valid address configured for the peer
|
||||
* (in AUTO mode), try NAKing with that so that we don't
|
||||
* have to upset things too much.
|
||||
*/
|
||||
ipcp->peer_ip = ipcp->peer_ifip;
|
||||
else
|
||||
/*
|
||||
* If we've already had a valid address configured for the peer,
|
||||
* try NAKing with that so that we don't have to upset things
|
||||
* too much.
|
||||
*/
|
||||
for (n = 0; n < iface->in_addrs; n++)
|
||||
if (iplist_ip2pos(&ipcp->cfg.peer_list, iface->in_addr[n].brd)
|
||||
>=0) {
|
||||
ipcp->peer_ip = iface->in_addr[n].brd;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == iface->in_addrs)
|
||||
/* Just pick an IP number from our list */
|
||||
ipcp->peer_ip = ChooseHisAddr
|
||||
(fp->bundle, ipcp->cfg.my_range.ipaddr);
|
||||
@ -827,7 +794,7 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
dec->rejend += length;
|
||||
} else {
|
||||
memcpy(dec->nakend, cp, 2);
|
||||
memcpy(dec->nakend+2, &ipcp->peer_ip.s_addr, length - 2);
|
||||
memcpy(dec->nakend + 2, &ipcp->peer_ip.s_addr, length - 2);
|
||||
dec->nakend += length;
|
||||
}
|
||||
break;
|
||||
@ -838,13 +805,20 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
* want to use.
|
||||
*/
|
||||
memcpy(dec->nakend, cp, 2);
|
||||
if ((ipcp->peer_ifip.s_addr & ipcp->cfg.peer_range.mask.s_addr) ==
|
||||
(ipcp->cfg.peer_range.ipaddr.s_addr &
|
||||
ipcp->cfg.peer_range.mask.s_addr))
|
||||
/* We prefer the already-configured address */
|
||||
memcpy(dec->nakend+2, &ipcp->peer_ifip.s_addr, length - 2);
|
||||
else
|
||||
memcpy(dec->nakend+2, &ipcp->peer_ip.s_addr, length - 2);
|
||||
for (n = 0; n < iface->in_addrs; n++)
|
||||
if ((iface->in_addr[n].brd.s_addr &
|
||||
ipcp->cfg.peer_range.mask.s_addr)
|
||||
== (ipcp->cfg.peer_range.ipaddr.s_addr &
|
||||
ipcp->cfg.peer_range.mask.s_addr)) {
|
||||
/* We prefer the already-configured address */
|
||||
memcpy(dec->nakend + 2, &iface->in_addr[n].brd.s_addr,
|
||||
length - 2);
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == iface->in_addrs)
|
||||
memcpy(dec->nakend + 2, &ipcp->peer_ip.s_addr, length - 2);
|
||||
|
||||
dec->nakend += length;
|
||||
break;
|
||||
}
|
||||
@ -852,6 +826,7 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
memcpy(dec->ackend, cp, length);
|
||||
dec->ackend += length;
|
||||
break;
|
||||
|
||||
case MODE_NAK:
|
||||
if (AcceptableAddr(&ipcp->cfg.my_range, ipaddr)) {
|
||||
/* Use address suggested by peer */
|
||||
@ -865,11 +840,13 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
fsm_Close(&ipcp->fsm);
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_REJ:
|
||||
ipcp->peer_reject |= (1 << type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case TY_COMPPROTO:
|
||||
memcpy(&compproto, cp + 2, 4);
|
||||
log_Printf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto));
|
||||
@ -920,16 +897,19 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_NAK:
|
||||
log_Printf(LogIPCP, "%s changing compproto: %08x --> %08x\n",
|
||||
tbuff, ipcp->my_compproto, compproto);
|
||||
ipcp->my_compproto = compproto;
|
||||
break;
|
||||
|
||||
case MODE_REJ:
|
||||
ipcp->peer_reject |= (1 << type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case TY_IPADDRS: /* RFC1172 */
|
||||
memcpy(&ipaddr.s_addr, cp + 2, 4);
|
||||
memcpy(&dstipaddr.s_addr, cp + 6, 4);
|
||||
@ -943,6 +923,7 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
memcpy(dec->ackend, cp, length);
|
||||
dec->ackend += length;
|
||||
break;
|
||||
|
||||
case MODE_NAK:
|
||||
snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s", tbuff,
|
||||
inet_ntoa(ipcp->my_ip));
|
||||
@ -950,6 +931,7 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
ipcp->my_ip = ipaddr;
|
||||
ipcp->peer_ip = dstipaddr;
|
||||
break;
|
||||
|
||||
case MODE_REJ:
|
||||
ipcp->peer_reject |= (1 << type);
|
||||
break;
|
||||
@ -995,12 +977,14 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
dec->ackend += length;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_NAK: /* what does this mean?? */
|
||||
if (IsEnabled(ipcp->cfg.ns.dns_neg)) {
|
||||
gotdnsnak = 1;
|
||||
memcpy(&dnsnak[type == TY_PRIMARY_DNS ? 0 : 1].s_addr, cp + 2, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_REJ: /* Can't do much, stop asking */
|
||||
ipcp->peer_reject |= (1 << (type - TY_ADJUST_NS));
|
||||
break;
|
||||
@ -1034,9 +1018,11 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
||||
dec->ackend += length;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_NAK:
|
||||
log_Printf(LogIPCP, "MS NBNS req %d - NAK??\n", type);
|
||||
break;
|
||||
|
||||
case MODE_REJ:
|
||||
log_Printf(LogIPCP, "MS NBNS req %d - REJ??\n", type);
|
||||
break;
|
||||
@ -1116,11 +1102,8 @@ ipcp_UseHisaddr(struct bundle *bundle, const char *hisaddr, int setaddr)
|
||||
ipcp->peer_ip.s_addr = ipcp->cfg.peer_range.ipaddr.s_addr;
|
||||
|
||||
if (setaddr && ipcp_SetIPaddress(bundle, ipcp->cfg.my_range.ipaddr,
|
||||
ipcp->cfg.peer_range.ipaddr, 0) < 0) {
|
||||
ipcp->cfg.my_range.ipaddr.s_addr = INADDR_ANY;
|
||||
ipcp->cfg.peer_range.ipaddr.s_addr = INADDR_ANY;
|
||||
ipcp->cfg.peer_range.ipaddr, 0) < 0)
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipcp.h,v 1.19 1998/05/21 21:45:49 brian Exp $
|
||||
* $Id: ipcp.h,v 1.20 1998/08/26 17:39:37 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -87,9 +87,6 @@ struct ipcp {
|
||||
u_int32_t peer_reject; /* Request codes rejected by peer */
|
||||
u_int32_t my_reject; /* Request codes I have rejected */
|
||||
|
||||
struct in_addr my_ifip; /* My configured interface address */
|
||||
struct in_addr peer_ifip; /* My congigured destination address */
|
||||
|
||||
struct pppThroughput throughput; /* throughput statistics */
|
||||
struct mqueue Queue[PRI_FAST + 1]; /* Output packet queues */
|
||||
};
|
||||
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: main.c,v 1.142 1998/08/09 09:13:54 brian Exp $
|
||||
* $Id: main.c,v 1.143 1998/09/17 00:45:27 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -75,6 +75,7 @@
|
||||
#include "chap.h"
|
||||
#include "cbcp.h"
|
||||
#include "datalink.h"
|
||||
#include "iface.h"
|
||||
|
||||
#ifndef O_NONBLOCK
|
||||
#ifdef O_NDELAY
|
||||
@ -329,10 +330,12 @@ main(int argc, char **argv)
|
||||
}
|
||||
if (prompt) {
|
||||
prompt->bundle = bundle; /* couldn't do it earlier */
|
||||
prompt_Printf(prompt, "Using interface: %s\n", bundle->ifp.Name);
|
||||
prompt_Printf(prompt, "Using interface: %s\n", bundle->iface->name);
|
||||
}
|
||||
SignalBundle = bundle;
|
||||
bundle->AliasEnabled = alias;
|
||||
if (alias)
|
||||
bundle->cfg.opt |= OPT_IFACEALIAS;
|
||||
|
||||
if (system_Select(bundle, "default", CONFFILE, prompt, NULL) < 0)
|
||||
prompt_Printf(prompt, "Warning: No default entry found in config file.\n");
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: ppp.8,v 1.125 1998/09/17 00:45:12 brian Exp $
|
||||
.\" $Id: ppp.8,v 1.126 1998/09/18 23:28:10 brian Exp $
|
||||
.Dd 20 September 1995
|
||||
.Os FreeBSD
|
||||
.Dt PPP 8
|
||||
@ -408,13 +408,10 @@ PPP ON awfulhak> add default HISADDR
|
||||
.Pp
|
||||
The string
|
||||
.Sq HISADDR
|
||||
represents the IP address of the connected peer. It is possible to
|
||||
use the keyword
|
||||
.Sq INTERFACE
|
||||
in place of
|
||||
.Sq HISADDR .
|
||||
This will create a direct route on the tun interface.
|
||||
If it fails due to an existing route, you can overwrite the existing
|
||||
represents the IP address of the connected peer.
|
||||
If the
|
||||
.Dq add
|
||||
command fails due to an existing route, you can overwrite the existing
|
||||
route using
|
||||
.Bd -literal -offset indent
|
||||
PPP ON awfulhak> add! default HISADDR
|
||||
@ -514,18 +511,15 @@ connection is established. See the provided
|
||||
.Dq pmdemand
|
||||
example in
|
||||
.Pa /etc/ppp/ppp.conf.sample
|
||||
which runs a script in the background after the connection is established.
|
||||
The literal strings
|
||||
.Dv HISADDR ,
|
||||
.Dv MYADDR
|
||||
which runs a script in the background after the connection is established
|
||||
(refer to the
|
||||
.Dq shell
|
||||
and
|
||||
.Dv INTERFACE
|
||||
may be used, and will be replaced with the relevant IP addresses and interface
|
||||
name. Similarly, when a connection is closed, the
|
||||
contents of the
|
||||
.Dq bg
|
||||
commands below for a description of possible substition strings). Similarly,
|
||||
when a connection is closed, the contents of the
|
||||
.Pa /etc/ppp/ppp.linkdown
|
||||
file are executed.
|
||||
Both of these files have the same format as
|
||||
file are executed. Both of these files have the same format as
|
||||
.Pa /etc/ppp/ppp.conf .
|
||||
.Pp
|
||||
In previous versions of
|
||||
@ -2134,6 +2128,28 @@ this option will tell
|
||||
.Nm
|
||||
not to make any utmp or wtmp entries. This is usually only necessary if
|
||||
you require the user to both login and authenticate themselves.
|
||||
.It iface-alias
|
||||
Default: Enabled if
|
||||
.Fl alias
|
||||
is specified. This option simply tells
|
||||
.Nm
|
||||
to add new interface addresses to the interface rather than replacing them.
|
||||
The option can only be enabled if IP aliasing is enabled
|
||||
.Pq Dq alias enable yes .
|
||||
.Pp
|
||||
With this option enabled,
|
||||
.Nm
|
||||
will pass traffic for old interface addresses through the IP alias engine
|
||||
.Pq see Xr libalias 5 ,
|
||||
resulting in the ability (in
|
||||
.Fl auto
|
||||
mode) to properly connect the process that caused the PPP link to
|
||||
come up in the first place.
|
||||
.Pp
|
||||
Disabling IP aliasing with
|
||||
.Dq alias enable off
|
||||
will also disable
|
||||
.Sq iface-alias .
|
||||
.El
|
||||
.Pp
|
||||
.It add[!] Ar dest[/nn] [mask] gateway
|
||||
@ -2162,24 +2178,14 @@ It is possible to use the symbolic names
|
||||
.Sq MYADDR
|
||||
or
|
||||
.Sq HISADDR
|
||||
as the destination, and either
|
||||
as the destination, and
|
||||
.Sq HISADDR
|
||||
or
|
||||
.Sq INTERFACE
|
||||
as the
|
||||
.Ar gateway .
|
||||
.Sq MYADDR
|
||||
is replaced with the interface address,
|
||||
is replaced with the interface address and
|
||||
.Sq HISADDR
|
||||
is replaced with the interface destination address and
|
||||
.Sq INTERFACE
|
||||
is replaced with the current interface name. If the interfaces destination
|
||||
address has not yet been assigned
|
||||
.Pq via Dq set ifaddr ,
|
||||
the current
|
||||
.Sq INTERFACE
|
||||
is used instead of
|
||||
.Sq HISADDR .
|
||||
is replaced with the interface destination (peer) address.
|
||||
.Pp
|
||||
If the
|
||||
.Ar add!
|
||||
@ -2476,6 +2482,52 @@ is specified, only the relevant compression layer(s) are terminated.
|
||||
Show a list of available commands. If
|
||||
.Ar command
|
||||
is specified, show the usage string for that command.
|
||||
.It iface Ar command Op args
|
||||
This command is used to control the interface used by
|
||||
.Nm ppp .
|
||||
.Ar Command
|
||||
may be one of the following:
|
||||
.Bl -tag -width XX
|
||||
.It iface add[!] Ar addr[/bits| mask] peer
|
||||
Add the given
|
||||
.Ar addr mask peer
|
||||
combination to the interface. Instead of specifying
|
||||
.Ar mask ,
|
||||
.Ar /bits
|
||||
can be used
|
||||
.Pq with no space between \&it and Ar addr .
|
||||
If the given address already exists, the command fails unless the
|
||||
.Dq \&!
|
||||
is used - in which case the previous interface address entry is overwritten
|
||||
with the new one, allowing a change of netmask or peer address.
|
||||
.It iface clear
|
||||
If this command is used while
|
||||
.Nm
|
||||
is in the OPENED state, all addresses except for the IPCP negotiated
|
||||
address are deleted from the interface. If
|
||||
.Nm
|
||||
is not in the OPENED state, all interface addresses are deleted.
|
||||
.Pp
|
||||
.It iface delete[!]|rm[!] Ar addr
|
||||
This command deletes the given
|
||||
.Ar addr
|
||||
from the interface. If the
|
||||
.Dq \&!
|
||||
is used, no error is given if the address isn't currently assigned to
|
||||
the interface (and no deletion takes place).
|
||||
.It iface show
|
||||
Shows the current state and current addresses for the interface. It is
|
||||
much the same as running
|
||||
.Dq ifconfig INTERFACE .
|
||||
.It iface help Op Ar sub-command
|
||||
This command, when invoked without
|
||||
.Ar sub-command ,
|
||||
will show a list of possbile
|
||||
.Dq iface
|
||||
sub-commands and a brief synopsis for each. When invoked with
|
||||
.Ar sub-command ,
|
||||
only the synopsis for the given sub-command is shown.
|
||||
.El
|
||||
.It [data]link Ar name[,name...] command Op Ar args
|
||||
This command may prefix any other command if the user wishes to
|
||||
specify which link the command should affect. This is only
|
||||
@ -3160,6 +3212,16 @@ It is not possible to change a link that is
|
||||
.Sq direct
|
||||
or
|
||||
.Sq dedicated .
|
||||
.Pp
|
||||
Note: If you issue the command
|
||||
.Dq set mode auto ,
|
||||
and have IP aliasing enabled, it may be useful to
|
||||
.Dq enable iface-alias
|
||||
afterwards. This will allow
|
||||
.Nm
|
||||
to do the necessary address translations to enable the process that
|
||||
triggers the connection to connect once the link is up despite the
|
||||
peer assigning us a new (dynamic) IP address.
|
||||
.It set mrru Op Ar value
|
||||
Setting this option enables Multi-link PPP negotiations, also known as
|
||||
Multi-link Protocol or MP. There is no default MRRU (Maximum
|
||||
@ -3409,6 +3471,9 @@ is not specified, all filters are shown.
|
||||
Show the current HDLC statistics.
|
||||
.It show help|?
|
||||
Give a summary of available show commands.
|
||||
.It show iface
|
||||
Show the current interface information
|
||||
.Pq the same \&as Dq iface show .
|
||||
.It show ipcp
|
||||
Show the current IPCP statistics.
|
||||
.It show lcp
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: ppp.8,v 1.125 1998/09/17 00:45:12 brian Exp $
|
||||
.\" $Id: ppp.8,v 1.126 1998/09/18 23:28:10 brian Exp $
|
||||
.Dd 20 September 1995
|
||||
.Os FreeBSD
|
||||
.Dt PPP 8
|
||||
@ -408,13 +408,10 @@ PPP ON awfulhak> add default HISADDR
|
||||
.Pp
|
||||
The string
|
||||
.Sq HISADDR
|
||||
represents the IP address of the connected peer. It is possible to
|
||||
use the keyword
|
||||
.Sq INTERFACE
|
||||
in place of
|
||||
.Sq HISADDR .
|
||||
This will create a direct route on the tun interface.
|
||||
If it fails due to an existing route, you can overwrite the existing
|
||||
represents the IP address of the connected peer.
|
||||
If the
|
||||
.Dq add
|
||||
command fails due to an existing route, you can overwrite the existing
|
||||
route using
|
||||
.Bd -literal -offset indent
|
||||
PPP ON awfulhak> add! default HISADDR
|
||||
@ -514,18 +511,15 @@ connection is established. See the provided
|
||||
.Dq pmdemand
|
||||
example in
|
||||
.Pa /etc/ppp/ppp.conf.sample
|
||||
which runs a script in the background after the connection is established.
|
||||
The literal strings
|
||||
.Dv HISADDR ,
|
||||
.Dv MYADDR
|
||||
which runs a script in the background after the connection is established
|
||||
(refer to the
|
||||
.Dq shell
|
||||
and
|
||||
.Dv INTERFACE
|
||||
may be used, and will be replaced with the relevant IP addresses and interface
|
||||
name. Similarly, when a connection is closed, the
|
||||
contents of the
|
||||
.Dq bg
|
||||
commands below for a description of possible substition strings). Similarly,
|
||||
when a connection is closed, the contents of the
|
||||
.Pa /etc/ppp/ppp.linkdown
|
||||
file are executed.
|
||||
Both of these files have the same format as
|
||||
file are executed. Both of these files have the same format as
|
||||
.Pa /etc/ppp/ppp.conf .
|
||||
.Pp
|
||||
In previous versions of
|
||||
@ -2134,6 +2128,28 @@ this option will tell
|
||||
.Nm
|
||||
not to make any utmp or wtmp entries. This is usually only necessary if
|
||||
you require the user to both login and authenticate themselves.
|
||||
.It iface-alias
|
||||
Default: Enabled if
|
||||
.Fl alias
|
||||
is specified. This option simply tells
|
||||
.Nm
|
||||
to add new interface addresses to the interface rather than replacing them.
|
||||
The option can only be enabled if IP aliasing is enabled
|
||||
.Pq Dq alias enable yes .
|
||||
.Pp
|
||||
With this option enabled,
|
||||
.Nm
|
||||
will pass traffic for old interface addresses through the IP alias engine
|
||||
.Pq see Xr libalias 5 ,
|
||||
resulting in the ability (in
|
||||
.Fl auto
|
||||
mode) to properly connect the process that caused the PPP link to
|
||||
come up in the first place.
|
||||
.Pp
|
||||
Disabling IP aliasing with
|
||||
.Dq alias enable off
|
||||
will also disable
|
||||
.Sq iface-alias .
|
||||
.El
|
||||
.Pp
|
||||
.It add[!] Ar dest[/nn] [mask] gateway
|
||||
@ -2162,24 +2178,14 @@ It is possible to use the symbolic names
|
||||
.Sq MYADDR
|
||||
or
|
||||
.Sq HISADDR
|
||||
as the destination, and either
|
||||
as the destination, and
|
||||
.Sq HISADDR
|
||||
or
|
||||
.Sq INTERFACE
|
||||
as the
|
||||
.Ar gateway .
|
||||
.Sq MYADDR
|
||||
is replaced with the interface address,
|
||||
is replaced with the interface address and
|
||||
.Sq HISADDR
|
||||
is replaced with the interface destination address and
|
||||
.Sq INTERFACE
|
||||
is replaced with the current interface name. If the interfaces destination
|
||||
address has not yet been assigned
|
||||
.Pq via Dq set ifaddr ,
|
||||
the current
|
||||
.Sq INTERFACE
|
||||
is used instead of
|
||||
.Sq HISADDR .
|
||||
is replaced with the interface destination (peer) address.
|
||||
.Pp
|
||||
If the
|
||||
.Ar add!
|
||||
@ -2476,6 +2482,52 @@ is specified, only the relevant compression layer(s) are terminated.
|
||||
Show a list of available commands. If
|
||||
.Ar command
|
||||
is specified, show the usage string for that command.
|
||||
.It iface Ar command Op args
|
||||
This command is used to control the interface used by
|
||||
.Nm ppp .
|
||||
.Ar Command
|
||||
may be one of the following:
|
||||
.Bl -tag -width XX
|
||||
.It iface add[!] Ar addr[/bits| mask] peer
|
||||
Add the given
|
||||
.Ar addr mask peer
|
||||
combination to the interface. Instead of specifying
|
||||
.Ar mask ,
|
||||
.Ar /bits
|
||||
can be used
|
||||
.Pq with no space between \&it and Ar addr .
|
||||
If the given address already exists, the command fails unless the
|
||||
.Dq \&!
|
||||
is used - in which case the previous interface address entry is overwritten
|
||||
with the new one, allowing a change of netmask or peer address.
|
||||
.It iface clear
|
||||
If this command is used while
|
||||
.Nm
|
||||
is in the OPENED state, all addresses except for the IPCP negotiated
|
||||
address are deleted from the interface. If
|
||||
.Nm
|
||||
is not in the OPENED state, all interface addresses are deleted.
|
||||
.Pp
|
||||
.It iface delete[!]|rm[!] Ar addr
|
||||
This command deletes the given
|
||||
.Ar addr
|
||||
from the interface. If the
|
||||
.Dq \&!
|
||||
is used, no error is given if the address isn't currently assigned to
|
||||
the interface (and no deletion takes place).
|
||||
.It iface show
|
||||
Shows the current state and current addresses for the interface. It is
|
||||
much the same as running
|
||||
.Dq ifconfig INTERFACE .
|
||||
.It iface help Op Ar sub-command
|
||||
This command, when invoked without
|
||||
.Ar sub-command ,
|
||||
will show a list of possbile
|
||||
.Dq iface
|
||||
sub-commands and a brief synopsis for each. When invoked with
|
||||
.Ar sub-command ,
|
||||
only the synopsis for the given sub-command is shown.
|
||||
.El
|
||||
.It [data]link Ar name[,name...] command Op Ar args
|
||||
This command may prefix any other command if the user wishes to
|
||||
specify which link the command should affect. This is only
|
||||
@ -3160,6 +3212,16 @@ It is not possible to change a link that is
|
||||
.Sq direct
|
||||
or
|
||||
.Sq dedicated .
|
||||
.Pp
|
||||
Note: If you issue the command
|
||||
.Dq set mode auto ,
|
||||
and have IP aliasing enabled, it may be useful to
|
||||
.Dq enable iface-alias
|
||||
afterwards. This will allow
|
||||
.Nm
|
||||
to do the necessary address translations to enable the process that
|
||||
triggers the connection to connect once the link is up despite the
|
||||
peer assigning us a new (dynamic) IP address.
|
||||
.It set mrru Op Ar value
|
||||
Setting this option enables Multi-link PPP negotiations, also known as
|
||||
Multi-link Protocol or MP. There is no default MRRU (Maximum
|
||||
@ -3409,6 +3471,9 @@ is not specified, all filters are shown.
|
||||
Show the current HDLC statistics.
|
||||
.It show help|?
|
||||
Give a summary of available show commands.
|
||||
.It show iface
|
||||
Show the current interface information
|
||||
.Pq the same \&as Dq iface show .
|
||||
.It show ipcp
|
||||
Show the current IPCP statistics.
|
||||
.It show lcp
|
||||
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: route.c,v 1.52 1998/07/28 21:54:54 brian Exp $
|
||||
* $Id: route.c,v 1.53 1998/08/17 06:42:40 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -61,6 +61,7 @@
|
||||
#include "bundle.h"
|
||||
#include "route.h"
|
||||
#include "prompt.h"
|
||||
#include "iface.h"
|
||||
|
||||
static void
|
||||
p_sockaddr(struct prompt *prompt, struct sockaddr *phost,
|
||||
@ -361,7 +362,7 @@ route_IfDelete(struct bundle *bundle, int all)
|
||||
char *sp, *cp, *ep;
|
||||
int mib[6];
|
||||
|
||||
log_Printf(LogDEBUG, "route_IfDelete (%d)\n", bundle->ifp.Index);
|
||||
log_Printf(LogDEBUG, "route_IfDelete (%d)\n", bundle->iface->index);
|
||||
sa_none.s_addr = INADDR_ANY;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
@ -407,7 +408,7 @@ route_IfDelete(struct bundle *bundle, int all)
|
||||
Index2Nam(rtm->rtm_index), rtm->rtm_flags,
|
||||
inet_ntoa(((struct sockaddr_in *) sa)->sin_addr));
|
||||
if (rtm->rtm_addrs & RTA_DST && rtm->rtm_addrs & RTA_GATEWAY &&
|
||||
rtm->rtm_index == bundle->ifp.Index &&
|
||||
rtm->rtm_index == bundle->iface->index &&
|
||||
(all || (rtm->rtm_flags & RTF_GATEWAY))) {
|
||||
sa_dst.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
|
||||
sa = (struct sockaddr *)((char *)sa + sa->sa_len);
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: tun.c,v 1.8 1998/06/27 14:18:15 brian Exp $
|
||||
* $Id: tun.c,v 1.9 1998/08/09 16:41:01 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -65,9 +65,10 @@ tun_configure(struct bundle *bundle, int mtu)
|
||||
{
|
||||
struct tuninfo info;
|
||||
|
||||
memset(&info, '\0', sizeof info);
|
||||
info.type = IFT_PPP;
|
||||
info.mtu = mtu;
|
||||
info.baudrate = bundle->ifp.Speed;
|
||||
info.baudrate = bundle->ifSpeed;
|
||||
#ifdef __OpenBSD__
|
||||
info.flags = IFF_UP|IFF_POINTOPOINT;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user