Example #1
0
/*
 * ipcp_ackci - Ack our CIs.
 * Called by fsm_rconfack, Receive Configure ACK.
 *
 * Returns:
 *	0 - Ack was bad.
 *	1 - Ack was good.
 */
static int
ipcp_ackci(
    fsm *f,
    u_char *p,
    int len)
{
    ipcp_options *go = &ipcp_gotoptions[f->unit];
    u_short cilen, citype, cishort;
    uint32_t cilong;
    u_char cimaxslotindex, cicflag;

    /*
     * CIs must be in exactly the same order that we sent...
     * Check packet length and CI length at each step.
     * If we find any deviations, then this packet is bad.
     */

#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
    if (neg) { \
	int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
	if ((len -= vjlen) < 0) \
	    goto bad; \
	GETCHAR(citype, p); \
	GETCHAR(cilen, p); \
	if (cilen != vjlen || \
	    citype != opt)  \
	    goto bad; \
	GETSHORT(cishort, p); \
	if (cishort != val) \
	    goto bad; \
	if (!old) { \
	    GETCHAR(cimaxslotindex, p); \
	    if (cimaxslotindex != maxslotindex) \
		goto bad; \
	    GETCHAR(cicflag, p); \
	    if (cicflag != cflag) \
		goto bad; \
	} \
    }

#define ACKCIADDR(opt, neg, old, val1, val2) \
    if (neg) { \
	int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
	uint32_t l; \
	if ((len -= addrlen) < 0) \
	    goto bad; \
	GETCHAR(citype, p); \
	GETCHAR(cilen, p); \
	if (cilen != addrlen || \
	    citype != opt) \
	    goto bad; \
	GETLONG(l, p); \
	cilong = htonl(l); \
	if (val1 != cilong) \
	    goto bad; \
	if (old) { \
	    GETLONG(l, p); \
	    cilong = htonl(l); \
	    if (val2 != cilong) \
		goto bad; \
	} \
    }

#define ACKCIDNS(opt, neg, addr) \
    if (neg) { \
	uint32_t l; \
	if ((len -= CILEN_ADDR) < 0) \
	    goto bad; \
	GETCHAR(citype, p); \
	GETCHAR(cilen, p); \
	if (cilen != CILEN_ADDR || citype != opt) \
	    goto bad; \
	GETLONG(l, p); \
	cilong = htonl(l); \
	if (addr != cilong) \
	    goto bad; \
    }

    ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
	      go->old_addrs, go->ouraddr, go->hisaddr);

    ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
	    go->maxslotindex, go->cflag);

    ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);

    ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);

    /*
     * If there are any remaining CIs, then this packet is bad.
     */
    if (len != 0)
	goto bad;
    return (1);

bad:
    IPCPDEBUG(("ipcp_ackci: received bad Ack!"));
    return (0);
}
Example #2
0
//******************************************************************************
//	 			Parse DNS address from ipconfig options
//******************************************************************************
Boolean Capi2ReadDnsSrv( PCHProtConfig_t *ipcnfg,
						   u_long* primaryDns1,
						   u_long* secDns1,
						   u_long* primaryDns2,
						   u_long* secDns2)        
{                                                                         
	u_char *input;                                                          
	u_char code, id, len_pid;
	u_short protocol;
	int len, t_len;               				  
	int i=0;
    int type, templ;							 
	u_long DNSsrvr;				
	u_long l;
	
	*primaryDns1 = 0;
	*secDns1 = 0;
	*primaryDns2 = 0;
	*secDns2 = 0;

	IPCPDEBUG(("ReadDnsSrv, read dns_servers"));
	/* if option length == 2, no option data */
	if (ipcnfg->length ==  0)                                 
    {                                                                     
		IPCPDEBUG(("Network ignored protocol options"));                  
		/* (Not an error, network does not want to bother) */
		return TRUE;                                                           
    }                                                                     
                                                                          
	len = 0;                                                              
	if (( ipcnfg->options[len++] & 0x83 ) == 0x81)	  	                  
    {                                                                     
		IPCPDEBUG(("Bad protocol config option"));                        
		return FALSE;                                                           
    }                                                                     
                                                                          
	t_len = len;                                                          
	while ( t_len < (ipcnfg->length) )                      
    {                                                                     
		input = (u_char *) &ipcnfg->options[t_len];  	                  
        GETSHORT(protocol, input);
        GETCHAR(len_pid, input);
        GETCHAR(code, input);
        GETCHAR(id, input);
        GETSHORT(len, input);
		switch (protocol)				                                  
    	{									                              
			/* Check LCP option from the Network */
			case PPP_LCP:			   
				break;                                                      

			/* Check IPCP option from the Network */
			case PPP_IPCP:
				if ( code == CONFREQ )
                {
                	IPCPDEBUG((" ReadOptions: CONFREQ"));
					i=0;
					while (i<(len-4))
                    {
   						GETCHAR(type, input);     			//RFC 1661, this is option type
   						GETCHAR(templ, input);		  		//RFC 1661, next byte is length
      					GETLONG(l, input);					//read but don't use
						i += templ;
					}
				}
				else if ( code == CONFACK || code == CONFNAK )													
                {	
                	IPCPDEBUG((" ReadOptions: CONFACK or CONFNAK"));
					
					i=0;
					while (i<(len-4))
                    {
   						GETCHAR(type, input);     //RFC 1661, this is option type
   						GETCHAR(templ, input);		  //RFC 1661, next byte is length
						switch (type)
                        {
							case CI_ADDR:
      							GETLONG(l, input);
								IPCPDEBUG(("CI_ADDR"));
								break;
							case CI_DNSADDR_PRI:
      							GETLONG(l, input);
								DNSsrvr = htonl(l);
								*primaryDns1 = DNSsrvr;
   								IPCPDEBUG(("CI_DNSADDR_PRI =%x", DNSsrvr));
								break;
						
							case (CI_DNSADDR_PRI+1):
      							GETLONG(l, input);
								DNSsrvr = htonl(l);
								*primaryDns2 = DNSsrvr;
   								IPCPDEBUG(("CI_DNSADDR_PRI =%x", DNSsrvr));
								break;
						
							case CI_DNSADDR_SEC:
      							GETLONG(l, input);
								DNSsrvr = htonl(l);
								*secDns1 = DNSsrvr;
   								IPCPDEBUG(("CI_DNSADDR_SEC"));
								break;
						
							case (CI_DNSADDR_SEC+1):
      							GETLONG(l, input);
								DNSsrvr = htonl(l);
								*secDns2 = DNSsrvr;
   								IPCPDEBUG(("CI_DNSADDR_SEC"));
								break;	  
							default:
								break;
                        }
						i += templ;

                    }
                }	
				else	/* Network had rejected */
                {
					while(i<(len-4))
                    {
   						GETCHAR(type, input);
   						GETCHAR(templ, input);								 
						switch (type)
                        {
							case CI_DNSADDR_PRI:
								IPCPDEBUG(("CI_DNSADDR_PRI rejected"));
								break;
						
							case (CI_DNSADDR_PRI+1):
								IPCPDEBUG(("CI_DNSADDR_PRI+1 rejected"));
								break;
						
							case CI_DNSADDR_SEC:
								IPCPDEBUG(("CI_DNSADDR_SEC rejected"));
								break;
						
							case (CI_DNSADDR_SEC+1):			 // Not supported
								IPCPDEBUG(("CI_DNSADDR_SEC+1 rejected"));
								break;	  
							default:
								break;
                        }
						i += templ;
                    }
					IPCPDEBUG((" ReadOptions: IPCP REJed"));	
                }	
				break;
			default:
				break;
    	}
	   	t_len += (len + 3);
     }                                                                                                            

	return TRUE;                                                           
}
Example #3
0
/*
 * ipcp_nakci - Peer has sent a NAK for some of our CIs.
 * This should not modify any state if the Nak is bad
 * or if IPCP is in the OPENED state.
 *
 * Returns:
 *	0 - Nak was bad.
 *	1 - Nak was good.
 */
static int ipcp_nakci(fsm *f, u_char *p, int len)
{
    ipcp_options *go = &ipcp_gotoptions[f->unit];
    u_char cimaxslotindex, cicflag;
    u_char citype, cilen, *next;
    u_short cishort;
    u32_t ciaddr1, ciaddr2, l, cidnsaddr;
    ipcp_options no;		/* options we've seen Naks for */
    ipcp_options try;		/* options to request next time */

    BZERO(&no, sizeof(no));
    try = *go;

    /*
     * Any Nak'd CIs must be in exactly the same order that we sent.
     * Check packet length and CI length at each step.
     * If we find any deviations, then this packet is bad.
     */
#define NAKCIADDR(opt, neg, old, code) \
	if (go->neg && \
			len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
			p[1] == cilen && \
			p[0] == opt) { \
		len -= cilen; \
		INCPTR(2, p); \
		GETLONG(l, p); \
		ciaddr1 = htonl(l); \
		if (old) { \
			GETLONG(l, p); \
			ciaddr2 = htonl(l); \
			no.old_addrs = 1; \
		} else \
			ciaddr2 = 0; \
		no.neg = 1; \
		code \
	}

#define NAKCIVJ(opt, neg, code) \
	if (go->neg && \
			((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
			len >= cilen && \
			p[0] == opt) { \
		len -= cilen; \
		INCPTR(2, p); \
		GETSHORT(cishort, p); \
		no.neg = 1; \
		code \
	}

#define NAKCIDNS(opt, neg, code) \
	if (go->neg && \
			((cilen = p[1]) == CILEN_ADDR) && \
			len >= cilen && \
			p[0] == opt) { \
		len -= cilen; \
		INCPTR(2, p); \
		GETLONG(l, p); \
		cidnsaddr = htonl(l); \
		no.neg = 1; \
		code \
	}

    /*
     * Accept the peer's idea of {our,his} address, if different
     * from our idea, only if the accept_{local,remote} flag is set.
     */
    NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
    if (go->accept_local && ciaddr1) { /* Do we know our address? */
    try.ouraddr = ciaddr1;
    IPCPDEBUG((LOG_INFO, "local IP address %s\n",
               inet_ntoa(ciaddr1)));
    }
    if (go->accept_remote && ciaddr2) { /* Does he know his? */
    try.hisaddr = ciaddr2;
    IPCPDEBUG((LOG_INFO, "remote IP address %s\n",
               inet_ntoa(ciaddr2)));
    }
             );

    /*
     * Accept the peer's value of maxslotindex provided that it
     * is less than what we asked for.  Turn off slot-ID compression
     * if the peer wants.  Send old-style compress-type option if
     * the peer wants.
     */
    NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
    if (cilen == CILEN_VJ) {
    GETCHAR(cimaxslotindex, p);
        GETCHAR(cicflag, p);
        if (cishort == IPCP_VJ_COMP) {
            try.old_vj = 0;
            if (cimaxslotindex < go->maxslotindex)
                try.maxslotindex = cimaxslotindex;
            if (!cicflag)
                try.cflag = 0;
        } else {
            try.neg_vj = 0;
Example #4
0
//******************************************************************************
//	 			BuildIpConfigOptions
//******************************************************************************
void BuildIpConfigOptions(PCHProtConfig_t *ip_cnfg,
						  IPConfigAuthType_t authType,
						  CHAP_ChallengeOptions_t *cc,
						  CHAP_ResponseOptions_t *cr,
						  PAP_CnfgOptions_t *po)
{
	int len, i, tlen;
	u_char *outp, *lenp, *len_pid;			 
	u_long dnsaddr_pri;
	u_long dnsaddr_sec;
	u_short IPCP_prot = PPP_IPCP;
	u_short UPAP_prot = PPP_UPAP;
	u_short CHAP_prot = PPP_CHAP;
	u_long  ipaddr = 0;
    u_long l;

	
	len = 0;							//start at the top			 
	dnsaddr_pri = 0;
	dnsaddr_sec = 0;

	ip_cnfg->options[len++] = 0x80;	  	/* octet2, Protocol Config Option, PPP for use with  */


	/** build Protocol Identifier, CHAP authentication (RFC 1994)*/
	if(authType == REQUIRE_CHAP)
	{

		/* Send CHAP challenge packet here */
    	if ( cc->flag ) 						    /* Request the network for CHAP authentication? */
		{
			outp = (u_char *)&ip_cnfg->options[len];  
			PUTSHORT(CHAP_prot, outp);				/* CHAP protocol */
			len += 2;

			ip_cnfg->options[len++] = cc->len;		/* Protocol ID length */

	   		IPCPDEBUG(("Build Option: chap cc len=%d total=%d\n",cc->len,len));

			for (i = 0; i < cc->len; i++)		    /* octet27, send PAP data           */
				ip_cnfg->options[len++] = cc->content[i];	/* octetm           */
			cc->flag = 0;						    /* Clear Request flag. We only do this once per request     */
		}			
		/* Send CHAP response packet here */
    	if ( cr->flag ) 						    /* Request the network for PAP authentication? */
		{
			outp = (u_char *)&ip_cnfg->options[len];  
			PUTSHORT(CHAP_prot, outp);				/* CHAP protocol */
			len += 2;
		
			ip_cnfg->options[len++] = cr->len;		/* Protocol ID length */
			
	   		IPCPDEBUG(("Build Option: chap resp len=%d total=%d\n",cr->len,len));
			for (i = 0; i < cr->len; i++)		    /* send PAP data           */
				ip_cnfg->options[len++] = cr->content[i];
			cr->flag = 0;						    /* Clear Request flag. We only do this once per request     */
		}
	}/** done CHAP */

	/** build Protocol Identifier, PAP authentication (RFC 1334)*/
	if(authType == REQUIRE_PAP)
	{
    	if ( po->flag ) 						  	/* Request the network for PAP authentication? */
		{
			outp = (u_char *)&ip_cnfg->options[len];  
			PUTSHORT(UPAP_prot, outp);				/* UPAP protocol */
			len += 2;
		
			ip_cnfg->options[len++] = po->len;		/* Protocol ID length */
			
	   		IPCPDEBUG(("Build Option: pap len=%d total=%d\n",po->len,len));
			for (i = 0; i < po->len; i++)		    /* send PAP data */
				ip_cnfg->options[len++] = po->content[i];  
			po->flag = 0;						 	/* Clear Request flag. We only do this once per request     */
		}			
	/** done PAP */
	}					 

	/** build Protocol Identifier, IPCP */
	outp = (u_char *)&ip_cnfg->options[len++];  
	PUTSHORT(IPCP_prot, outp);						/* IPCP protocol */
	len += 1;							  

	len_pid = (u_char *)&ip_cnfg->options[len++];	/* Protocol ID length */

	tlen = len;

/*  build code, id, length */
	ip_cnfg->options[len++] = 1;			/* configure-req */
	ip_cnfg->options[len++] = 1;			/* id */
	lenp = (u_char *)&ip_cnfg->options[len++];  
	len++;

/** build IPCP options 129 (RFC 1877)**/


   	IPCPDEBUG(("Build Option: PDNS"));
	ip_cnfg->options[len++] = CI_DNSADDR_PRI;
	ip_cnfg->options[len++] = 6;
	outp = (u_char *)&ip_cnfg->options[len];  
	l = ntohl(dnsaddr_pri);
	PUTLONG(l, outp);							/* allow network to NAK and give us primary DNS server addr */
	len += 4;

/** build IPCP options 130 (RFC 1877)**/

   	IPCPDEBUG(("Build Option: SDNS"));
	ip_cnfg->options[len++] = CI_DNSADDR_SEC;
	ip_cnfg->options[len++] = 6;
	outp = (u_char *)&ip_cnfg->options[len];  
	l = ntohl(dnsaddr_sec);
	PUTLONG(ipaddr, outp);					    	/* allow network to NAK and give us secondary DNS server addr*/ 	
	len += 4;

	tlen = len - tlen;
	PUTCHAR(tlen, len_pid);							/* store Protocol ID length */
	PUTSHORT(tlen, lenp);					    	/* store IPCP length */

	if (len > 1)
		ip_cnfg->length = len;		    	/* Protocol Config Option length Config protocol octet */
	else
		ip_cnfg->length = 0;		    		/* If no options, length is zero as per discussion with Iulia */

/* --- DEBUG print --- */
/*---------------------------------------------------------------*/
  IPCPDEBUG(("\r\nIP config options: %x", ip_cnfg->length));
  for (i = 0; i < len; i++)                                    
  		IPCPDEBUG(("%x ",ip_cnfg->options[i]));
/*---------------------------------------------------------------*/
}