[PATCH 03/11] gatppp: Add PPP server extension

Zhang, Zhenhua zhenhua.zhang at intel.com
Sun Jun 20 19:38:02 PDT 2010


Hi Denis,

Denis Kenzior wrote:
> Hi Zhenhua,
> 
>> 1. Add interface to set PPP server info by g_at_ppp_set_server_info.
>> 2. Pass local and peer address through IPCP handshaking.
>> ---
> 
> Its great that you're working on the PPP Server extensions.
> Can I get you to
> submit a patch taking ownership of this task?  See ofono/TODO 'PPP
> Server support'.
> 
>> +static void ipcp_generate_peer_config_options(struct ipcp_data
>> *ipcp) +{ +	guint16 len = 0;
>> +
>> +	FILL_IP(ipcp->req_options & REQ_OPTION_IPADDR,
>> +					IP_ADDRESS, &ipcp->peer_addr);
>> +	FILL_IP(ipcp->req_options & REQ_OPTION_DNS1,
>> +					PRIMARY_DNS_SERVER,
> &ipcp->dns1);
>> +	FILL_IP(ipcp->req_options & REQ_OPTION_DNS2,
>> +					SECONDARY_DNS_SERVER,
> &ipcp->dns2);
>> +	FILL_IP(ipcp->req_options & REQ_OPTION_NBNS1,
>> +					PRIMARY_NBNS_SERVER,
> &ipcp->nbns1);
>> +	FILL_IP(ipcp->req_options & REQ_OPTION_NBNS2,
>> +					SECONDARY_NBNS_SERVER,
> &ipcp->nbns2);
>> +
> 
> Using ipcp->req_options is the wrong thing here.  That is used
> for options
> sent in a Configure-Req.  Here you're filling in options to be
> sent in a
> Configure-Nak, Configure-Reject or a Configure-Ack.  You
> should simply be filling
> these in ipcp_rcr.  Feel free to modify the FILL_IP macro to take an
> additional destination parameter.

Okay. I will do that.

>> +	ipcp->options_len = len;
>> +}
>> +
>> +void ipcp_set_server_info(struct pppcp_data *pppcp, guint32
>> local_addr, +				guint32 peer_addr, +				guint32 dns1, guint32 dns2,
>> +				guint32 nbns1, guint32 nbns2)
>> +{
>> +	struct ipcp_data *ipcp = pppcp_get_data(pppcp);
>> +
>> +	ipcp->req_options = REQ_OPTION_IPADDR | REQ_OPTION_DNS1 |
>> +				REQ_OPTION_DNS2 | REQ_OPTION_NBNS1 |
>> +				REQ_OPTION_NBNS2;
>> +
>> +	ipcp->local_addr = local_addr;
>> +	ipcp->peer_addr = peer_addr;
>> +	ipcp->dns1 = dns1;
>> +	ipcp->dns2 = dns2;
>> +	ipcp->nbns1 = nbns1;
>> +	ipcp->nbns2 = nbns2;
>> +
>> +	ipcp_generate_config_options(ipcp);
> 
> Please note that this function is currently having no effect,
> you're missing a
> call to pppcp_set_local_options.  However, in the case of a server, we
> actually do not want to request DNS or NBNS, and we should
> only send our local
> address to the peer if it is non-zero.  Please note that all
> PPP modems we
> have encountered so far, do not send their local IP address in
> a Configure-
> Request.  Thus calling ipcp_set_server_info should end up
> generating an empty
> Configure-Request or with only the local IP address present.

It's confused me a little. Please correct me if I am wrong. I think PPP modem should send their local IP address to peer in a Configure-Request. So client could accept the peer address in ipcp_rcr.

In the case of a server, ipcp_set_server_info() should set local, peer, DNS and NBNS info and call pppcp_set_local_options(). And server only send our local address to peer in a Configure-Request.

>> +}
>> +
>>  static void ipcp_reset_config_options(struct ipcp_data *ipcp)  {
>>  	ipcp->req_options = REQ_OPTION_IPADDR | REQ_OPTION_DNS1 |
>>  				REQ_OPTION_DNS2 | REQ_OPTION_NBNS1 |
>>  				REQ_OPTION_NBNS2;
>> -	ipcp->ipaddr = 0;
>> +	ipcp->local_addr = 0;
> 
> In the case of a server, the local_address should not be reset.

It seems we need to add a flag in ipcp_data to indicate whether it's server or not. Does it make sense?

>> +	ipcp->peer_addr = 0;
>>  	ipcp->dns1 = 0;
>>  	ipcp->dns2 = 0;
>>  	ipcp->nbns1 = 0;
>> @@ -274,11 +321,54 @@ static enum rcr_result ipcp_rcr(struct
>>  pppcp_data *pppcp, guint8 **new_options, guint16 *new_len)
>>  {
>>  	struct ppp_option_iter iter;
>> +	struct ipcp_data *ipcp = pppcp_get_data(pppcp);
>> +	guint32 peer_addr;
>> +	guint32 dns1;
>> +	guint32 dns2;
>> 
>>  	ppp_option_iter_init(&iter, packet);
>> 
>> -	if (ppp_option_iter_next(&iter) == FALSE)
>> -		return RCR_ACCEPT;
> 
> Again, be careful here.  In the case of a client we should
> only accept the
> Server's IP-Address, nothing else.
> 
>> +	while (ppp_option_iter_next(&iter) == TRUE) {
>> +		const guint8 *data = ppp_option_iter_get_data(&iter); +
>> +		switch (ppp_option_iter_get_type(&iter)) {
>> +		case IP_ADDRESS:
>> +			memcpy(&peer_addr, data, 4);
>> +			break;
>> +		case PRIMARY_DNS_SERVER:
>> +			memcpy(&dns1, data, 4);
>> +			break;
>> +		case SECONDARY_DNS_SERVER:
>> +			memcpy(&dns2, data, 4);
>> +			break;
>> +		default:
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (peer_addr && dns1 && dns2) {
>> +		if (ipcp->peer_addr == 0) {
>> +			/* RFC 1332 Section 3.3
>> +			 * Accept the value of IP address as
> peer IP address
>> +			 */
>> +			ipcp->peer_addr = peer_addr;
>> +
> 
> This part doesn't really make any sense, if peer is sending 0,
> he's asking us
> for an IP.

For client side, the peer server address is zero initially. So it need to accept the server address immediately.

>> +			return RCR_ACCEPT;
>> +		} else if (ipcp->peer_addr == peer_addr)
>> +			return RCR_ACCEPT;
> 
> You need to ensure that not only the peer_addr matches, but
> also the dns /
> nbns addresses.  In our case we should be Configure-Rejecting
> the NBNS options
> and Configure-Naking DNS ones if they're set to zero or don't
> match what the
> peer is sending us.

Agree. Will update that part.

>> +	} else {
>> +		/* Peer requests us to send ip address in config options */ +		if
>> (ipcp->peer_addr) { +			struct ipcp_data *peer;
>> +
>> +			peer = g_memdup(ipcp, sizeof(struct ipcp_data));
>> +			ipcp_generate_peer_config_options(peer);
> 
> Yuck, please don't do this.  The main PPPCP layer will take
> care of freeing
> new_options, however you're now leaking the rest of the
> ipcp_data structure.

Ok. I will take care about it and resend the patch later.

>> +
>> +			*new_len = peer->options_len;
>> +			*new_options = peer->options;
>> +			return RCR_NAK;
>> +		}
>> +	}
>> 
>>  	/* Reject all options */
>>  	*new_len = packet->length - sizeof(*packet);
>> 
> 
> Regards,
> -Denis

Regards,
Zhenhua



More information about the ofono mailing list