Beispiel #1
0
Datei: ip.c Projekt: vstakhov/mpd
void 
in_addrtou_range(const struct in_addr *src, u_char width, struct u_range *dst)
{
	u_rangeclear(dst);
	in_addrtou_addr(src, &dst->addr);
	dst->width = width;
}
Beispiel #2
0
static void
IpcpUnConfigure(Fsm fp)
{
    Bund 	b = (Bund)fp->arg;
    IpcpState	const ipcp = &b->ipcp;
  
    if (ipcp->self_ippool_used) {
	struct u_addr ip;
	in_addrtou_addr(&ipcp->want_addr, &ip);
	IPPoolFree(ipcp->conf.self_ippool, &ip);
	ipcp->self_ippool_used = 0;
    }
    if (b->params.ippool_used) {
	struct u_addr ip;
	in_addrtou_addr(&ipcp->peer_addr, &ip);
	IPPoolFree(b->params.ippool, &ip);
	b->params.ippool_used = 0;
    } else if (ipcp->ippool_used) {
	struct u_addr ip;
	in_addrtou_addr(&ipcp->peer_addr, &ip);
	IPPoolFree(ipcp->conf.ippool, &ip);
	ipcp->ippool_used = 0;
    }
}
Beispiel #3
0
static void
IpcpDecodeConfig(Fsm fp, FsmOption list, int num, int mode)
{
    Bund 	b = (Bund)fp->arg;
  IpcpState		const ipcp = &b->ipcp;
  struct in_addr	*wantip, *peerip;
  int			k;

  /* Decode each config option */
  for (k = 0; k < num; k++) {
    FsmOption	const opt = &list[k];
    FsmOptInfo	const oi = FsmFindOptInfo(gIpcpConfOpts, opt->type);

    if (!oi) {
      Log(LG_IPCP, ("[%s]   UNKNOWN[%d] len=%d", b->name, opt->type, opt->len));
      if (mode == MODE_REQ)
	FsmRej(fp, opt);
      continue;
    }
    if (!oi->supported) {
      Log(LG_IPCP, ("[%s]   %s", b->name, oi->name));
      if (mode == MODE_REQ) {
	Log(LG_IPCP, ("[%s]     Not supported", b->name));
	FsmRej(fp, opt);
      }
      continue;
    }
    if (opt->len < oi->minLen + 2 || opt->len > oi->maxLen + 2) {
      Log(LG_IPCP, ("[%s]   %s", b->name, oi->name));
      if (mode == MODE_REQ) {
	Log(LG_IPCP, ("[%s]     bogus len=%d", b->name, opt->len));
	FsmRej(fp, opt);
      }
      continue;
    }
    switch (opt->type) {
      case TY_IPADDR:
	{
	  struct in_addr	ip;
	  struct u_addr		tmp;

	  memcpy(&ip, opt->data, 4);
	  in_addrtou_addr(&ip, &tmp);
	  Log(LG_IPCP, ("[%s]   %s %s", b->name, oi->name, inet_ntoa(ip)));
	  switch (mode) {
	    case MODE_REQ:
	      if (!IpAddrInRange(&ipcp->peer_allow, &tmp) || !ip.s_addr) {
		if (ipcp->peer_addr.s_addr == 0)
		  Log(LG_IPCP, ("[%s]     no IP address available for peer!", b->name));
		if (Enabled(&ipcp->conf.options, IPCP_CONF_PRETENDIP)) {
		  Log(LG_IPCP, ("[%s]     pretending that %s is OK, will ignore",
		      b->name, inet_ntoa(ip)));
		  ipcp->peer_addr = ip;
		  FsmAck(fp, opt);
		  break;
		}
		memcpy(opt->data, &ipcp->peer_addr, 4);
		Log(LG_IPCP, ("[%s]     NAKing with %s", b->name, inet_ntoa(ipcp->peer_addr)));
		FsmNak(fp, opt);
		break;
	      }
	      Log(LG_IPCP, ("[%s]     %s is OK", b->name, inet_ntoa(ip)));
	      ipcp->peer_addr = ip;
	      FsmAck(fp, opt);
	      break;
	    case MODE_NAK:
	      {
		if (IpAddrInRange(&ipcp->self_allow, &tmp)) {
		  Log(LG_IPCP, ("[%s]     %s is OK", b->name, inet_ntoa(ip)));
		  ipcp->want_addr = ip;
		} else if (Enabled(&ipcp->conf.options, IPCP_CONF_PRETENDIP)) {
		  Log(LG_IPCP, ("[%s]     pretending that %s is OK, will ignore",
		      b->name, inet_ntoa(ip)));
		  ipcp->want_addr = ip;
		} else
		  Log(LG_IPCP, ("[%s]     %s is unacceptable", b->name, inet_ntoa(ip)));
	      }
	      break;
	    case MODE_REJ:
	      IPCP_PEER_REJ(ipcp, opt->type);
	      if (ipcp->want_addr.s_addr == 0)
		Log(LG_IPCP, ("[%s]     Problem: I need an IP address!", b->name));
	      break;
	  }
	}
	break;

#ifdef USE_NG_VJC
      case TY_COMPPROTO:
	{
	  struct ipcpvjcomp	vj;

	  memcpy(&vj, opt->data, sizeof(vj));
	  Log(LG_IPCP, ("[%s]   %s %s, %d comp. channels, %s comp-cid",
	    b->name, oi->name, ProtoName(ntohs(vj.proto)),
	    vj.maxchan + 1, vj.compcid ? "allow" : "no"));
	  switch (mode) {
	    case MODE_REQ:
	      if (!Acceptable(&ipcp->conf.options, IPCP_CONF_VJCOMP) && 
	    	  !b->params.vjc_enable) {
		FsmRej(fp, opt);
		break;
	      }
	      if (ntohs(vj.proto) == PROTO_VJCOMP
		  && vj.maxchan <= IPCP_VJCOMP_MAX_MAXCHAN
		  && vj.maxchan >= IPCP_VJCOMP_MIN_MAXCHAN) {
		ipcp->peer_comp = vj;
		FsmAck(fp, opt);
		break;
	      }
	      vj.proto = htons(PROTO_VJCOMP);
	      vj.maxchan = IPCP_VJCOMP_MAX_MAXCHAN;
	      vj.compcid = 0;
	      memcpy(opt->data, &vj, sizeof(vj));
	      FsmNak(fp, opt);
	      break;
	    case MODE_NAK:
	      if (ntohs(vj.proto) != PROTO_VJCOMP) {
		Log(LG_IPCP, ("[%s]     Can't accept proto 0x%04x",
		  b->name, (u_short) ntohs(vj.proto)));
		break;
	      }
	      if (vj.maxchan != ipcp->want_comp.maxchan) {
		if (vj.maxchan <= IPCP_VJCOMP_MAX_MAXCHAN
		    && vj.maxchan >= IPCP_VJCOMP_MIN_MAXCHAN) {
		  Log(LG_IPCP, ("[%s]     Adjusting # compression channels", b->name));
		  ipcp->want_comp.maxchan = vj.maxchan;
		} else {
		  Log(LG_IPCP, ("[%s]     Can't handle %d maxchan", b->name, vj.maxchan));
		}
	      }
	      if (vj.compcid) {
		Log(LG_IPCP, ("[%s]     Can't accept comp-cid", b->name));
		break;
	      }
	      break;
	    case MODE_REJ:
	      IPCP_PEER_REJ(ipcp, opt->type);
	      ipcp->want_comp.proto = 0;
	      break;
	  }
	}
	break;
#endif /* USE_NG_VJC */

      case TY_PRIMARYDNS:
        if (b->params.peer_dns[0].s_addr != 0)
	    peerip = &b->params.peer_dns[0];
	else
	    peerip = &ipcp->conf.peer_dns[0];
	wantip = &ipcp->want_dns[0];
	goto doDnsNbns;
      case TY_PRIMARYNBNS:
        if (b->params.peer_nbns[0].s_addr != 0)
	    peerip = &b->params.peer_nbns[0];
	else
	    peerip = &ipcp->conf.peer_nbns[0];
	wantip = &ipcp->want_nbns[0];
	goto doDnsNbns;
      case TY_SECONDARYDNS:
        if (b->params.peer_dns[1].s_addr != 0)
	    peerip = &b->params.peer_dns[1];
	else
	    peerip = &ipcp->conf.peer_dns[1];
	wantip = &ipcp->want_dns[1];
	goto doDnsNbns;
      case TY_SECONDARYNBNS:
        if (b->params.peer_nbns[1].s_addr != 0)
	    peerip = &b->params.peer_nbns[1];
	else
	    peerip = &ipcp->conf.peer_nbns[1];
	wantip = &ipcp->want_nbns[1];
doDnsNbns:
	{
	  struct in_addr	hisip;

	  memcpy(&hisip, opt->data, 4);
	  Log(LG_IPCP, ("[%s]   %s %s", b->name, oi->name, inet_ntoa(hisip)));
	  switch (mode) {
	    case MODE_REQ:
	      if (hisip.s_addr == 0) {		/* he's asking for one */
		if (peerip->s_addr == 0) {	/* we don't got one */
		  FsmRej(fp, opt);
		  break;
		}
		Log(LG_IPCP, ("[%s]     NAKing with %s", b->name, inet_ntoa(*peerip)));
		memcpy(opt->data, peerip, sizeof(*peerip));
		FsmNak(fp, opt);		/* we got one for him */
		break;
	      }
	      FsmAck(fp, opt);			/* he knows what he wants */
	      break;
	    case MODE_NAK:	/* we asked for his server, he's telling us */
	      *wantip = hisip;
	      break;
	    case MODE_REJ:	/* we asked for his server, he's ignorant */
	      IPCP_PEER_REJ(ipcp, opt->type);
	      break;
	  }
	}
	break;

      default:
	assert(0);
    }
  }
}
Beispiel #4
0
static void
IpcpLayerUp(Fsm fp)
{
    Bund 			b = (Bund)fp->arg;
    IpcpState			const ipcp = &b->ipcp;
    char			ipbuf[20];
#ifdef USE_NG_VJC
    char			path[NG_PATHSIZ];
    struct ngm_vjc_config	vjc;
#endif
    struct u_addr		tmp;

    /* Determine actual address we'll use for ourselves */
    in_addrtou_addr(&ipcp->want_addr, &tmp);
    if (!IpAddrInRange(&ipcp->self_allow, &tmp)) {
	Log(LG_IPCP, ("[%s]   Note: ignoring negotiated %s IP %s,",
    	    b->name, "self", inet_ntoa(ipcp->want_addr)));
	u_addrtoin_addr(&ipcp->self_allow.addr, &ipcp->want_addr);
	Log(LG_IPCP, ("[%s]        using %s instead.",
    	    b->name, inet_ntoa(ipcp->want_addr)));
    }

    /* Determine actual address we'll use for peer */
    in_addrtou_addr(&ipcp->peer_addr, &tmp);
    if (!IpAddrInRange(&ipcp->peer_allow, &tmp)
    	    && !u_addrempty(&ipcp->peer_allow.addr)) {
	Log(LG_IPCP, ("[%s]   Note: ignoring negotiated %s IP %s,",
    	    b->name, "peer", inet_ntoa(ipcp->peer_addr)));
	u_addrtoin_addr(&ipcp->peer_allow.addr, &ipcp->peer_addr);
	Log(LG_IPCP, ("[%s]        using %s instead.",
    	    b->name, inet_ntoa(ipcp->peer_addr)));
    }

    /* Report */
    strlcpy(ipbuf, inet_ntoa(ipcp->peer_addr), sizeof(ipbuf));
    Log(LG_IPCP, ("[%s]   %s -> %s", b->name, inet_ntoa(ipcp->want_addr), ipbuf));

#ifdef USE_NG_VJC
    memset(&vjc, 0, sizeof(vjc));
    if (ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP || 
	    ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP) {
  
	IpcpNgInitVJ(b);

	/* Configure VJ compression node */
	vjc.enableComp = ntohs(ipcp->peer_comp.proto) == PROTO_VJCOMP;
	vjc.enableDecomp = ntohs(ipcp->want_comp.proto) == PROTO_VJCOMP;
	vjc.maxChannel = ipcp->peer_comp.maxchan;
	vjc.compressCID = ipcp->peer_comp.compcid;
        snprintf(path, sizeof(path), "[%x]:%s", b->nodeID, NG_PPP_HOOK_VJC_IP);
	if (NgSendMsg(gLinksCsock, path,
    		NGM_VJC_COOKIE, NGM_VJC_SET_CONFIG, &vjc, sizeof(vjc)) < 0) {
	    Perror("[%s] can't config %s node", b->name, NG_VJC_NODE_TYPE);
	}
    }
#endif /* USE_NG_VJC */

    /* Enable IP packets in the PPP node */
    b->pppConfig.bund.enableIP = 1;
#ifdef USE_NG_VJC
    b->pppConfig.bund.enableVJCompression = vjc.enableComp;
    b->pppConfig.bund.enableVJDecompression = vjc.enableDecomp;
#endif
    NgFuncSetConfig(b);

    BundNcpsJoin(b, NCP_IPCP);
}