Deleted Added
full compact
ipcp.c (39395) ipcp.c (40561)
1/*
2 * PPP IP Control Protocol (IPCP) Module
3 *
4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5 *
6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the Internet Initiative Japan, Inc. The name of the
14 * IIJ may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 *
1/*
2 * PPP IP Control Protocol (IPCP) Module
3 *
4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5 *
6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the Internet Initiative Japan, Inc. The name of the
14 * IIJ may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * $Id: ipcp.c,v 1.65 1998/09/04 18:25:59 brian Exp $
20 * $Id: ipcp.c,v 1.66 1998/09/17 00:45:26 brian Exp $
21 *
22 * TODO:
23 * o More RFC1772 backward compatibility
24 */
25#include <sys/param.h>
26#include <netinet/in_systm.h>
27#include <netinet/in.h>
28#include <netinet/ip.h>

--- 43 unchanged lines hidden (view full) ---

72#include "physical.h"
73#include "mp.h"
74#include "bundle.h"
75#include "id.h"
76#include "arp.h"
77#include "systems.h"
78#include "prompt.h"
79#include "route.h"
21 *
22 * TODO:
23 * o More RFC1772 backward compatibility
24 */
25#include <sys/param.h>
26#include <netinet/in_systm.h>
27#include <netinet/in.h>
28#include <netinet/ip.h>

--- 43 unchanged lines hidden (view full) ---

72#include "physical.h"
73#include "mp.h"
74#include "bundle.h"
75#include "id.h"
76#include "arp.h"
77#include "systems.h"
78#include "prompt.h"
79#include "route.h"
80#include "iface.h"
80
81#undef REJECTED
82#define REJECTED(p, x) ((p)->peer_reject & (1<<(x)))
83#define issep(ch) ((ch) == ' ' || (ch) == '\t')
84#define isip(ch) (((ch) >= '0' && (ch) <= '9') || (ch) == '.')
85
86struct compreq {
87 u_short proto;

--- 261 unchanged lines hidden (view full) ---

349 bundle, l, parent, &ipcp_Callbacks, timer_names);
350
351 ipcp->route = NULL;
352 ipcp->cfg.vj.slots = DEF_VJ_STATES;
353 ipcp->cfg.vj.slotcomp = 1;
354 memset(&ipcp->cfg.my_range, '\0', sizeof ipcp->cfg.my_range);
355 if (gethostname(name, sizeof name) == 0) {
356 hp = gethostbyname(name);
81
82#undef REJECTED
83#define REJECTED(p, x) ((p)->peer_reject & (1<<(x)))
84#define issep(ch) ((ch) == ' ' || (ch) == '\t')
85#define isip(ch) (((ch) >= '0' && (ch) <= '9') || (ch) == '.')
86
87struct compreq {
88 u_short proto;

--- 261 unchanged lines hidden (view full) ---

350 bundle, l, parent, &ipcp_Callbacks, timer_names);
351
352 ipcp->route = NULL;
353 ipcp->cfg.vj.slots = DEF_VJ_STATES;
354 ipcp->cfg.vj.slotcomp = 1;
355 memset(&ipcp->cfg.my_range, '\0', sizeof ipcp->cfg.my_range);
356 if (gethostname(name, sizeof name) == 0) {
357 hp = gethostbyname(name);
357 if (hp && hp->h_addrtype == AF_INET) {
358 if (hp && hp->h_addrtype == AF_INET)
358 memcpy(&ipcp->cfg.my_range.ipaddr.s_addr, hp->h_addr, hp->h_length);
359 memcpy(&ipcp->cfg.my_range.ipaddr.s_addr, hp->h_addr, hp->h_length);
359 ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
360 ipcp->cfg.peer_range.width = 32;
361 }
362 }
363 ipcp->cfg.netmask.s_addr = INADDR_ANY;
364 memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range);
365 iplist_setsrc(&ipcp->cfg.peer_list, "");
366 ipcp->cfg.HaveTriggerAddress = 0;
367
368 ipcp->cfg.ns.dns[0].s_addr = INADDR_ANY;
369 ipcp->cfg.ns.dns[1].s_addr = INADDR_ANY;
370 ipcp->cfg.ns.dns_neg = 0;
371 ipcp->cfg.ns.nbns[0].s_addr = INADDR_ANY;
372 ipcp->cfg.ns.nbns[1].s_addr = INADDR_ANY;
373
374 ipcp->cfg.fsmretry = DEF_FSMRETRY;
375 ipcp->cfg.vj.neg = NEG_ENABLED|NEG_ACCEPTED;
376
377 memset(&ipcp->vj, '\0', sizeof ipcp->vj);
378
360 }
361 ipcp->cfg.netmask.s_addr = INADDR_ANY;
362 memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range);
363 iplist_setsrc(&ipcp->cfg.peer_list, "");
364 ipcp->cfg.HaveTriggerAddress = 0;
365
366 ipcp->cfg.ns.dns[0].s_addr = INADDR_ANY;
367 ipcp->cfg.ns.dns[1].s_addr = INADDR_ANY;
368 ipcp->cfg.ns.dns_neg = 0;
369 ipcp->cfg.ns.nbns[0].s_addr = INADDR_ANY;
370 ipcp->cfg.ns.nbns[1].s_addr = INADDR_ANY;
371
372 ipcp->cfg.fsmretry = DEF_FSMRETRY;
373 ipcp->cfg.vj.neg = NEG_ENABLED|NEG_ACCEPTED;
374
375 memset(&ipcp->vj, '\0', sizeof ipcp->vj);
376
379 ipcp->my_ifip.s_addr = INADDR_ANY;
380 ipcp->peer_ifip.s_addr = INADDR_ANY;
381
382 throughput_init(&ipcp->throughput);
383 memset(ipcp->Queue, '\0', sizeof ipcp->Queue);
384 ipcp_Setup(ipcp);
385}
386
387void
388ipcp_SetLink(struct ipcp *ipcp, struct link *l)
389{
390 ipcp->fsm.link = l;
391}
392
393void
394ipcp_Setup(struct ipcp *ipcp)
395{
377 throughput_init(&ipcp->throughput);
378 memset(ipcp->Queue, '\0', sizeof ipcp->Queue);
379 ipcp_Setup(ipcp);
380}
381
382void
383ipcp_SetLink(struct ipcp *ipcp, struct link *l)
384{
385 ipcp->fsm.link = l;
386}
387
388void
389ipcp_Setup(struct ipcp *ipcp)
390{
396 int pos;
391 struct iface *iface = ipcp->fsm.bundle->iface;
392 int pos, n;
397
398 ipcp->fsm.open_mode = 0;
399 ipcp->fsm.maxconfig = 10;
400
401 if (iplist_isvalid(&ipcp->cfg.peer_list)) {
393
394 ipcp->fsm.open_mode = 0;
395 ipcp->fsm.maxconfig = 10;
396
397 if (iplist_isvalid(&ipcp->cfg.peer_list)) {
402 if (ipcp->my_ifip.s_addr != INADDR_ANY &&
403 (pos = iplist_ip2pos(&ipcp->cfg.peer_list, ipcp->my_ifip)) != -1)
404 ipcp->cfg.peer_range.ipaddr = iplist_setcurpos(&ipcp->cfg.peer_list, pos);
405 else
398 /* Try to give the peer a previously configured IP address */
399 for (n = 0; n < iface->in_addrs; n++) {
400 pos = iplist_ip2pos(&ipcp->cfg.peer_list, iface->in_addr[n].brd);
401 if (pos != -1) {
402 ipcp->cfg.peer_range.ipaddr =
403 iplist_setcurpos(&ipcp->cfg.peer_list, pos);
404 break;
405 }
406 }
407 if (n == iface->in_addrs)
408 /* Ok, so none of 'em fit.... pick a random one */
406 ipcp->cfg.peer_range.ipaddr = iplist_setrandpos(&ipcp->cfg.peer_list);
409 ipcp->cfg.peer_range.ipaddr = iplist_setrandpos(&ipcp->cfg.peer_list);
410
407 ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
408 ipcp->cfg.peer_range.width = 32;
409 }
410
411 ipcp->heis1172 = 0;
412
413 ipcp->peer_ip = ipcp->cfg.peer_range.ipaddr;
414 ipcp->peer_compproto = 0;
415
416 if (ipcp->cfg.HaveTriggerAddress) {
417 /*
418 * Some implementations of PPP require that we send a
419 * *special* value as our address, even though the rfc specifies
420 * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0").
421 */
422 ipcp->my_ip = ipcp->cfg.TriggerAddress;
423 log_Printf(LogIPCP, "Using trigger address %s\n",
424 inet_ntoa(ipcp->cfg.TriggerAddress));
411 ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
412 ipcp->cfg.peer_range.width = 32;
413 }
414
415 ipcp->heis1172 = 0;
416
417 ipcp->peer_ip = ipcp->cfg.peer_range.ipaddr;
418 ipcp->peer_compproto = 0;
419
420 if (ipcp->cfg.HaveTriggerAddress) {
421 /*
422 * Some implementations of PPP require that we send a
423 * *special* value as our address, even though the rfc specifies
424 * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0").
425 */
426 ipcp->my_ip = ipcp->cfg.TriggerAddress;
427 log_Printf(LogIPCP, "Using trigger address %s\n",
428 inet_ntoa(ipcp->cfg.TriggerAddress));
425 } else if ((ipcp->my_ifip.s_addr & ipcp->cfg.my_range.mask.s_addr) ==
426 (ipcp->cfg.my_range.ipaddr.s_addr &
427 ipcp->cfg.my_range.mask.s_addr))
429 } else {
428 /*
430 /*
429 * Otherwise, if we've been assigned an IP number before, we really
430 * want to keep the same IP number so that we can keep any existing
431 * connections that are bound to that IP.
431 * Otherwise, if we've used an IP number before and it's still within
432 * the network specified on the ``set ifaddr'' line, we really
433 * want to keep that IP number so that we can keep any existing
434 * connections that are bound to that IP (assuming we're not
435 * ``iface-alias''ing).
432 */
436 */
433 ipcp->my_ip = ipcp->my_ifip;
434 else
435 ipcp->my_ip = ipcp->cfg.my_range.ipaddr;
437 for (n = 0; n < iface->in_addrs; n++)
438 if ((iface->in_addr[n].ifa.s_addr & ipcp->cfg.my_range.mask.s_addr) ==
439 (ipcp->cfg.my_range.ipaddr.s_addr & ipcp->cfg.my_range.mask.s_addr)) {
440 ipcp->my_ip = iface->in_addr[n].ifa;
441 break;
442 }
443 if (n == iface->in_addrs)
444 ipcp->my_ip = ipcp->cfg.my_range.ipaddr;
445 }
436
437 if (IsEnabled(ipcp->cfg.vj.neg))
438 ipcp->my_compproto = (PROTO_VJCOMP << 16) +
439 ((ipcp->cfg.vj.slots - 1) << 8) +
440 ipcp->cfg.vj.slotcomp;
441 else
442 ipcp->my_compproto = 0;
443 sl_compress_init(&ipcp->vj.cslc, ipcp->cfg.vj.slots - 1);
444
445 ipcp->peer_reject = 0;
446 ipcp->my_reject = 0;
447}
448
449static int
450ipcp_SetIPaddress(struct bundle *bundle, struct in_addr myaddr,
451 struct in_addr hisaddr, int silent)
452{
446
447 if (IsEnabled(ipcp->cfg.vj.neg))
448 ipcp->my_compproto = (PROTO_VJCOMP << 16) +
449 ((ipcp->cfg.vj.slots - 1) << 8) +
450 ipcp->cfg.vj.slotcomp;
451 else
452 ipcp->my_compproto = 0;
453 sl_compress_init(&ipcp->vj.cslc, ipcp->cfg.vj.slots - 1);
454
455 ipcp->peer_reject = 0;
456 ipcp->my_reject = 0;
457}
458
459static int
460ipcp_SetIPaddress(struct bundle *bundle, struct in_addr myaddr,
461 struct in_addr hisaddr, int silent)
462{
453 struct sockaddr_in *sock_in;
454 int s;
455 u_int32_t mask, addr;
456 struct ifaliasreq ifra;
463 struct in_addr mask, oaddr;
464 u_int32_t addr;
457
465
458 /* If given addresses are alreay set, then ignore this request */
459 if (bundle->ncp.ipcp.my_ifip.s_addr == myaddr.s_addr &&
460 bundle->ncp.ipcp.peer_ifip.s_addr == hisaddr.s_addr)
461 return 0;
462
463 ipcp_CleanInterface(&bundle->ncp.ipcp);
464
465 s = ID0socket(AF_INET, SOCK_DGRAM, 0);
466 if (s < 0) {
467 log_Printf(LogERROR, "SetIPaddress: socket(): %s\n", strerror(errno));
468 return (-1);
469 }
470
471 memset(&ifra, '\0', sizeof ifra);
472 strncpy(ifra.ifra_name, bundle->ifp.Name, sizeof ifra.ifra_name - 1);
473 ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
474
475 /* Set interface address */
476 sock_in = (struct sockaddr_in *)&ifra.ifra_addr;
477 sock_in->sin_family = AF_INET;
478 sock_in->sin_addr = myaddr;
479 sock_in->sin_len = sizeof *sock_in;
480
481 /* Set destination address */
482 sock_in = (struct sockaddr_in *)&ifra.ifra_broadaddr;
483 sock_in->sin_family = AF_INET;
484 sock_in->sin_addr = hisaddr;
485 sock_in->sin_len = sizeof *sock_in;
486
487 addr = ntohl(myaddr.s_addr);
466 addr = htonl(myaddr.s_addr);
488 if (IN_CLASSA(addr))
467 if (IN_CLASSA(addr))
489 mask = IN_CLASSA_NET;
468 mask.s_addr = htonl(IN_CLASSA_NET);
490 else if (IN_CLASSB(addr))
469 else if (IN_CLASSB(addr))
491 mask = IN_CLASSB_NET;
470 mask.s_addr = htonl(IN_CLASSB_NET);
492 else
471 else
493 mask = IN_CLASSC_NET;
472 mask.s_addr = htonl(IN_CLASSC_NET);
494
473
495 /* if subnet mask is given, use it instead of class mask */
496 if (bundle->ncp.ipcp.cfg.netmask.s_addr != INADDR_ANY &&
474 if (bundle->ncp.ipcp.cfg.netmask.s_addr != INADDR_ANY &&
497 (ntohl(bundle->ncp.ipcp.cfg.netmask.s_addr) & mask) == mask)
498 mask = ntohl(bundle->ncp.ipcp.cfg.netmask.s_addr);
475 (ntohl(bundle->ncp.ipcp.cfg.netmask.s_addr) & mask.s_addr) == mask.s_addr)
476 mask.s_addr = htonl(bundle->ncp.ipcp.cfg.netmask.s_addr);
499
477
500 sock_in = (struct sockaddr_in *)&ifra.ifra_mask;
501 sock_in->sin_family = AF_INET;
502 sock_in->sin_addr.s_addr = htonl(mask);
503 sock_in->sin_len = sizeof *sock_in;
478 oaddr.s_addr = bundle->iface->in_addrs ?
479 bundle->iface->in_addr[0].ifa.s_addr : INADDR_ANY;
480 if (!iface_inAdd(bundle->iface, myaddr, mask, hisaddr,
481 IFACE_ADD_FIRST|IFACE_FORCE_ADD))
482 return -1;
504
483
505 if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0) {
506 if (!silent)
507 log_Printf(LogERROR, "SetIPaddress: ioctl(SIOCAIFADDR): %s\n",
508 strerror(errno));
509 close(s);
510 return (-1);
511 }
484 if (!Enabled(bundle, OPT_IFACEALIAS) && bundle->iface->in_addrs > 1
485 && myaddr.s_addr != oaddr.s_addr)
486 /* Nuke the old one */
487 iface_inDelete(bundle->iface, oaddr);
512
513 if (Enabled(bundle, OPT_SROUTES))
514 route_Change(bundle, bundle->ncp.ipcp.route, myaddr, hisaddr);
515
488
489 if (Enabled(bundle, OPT_SROUTES))
490 route_Change(bundle, bundle->ncp.ipcp.route, myaddr, hisaddr);
491
516 bundle->ncp.ipcp.peer_ifip.s_addr = hisaddr.s_addr;
517 bundle->ncp.ipcp.my_ifip.s_addr = myaddr.s_addr;
492 if (Enabled(bundle, OPT_PROXY)) {
493 int s = ID0socket(AF_INET, SOCK_DGRAM, 0);
494 if (s < 0)
495 log_Printf(LogERROR, "ipcp_SetIPaddress: socket(): %s\n",
496 strerror(errno));
497 else {
498 arp_SetProxy(bundle, hisaddr, s);
499 close(s);
500 }
501 }
518
502
519 if (Enabled(bundle, OPT_PROXY))
520 arp_SetProxy(bundle, bundle->ncp.ipcp.peer_ifip, s);
521
522 close(s);
523 return (0);
503 return 0;
524}
525
526static struct in_addr
504}
505
506static struct in_addr
527ChooseHisAddr(struct bundle *bundle, const struct in_addr gw)
507ChooseHisAddr(struct bundle *bundle, struct in_addr gw)
528{
529 struct in_addr try;
530 u_long f;
531
532 for (f = 0; f < bundle->ncp.ipcp.cfg.peer_list.nItems; f++) {
533 try = iplist_next(&bundle->ncp.ipcp.cfg.peer_list);
534 log_Printf(LogDEBUG, "ChooseHisAddr: Check item %ld (%s)\n",
535 f, inet_ntoa(try));

--- 98 unchanged lines hidden (view full) ---

634 log_Printf(LogIPCP, "%s: LayerFinish.\n", fp->link->name);
635 throughput_stop(&ipcp->throughput);
636 throughput_log(&ipcp->throughput, LogIPCP, NULL);
637}
638
639void
640ipcp_CleanInterface(struct ipcp *ipcp)
641{
508{
509 struct in_addr try;
510 u_long f;
511
512 for (f = 0; f < bundle->ncp.ipcp.cfg.peer_list.nItems; f++) {
513 try = iplist_next(&bundle->ncp.ipcp.cfg.peer_list);
514 log_Printf(LogDEBUG, "ChooseHisAddr: Check item %ld (%s)\n",
515 f, inet_ntoa(try));

--- 98 unchanged lines hidden (view full) ---

614 log_Printf(LogIPCP, "%s: LayerFinish.\n", fp->link->name);
615 throughput_stop(&ipcp->throughput);
616 throughput_log(&ipcp->throughput, LogIPCP, NULL);
617}
618
619void
620ipcp_CleanInterface(struct ipcp *ipcp)
621{
642 struct ifaliasreq ifra;
643 struct sockaddr_in *me, *peer;
644 int s;
622 struct iface *iface = ipcp->fsm.bundle->iface;
645
623
646 s = ID0socket(AF_INET, SOCK_DGRAM, 0);
647 if (s < 0) {
648 log_Printf(LogERROR, "ipcp_CleanInterface: socket: %s\n", strerror(errno));
649 return;
650 }
651
652 route_Clean(ipcp->fsm.bundle, ipcp->route);
653
624 route_Clean(ipcp->fsm.bundle, ipcp->route);
625
654 if (Enabled(ipcp->fsm.bundle, OPT_PROXY))
655 arp_ClearProxy(ipcp->fsm.bundle, ipcp->peer_ifip, s);
656
657 if (ipcp->my_ifip.s_addr != INADDR_ANY ||
658 ipcp->peer_ifip.s_addr != INADDR_ANY) {
659 memset(&ifra, '\0', sizeof ifra);
660 strncpy(ifra.ifra_name, ipcp->fsm.bundle->ifp.Name,
661 sizeof ifra.ifra_name - 1);
662 ifra.ifra_name[sizeof ifra.ifra_name - 1] = '\0';
663 me = (struct sockaddr_in *)&ifra.ifra_addr;
664 peer = (struct sockaddr_in *)&ifra.ifra_broadaddr;
665 me->sin_family = peer->sin_family = AF_INET;
666 me->sin_len = peer->sin_len = sizeof(struct sockaddr_in);
667 me->sin_addr = ipcp->my_ifip;
668 peer->sin_addr = ipcp->peer_ifip;
669 if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0)
670 log_Printf(LogERROR, "ipcp_CleanInterface: ioctl(SIOCDIFADDR): %s\n",
671 strerror(errno));
672 ipcp->my_ifip.s_addr = ipcp->peer_ifip.s_addr = INADDR_ANY;
626 if (iface->in_addrs && Enabled(ipcp->fsm.bundle, OPT_PROXY)) {
627 int s = ID0socket(AF_INET, SOCK_DGRAM, 0);
628 if (s < 0)
629 log_Printf(LogERROR, "ipcp_CleanInterface: socket: %s\n",
630 strerror(errno));
631 else {
632 arp_ClearProxy(ipcp->fsm.bundle, iface->in_addr[0].brd, s);
633 close(s);
634 }
673 }
674
635 }
636
675 close(s);
637 iface_inClear(ipcp->fsm.bundle->iface, IFACE_CLEAR_ALL);
676}
677
678static void
679IpcpLayerDown(struct fsm *fp)
680{
681 /* About to come down */
682 struct ipcp *ipcp = fsm2ipcp(fp);
683 const char *s;
684
638}
639
640static void
641IpcpLayerDown(struct fsm *fp)
642{
643 /* About to come down */
644 struct ipcp *ipcp = fsm2ipcp(fp);
645 const char *s;
646
685 s = inet_ntoa(ipcp->peer_ifip);
647 if (ipcp->fsm.bundle->iface->in_addrs)
648 s = inet_ntoa(ipcp->fsm.bundle->iface->in_addr[0].ifa);
649 else
650 s = "Interface configuration error !";
686 log_Printf(LogIPCP, "%s: LayerDown: %s\n", fp->link->name, s);
687
688 /*
689 * XXX this stuff should really live in the FSM. Our config should
690 * associate executable sections in files with events.
691 */
692 if (system_Select(fp->bundle, s, LINKDOWNFILE, NULL, NULL) < 0) {
693 if (bundle_GetLabel(fp->bundle)) {
694 if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle),
695 LINKDOWNFILE, NULL, NULL) < 0)
696 system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL);
697 } else
698 system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL);
699 }
700
651 log_Printf(LogIPCP, "%s: LayerDown: %s\n", fp->link->name, s);
652
653 /*
654 * XXX this stuff should really live in the FSM. Our config should
655 * associate executable sections in files with events.
656 */
657 if (system_Select(fp->bundle, s, LINKDOWNFILE, NULL, NULL) < 0) {
658 if (bundle_GetLabel(fp->bundle)) {
659 if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle),
660 LINKDOWNFILE, NULL, NULL) < 0)
661 system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL);
662 } else
663 system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL);
664 }
665
701 if (!(ipcp->fsm.bundle->phys_type.all & PHYS_AUTO))
702 ipcp_CleanInterface(ipcp);
703
704 ipcp_Setup(ipcp);
705}
706
707int
708ipcp_InterfaceUp(struct ipcp *ipcp)
709{
710 if (ipcp_SetIPaddress(ipcp->fsm.bundle, ipcp->my_ip, ipcp->peer_ip, 0) < 0) {
711 log_Printf(LogERROR, "ipcp_InterfaceUp: unable to set ip address\n");

--- 8 unchanged lines hidden (view full) ---

720 return 1;
721}
722
723static int
724IpcpLayerUp(struct fsm *fp)
725{
726 /* We're now up */
727 struct ipcp *ipcp = fsm2ipcp(fp);
666 ipcp_Setup(ipcp);
667}
668
669int
670ipcp_InterfaceUp(struct ipcp *ipcp)
671{
672 if (ipcp_SetIPaddress(ipcp->fsm.bundle, ipcp->my_ip, ipcp->peer_ip, 0) < 0) {
673 log_Printf(LogERROR, "ipcp_InterfaceUp: unable to set ip address\n");

--- 8 unchanged lines hidden (view full) ---

682 return 1;
683}
684
685static int
686IpcpLayerUp(struct fsm *fp)
687{
688 /* We're now up */
689 struct ipcp *ipcp = fsm2ipcp(fp);
728 char tbuff[100];
690 char tbuff[16];
729
730 log_Printf(LogIPCP, "%s: LayerUp.\n", fp->link->name);
691
692 log_Printf(LogIPCP, "%s: LayerUp.\n", fp->link->name);
731 snprintf(tbuff, sizeof tbuff, "myaddr = %s ", inet_ntoa(ipcp->my_ip));
732 log_Printf(LogIPCP, " %s hisaddr = %s\n", tbuff, inet_ntoa(ipcp->peer_ip));
693 snprintf(tbuff, sizeof tbuff, "%s", inet_ntoa(ipcp->my_ip));
694 log_Printf(LogIPCP, "myaddr %s hisaddr = %s\n",
695 tbuff, inet_ntoa(ipcp->peer_ip));
733
734 if (ipcp->peer_compproto >> 16 == PROTO_VJCOMP)
735 sl_compress_init(&ipcp->vj.cslc, (ipcp->peer_compproto >> 8) & 255);
736
737 if (!ipcp_InterfaceUp(ipcp))
738 return 0;
739
740 /*
741 * XXX this stuff should really live in the FSM. Our config should
742 * associate executable sections in files with events.
743 */
696
697 if (ipcp->peer_compproto >> 16 == PROTO_VJCOMP)
698 sl_compress_init(&ipcp->vj.cslc, (ipcp->peer_compproto >> 8) & 255);
699
700 if (!ipcp_InterfaceUp(ipcp))
701 return 0;
702
703 /*
704 * XXX this stuff should really live in the FSM. Our config should
705 * associate executable sections in files with events.
706 */
744 if (system_Select(fp->bundle, inet_ntoa(ipcp->my_ifip), LINKUPFILE,
745 NULL, NULL) < 0) {
707 if (system_Select(fp->bundle, tbuff, LINKUPFILE, NULL, NULL) < 0) {
746 if (bundle_GetLabel(fp->bundle)) {
747 if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle),
748 LINKUPFILE, NULL, NULL) < 0)
749 system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL);
750 } else
751 system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL);
752 }
753
754 log_DisplayPrompts();
755 return 1;
756}
757
758static int
708 if (bundle_GetLabel(fp->bundle)) {
709 if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle),
710 LINKUPFILE, NULL, NULL) < 0)
711 system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL);
712 } else
713 system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL);
714 }
715
716 log_DisplayPrompts();
717 return 1;
718}
719
720static int
759AcceptableAddr(struct in_range *prange, struct in_addr ipaddr)
721AcceptableAddr(const struct in_range *prange, struct in_addr ipaddr)
760{
761 /* Is the given IP in the given range ? */
762 return (prange->ipaddr.s_addr & prange->mask.s_addr) ==
763 (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr;
764}
765
766static void
767IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
768 struct fsm_decode *dec)
769{
770 /* Deal with incoming PROTO_IPCP */
722{
723 /* Is the given IP in the given range ? */
724 return (prange->ipaddr.s_addr & prange->mask.s_addr) ==
725 (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr;
726}
727
728static void
729IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
730 struct fsm_decode *dec)
731{
732 /* Deal with incoming PROTO_IPCP */
733 struct iface *iface = fp->bundle->iface;
771 struct ipcp *ipcp = fsm2ipcp(fp);
734 struct ipcp *ipcp = fsm2ipcp(fp);
772 int type, length;
735 int type, length, gotdns, gotdnsnak, n;
773 u_int32_t compproto;
774 struct compreq *pcomp;
775 struct in_addr ipaddr, dstipaddr, have_ip, dns[2], dnsnak[2];
776 char tbuff[100], tbuff2[100];
736 u_int32_t compproto;
737 struct compreq *pcomp;
738 struct in_addr ipaddr, dstipaddr, have_ip, dns[2], dnsnak[2];
739 char tbuff[100], tbuff2[100];
777 int gotdns, gotdnsnak;
778
779 gotdns = 0;
780 gotdnsnak = 0;
781 dnsnak[0].s_addr = dnsnak[1].s_addr = INADDR_ANY;
782
783 while (plen >= sizeof(struct fsmconfig)) {
784 type = *cp;
785 length = cp[1];

--- 19 unchanged lines hidden (view full) ---

805 case MODE_REQ:
806 if (iplist_isvalid(&ipcp->cfg.peer_list)) {
807 if (ipaddr.s_addr == INADDR_ANY ||
808 iplist_ip2pos(&ipcp->cfg.peer_list, ipaddr) < 0 ||
809 ipcp_SetIPaddress(fp->bundle, ipcp->cfg.my_range.ipaddr,
810 ipaddr, 1)) {
811 log_Printf(LogIPCP, "%s: Address invalid or already in use\n",
812 inet_ntoa(ipaddr));
740
741 gotdns = 0;
742 gotdnsnak = 0;
743 dnsnak[0].s_addr = dnsnak[1].s_addr = INADDR_ANY;
744
745 while (plen >= sizeof(struct fsmconfig)) {
746 type = *cp;
747 length = cp[1];

--- 19 unchanged lines hidden (view full) ---

767 case MODE_REQ:
768 if (iplist_isvalid(&ipcp->cfg.peer_list)) {
769 if (ipaddr.s_addr == INADDR_ANY ||
770 iplist_ip2pos(&ipcp->cfg.peer_list, ipaddr) < 0 ||
771 ipcp_SetIPaddress(fp->bundle, ipcp->cfg.my_range.ipaddr,
772 ipaddr, 1)) {
773 log_Printf(LogIPCP, "%s: Address invalid or already in use\n",
774 inet_ntoa(ipaddr));
813 if (iplist_ip2pos(&ipcp->cfg.peer_list, ipcp->peer_ifip) >= 0)
814 /*
815 * If we've already got a valid address configured for the peer
816 * (in AUTO mode), try NAKing with that so that we don't
817 * have to upset things too much.
818 */
819 ipcp->peer_ip = ipcp->peer_ifip;
820 else
775 /*
776 * If we've already had a valid address configured for the peer,
777 * try NAKing with that so that we don't have to upset things
778 * too much.
779 */
780 for (n = 0; n < iface->in_addrs; n++)
781 if (iplist_ip2pos(&ipcp->cfg.peer_list, iface->in_addr[n].brd)
782 >=0) {
783 ipcp->peer_ip = iface->in_addr[n].brd;
784 break;
785 }
786
787 if (n == iface->in_addrs)
821 /* Just pick an IP number from our list */
822 ipcp->peer_ip = ChooseHisAddr
823 (fp->bundle, ipcp->cfg.my_range.ipaddr);
824
825 if (ipcp->peer_ip.s_addr == INADDR_ANY) {
826 memcpy(dec->rejend, cp, length);
827 dec->rejend += length;
828 } else {
829 memcpy(dec->nakend, cp, 2);
788 /* Just pick an IP number from our list */
789 ipcp->peer_ip = ChooseHisAddr
790 (fp->bundle, ipcp->cfg.my_range.ipaddr);
791
792 if (ipcp->peer_ip.s_addr == INADDR_ANY) {
793 memcpy(dec->rejend, cp, length);
794 dec->rejend += length;
795 } else {
796 memcpy(dec->nakend, cp, 2);
830 memcpy(dec->nakend+2, &ipcp->peer_ip.s_addr, length - 2);
797 memcpy(dec->nakend + 2, &ipcp->peer_ip.s_addr, length - 2);
831 dec->nakend += length;
832 }
833 break;
834 }
835 } else if (!AcceptableAddr(&ipcp->cfg.peer_range, ipaddr)) {
836 /*
837 * If destination address is not acceptable, NAK with what we
838 * want to use.
839 */
840 memcpy(dec->nakend, cp, 2);
798 dec->nakend += length;
799 }
800 break;
801 }
802 } else if (!AcceptableAddr(&ipcp->cfg.peer_range, ipaddr)) {
803 /*
804 * If destination address is not acceptable, NAK with what we
805 * want to use.
806 */
807 memcpy(dec->nakend, cp, 2);
841 if ((ipcp->peer_ifip.s_addr & ipcp->cfg.peer_range.mask.s_addr) ==
842 (ipcp->cfg.peer_range.ipaddr.s_addr &
843 ipcp->cfg.peer_range.mask.s_addr))
844 /* We prefer the already-configured address */
845 memcpy(dec->nakend+2, &ipcp->peer_ifip.s_addr, length - 2);
846 else
847 memcpy(dec->nakend+2, &ipcp->peer_ip.s_addr, length - 2);
808 for (n = 0; n < iface->in_addrs; n++)
809 if ((iface->in_addr[n].brd.s_addr &
810 ipcp->cfg.peer_range.mask.s_addr)
811 == (ipcp->cfg.peer_range.ipaddr.s_addr &
812 ipcp->cfg.peer_range.mask.s_addr)) {
813 /* We prefer the already-configured address */
814 memcpy(dec->nakend + 2, &iface->in_addr[n].brd.s_addr,
815 length - 2);
816 break;
817 }
818
819 if (n == iface->in_addrs)
820 memcpy(dec->nakend + 2, &ipcp->peer_ip.s_addr, length - 2);
821
848 dec->nakend += length;
849 break;
850 }
851 ipcp->peer_ip = ipaddr;
852 memcpy(dec->ackend, cp, length);
853 dec->ackend += length;
854 break;
822 dec->nakend += length;
823 break;
824 }
825 ipcp->peer_ip = ipaddr;
826 memcpy(dec->ackend, cp, length);
827 dec->ackend += length;
828 break;
829
855 case MODE_NAK:
856 if (AcceptableAddr(&ipcp->cfg.my_range, ipaddr)) {
857 /* Use address suggested by peer */
858 snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff,
859 inet_ntoa(ipcp->my_ip));
860 log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr));
861 ipcp->my_ip = ipaddr;
862 } else {
863 log_Printf(log_IsKept(LogIPCP) ? LogIPCP : LogPHASE,
864 "%s: Unacceptable address!\n", inet_ntoa(ipaddr));
865 fsm_Close(&ipcp->fsm);
866 }
867 break;
830 case MODE_NAK:
831 if (AcceptableAddr(&ipcp->cfg.my_range, ipaddr)) {
832 /* Use address suggested by peer */
833 snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff,
834 inet_ntoa(ipcp->my_ip));
835 log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr));
836 ipcp->my_ip = ipaddr;
837 } else {
838 log_Printf(log_IsKept(LogIPCP) ? LogIPCP : LogPHASE,
839 "%s: Unacceptable address!\n", inet_ntoa(ipaddr));
840 fsm_Close(&ipcp->fsm);
841 }
842 break;
843
868 case MODE_REJ:
869 ipcp->peer_reject |= (1 << type);
870 break;
871 }
872 break;
844 case MODE_REJ:
845 ipcp->peer_reject |= (1 << type);
846 break;
847 }
848 break;
849
873 case TY_COMPPROTO:
874 memcpy(&compproto, cp + 2, 4);
875 log_Printf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto));
876
877 switch (mode_type) {
878 case MODE_REQ:
879 if (!IsAccepted(ipcp->cfg.vj.neg)) {
880 memcpy(dec->rejend, cp, length);

--- 34 unchanged lines hidden (view full) ---

915 break;
916 default:
917 memcpy(dec->rejend, cp, length);
918 dec->rejend += length;
919 break;
920 }
921 }
922 break;
850 case TY_COMPPROTO:
851 memcpy(&compproto, cp + 2, 4);
852 log_Printf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto));
853
854 switch (mode_type) {
855 case MODE_REQ:
856 if (!IsAccepted(ipcp->cfg.vj.neg)) {
857 memcpy(dec->rejend, cp, length);

--- 34 unchanged lines hidden (view full) ---

892 break;
893 default:
894 memcpy(dec->rejend, cp, length);
895 dec->rejend += length;
896 break;
897 }
898 }
899 break;
900
923 case MODE_NAK:
924 log_Printf(LogIPCP, "%s changing compproto: %08x --> %08x\n",
925 tbuff, ipcp->my_compproto, compproto);
926 ipcp->my_compproto = compproto;
927 break;
901 case MODE_NAK:
902 log_Printf(LogIPCP, "%s changing compproto: %08x --> %08x\n",
903 tbuff, ipcp->my_compproto, compproto);
904 ipcp->my_compproto = compproto;
905 break;
906
928 case MODE_REJ:
929 ipcp->peer_reject |= (1 << type);
930 break;
931 }
932 break;
907 case MODE_REJ:
908 ipcp->peer_reject |= (1 << type);
909 break;
910 }
911 break;
912
933 case TY_IPADDRS: /* RFC1172 */
934 memcpy(&ipaddr.s_addr, cp + 2, 4);
935 memcpy(&dstipaddr.s_addr, cp + 6, 4);
936 snprintf(tbuff2, sizeof tbuff2, "%s %s,", tbuff, inet_ntoa(ipaddr));
937 log_Printf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr));
938
939 switch (mode_type) {
940 case MODE_REQ:
941 ipcp->peer_ip = ipaddr;
942 ipcp->my_ip = dstipaddr;
943 memcpy(dec->ackend, cp, length);
944 dec->ackend += length;
945 break;
913 case TY_IPADDRS: /* RFC1172 */
914 memcpy(&ipaddr.s_addr, cp + 2, 4);
915 memcpy(&dstipaddr.s_addr, cp + 6, 4);
916 snprintf(tbuff2, sizeof tbuff2, "%s %s,", tbuff, inet_ntoa(ipaddr));
917 log_Printf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr));
918
919 switch (mode_type) {
920 case MODE_REQ:
921 ipcp->peer_ip = ipaddr;
922 ipcp->my_ip = dstipaddr;
923 memcpy(dec->ackend, cp, length);
924 dec->ackend += length;
925 break;
926
946 case MODE_NAK:
947 snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s", tbuff,
948 inet_ntoa(ipcp->my_ip));
949 log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr));
950 ipcp->my_ip = ipaddr;
951 ipcp->peer_ip = dstipaddr;
952 break;
927 case MODE_NAK:
928 snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s", tbuff,
929 inet_ntoa(ipcp->my_ip));
930 log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr));
931 ipcp->my_ip = ipaddr;
932 ipcp->peer_ip = dstipaddr;
933 break;
934
953 case MODE_REJ:
954 ipcp->peer_reject |= (1 << type);
955 break;
956 }
957 break;
958
959 case TY_PRIMARY_DNS: /* DNS negotiation (rfc1877) */
960 case TY_SECONDARY_DNS:

--- 29 unchanged lines hidden (view full) ---

990 /*
991 * Otherwise they have it right (this time) so we send a ack packet
992 * back confirming it... end of story
993 */
994 memcpy(dec->ackend, cp, length);
995 dec->ackend += length;
996 }
997 break;
935 case MODE_REJ:
936 ipcp->peer_reject |= (1 << type);
937 break;
938 }
939 break;
940
941 case TY_PRIMARY_DNS: /* DNS negotiation (rfc1877) */
942 case TY_SECONDARY_DNS:

--- 29 unchanged lines hidden (view full) ---

972 /*
973 * Otherwise they have it right (this time) so we send a ack packet
974 * back confirming it... end of story
975 */
976 memcpy(dec->ackend, cp, length);
977 dec->ackend += length;
978 }
979 break;
980
998 case MODE_NAK: /* what does this mean?? */
999 if (IsEnabled(ipcp->cfg.ns.dns_neg)) {
1000 gotdnsnak = 1;
1001 memcpy(&dnsnak[type == TY_PRIMARY_DNS ? 0 : 1].s_addr, cp + 2, 4);
1002 }
1003 break;
981 case MODE_NAK: /* what does this mean?? */
982 if (IsEnabled(ipcp->cfg.ns.dns_neg)) {
983 gotdnsnak = 1;
984 memcpy(&dnsnak[type == TY_PRIMARY_DNS ? 0 : 1].s_addr, cp + 2, 4);
985 }
986 break;
987
1004 case MODE_REJ: /* Can't do much, stop asking */
1005 ipcp->peer_reject |= (1 << (type - TY_ADJUST_NS));
1006 break;
1007 }
1008 break;
1009
1010 case TY_PRIMARY_NBNS: /* M$ NetBIOS nameserver hack (rfc1877) */
1011 case TY_SECONDARY_NBNS:

--- 17 unchanged lines hidden (view full) ---

1029 memcpy(dec->nakend, cp, 2);
1030 memcpy(dec->nakend+2, &have_ip.s_addr, length);
1031 dec->nakend += length;
1032 } else {
1033 memcpy(dec->ackend, cp, length);
1034 dec->ackend += length;
1035 }
1036 break;
988 case MODE_REJ: /* Can't do much, stop asking */
989 ipcp->peer_reject |= (1 << (type - TY_ADJUST_NS));
990 break;
991 }
992 break;
993
994 case TY_PRIMARY_NBNS: /* M$ NetBIOS nameserver hack (rfc1877) */
995 case TY_SECONDARY_NBNS:

--- 17 unchanged lines hidden (view full) ---

1013 memcpy(dec->nakend, cp, 2);
1014 memcpy(dec->nakend+2, &have_ip.s_addr, length);
1015 dec->nakend += length;
1016 } else {
1017 memcpy(dec->ackend, cp, length);
1018 dec->ackend += length;
1019 }
1020 break;
1021
1037 case MODE_NAK:
1038 log_Printf(LogIPCP, "MS NBNS req %d - NAK??\n", type);
1039 break;
1022 case MODE_NAK:
1023 log_Printf(LogIPCP, "MS NBNS req %d - NAK??\n", type);
1024 break;
1025
1040 case MODE_REJ:
1041 log_Printf(LogIPCP, "MS NBNS req %d - REJ??\n", type);
1042 break;
1043 }
1044 break;
1045
1046 default:
1047 if (mode_type != MODE_NOP) {

--- 63 unchanged lines hidden (view full) ---

1111 return 0;
1112 }
1113 } else if (ParseAddr(ipcp, 1, &hisaddr, &ipcp->cfg.peer_range.ipaddr,
1114 &ipcp->cfg.peer_range.mask,
1115 &ipcp->cfg.peer_range.width) != 0) {
1116 ipcp->peer_ip.s_addr = ipcp->cfg.peer_range.ipaddr.s_addr;
1117
1118 if (setaddr && ipcp_SetIPaddress(bundle, ipcp->cfg.my_range.ipaddr,
1026 case MODE_REJ:
1027 log_Printf(LogIPCP, "MS NBNS req %d - REJ??\n", type);
1028 break;
1029 }
1030 break;
1031
1032 default:
1033 if (mode_type != MODE_NOP) {

--- 63 unchanged lines hidden (view full) ---

1097 return 0;
1098 }
1099 } else if (ParseAddr(ipcp, 1, &hisaddr, &ipcp->cfg.peer_range.ipaddr,
1100 &ipcp->cfg.peer_range.mask,
1101 &ipcp->cfg.peer_range.width) != 0) {
1102 ipcp->peer_ip.s_addr = ipcp->cfg.peer_range.ipaddr.s_addr;
1103
1104 if (setaddr && ipcp_SetIPaddress(bundle, ipcp->cfg.my_range.ipaddr,
1119 ipcp->cfg.peer_range.ipaddr, 0) < 0) {
1120 ipcp->cfg.my_range.ipaddr.s_addr = INADDR_ANY;
1121 ipcp->cfg.peer_range.ipaddr.s_addr = INADDR_ANY;
1105 ipcp->cfg.peer_range.ipaddr, 0) < 0)
1122 return 0;
1106 return 0;
1123 }
1124 } else
1125 return 0;
1126
1127 return 1;
1128}
1107 } else
1108 return 0;
1109
1110 return 1;
1111}