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.

Ok getting pretty close now :)

> +static void ipcp_reset_server_config_options(struct ipcp_data *ipcp)
> +{
> +     ipcp->req_options = REQ_OPTION_IPADDR;

Might want to only request IP Addr if local_addr is not zero.  Just like in 
set_server_info.

> +
> +     ipcp_generate_config_options(ipcp);
> +}
> +

<snip>

> @@ -167,7 +211,7 @@ static void ipcp_rca(struct pppcp_data *pppcp,
> 
>               switch (ppp_option_iter_get_type(&iter)) {
>               case IP_ADDRESS:
> -                     memcpy(&ipcp->ipaddr, data, 4);
> +                     memcpy(&ipcp->local_addr, data, 4);
>                       break;
>               case PRIMARY_DNS_SERVER:
>                       memcpy(&ipcp->dns1, data, 4);

You might not want to do anything here in the case of a server role.

> @@ -204,7 +248,7 @@ static void ipcp_rcn_nak(struct pppcp_data *pppcp,
>               case IP_ADDRESS:
>                       g_print("Setting suggested ip addr\n");
>                       ipcp->req_options |= REQ_OPTION_IPADDR;
> -                     memcpy(&ipcp->ipaddr, data, 4);
> +                     memcpy(&ipcp->local_addr, data, 4);
>                       break;
>               case PRIMARY_DNS_SERVER:
>                       g_print("Setting suggested dns1\n");

Again, probably don't want to set the local_addr in the case of a server role.

> @@ -269,17 +313,102 @@ static void ipcp_rcn_rej(struct pppcp_data *pppcp,
>       pppcp_set_local_options(pppcp, ipcp->options, ipcp->options_len);
>  }
> 
> +static guint8 *ipcp_generate_peer_config_options(struct ipcp_data *ipcp,
> +                                                     guint16 *new_len)
> +{
> +     guint8 *options;
> +     guint16 len = 0;
> +
> +     options = g_try_new0(guint8, MAX_CONFIG_OPTION_SIZE);
> +     if (!options)
> +             return NULL;
> +
> +     FILL_IP(options, TRUE, IP_ADDRESS, &ipcp->peer_addr);
> +     FILL_IP(options, TRUE, PRIMARY_DNS_SERVER, &ipcp->dns1);
> +     FILL_IP(options, TRUE, SECONDARY_DNS_SERVER, &ipcp->dns2);
> +     FILL_IP(options, TRUE, PRIMARY_NBNS_SERVER, &ipcp->nbns1);
> +     FILL_IP(options, TRUE, SECONDARY_NBNS_SERVER, &ipcp->nbns2);
> +
> +     *new_len = MAX_CONFIG_OPTION_SIZE;

Don't use MAX_CONFIG_OPTION_SIZE, instead use len (which is filled properly by 
the FILL_IP macro)  Also, we shouldn't bother supporting NBNS, lets never 
suggest those options as a server or set them in set_server_info.

> +
> +     return options;
> +}
> +
>  static enum rcr_result ipcp_rcr(struct pppcp_data *pppcp,
>                                       const struct pppcp_packet *packet,
>                                       guint8 **new_options, guint16 *new_len)
>  {
>       struct ppp_option_iter iter;
> +     struct ipcp_data *ipcp = pppcp_get_data(pppcp);
> +     guint32 peer_addr = 0;
> +     guint32 dns1 = 0;
> +     guint32 dns2 = 0;
> +     guint32 nbns1 = 0;
> +     guint32 nbns2 = 0;
> 
>       ppp_option_iter_init(&iter, packet);
> 
> -     if (ppp_option_iter_next(&iter) == FALSE)
> +     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;
> +             case PRIMARY_NBNS_SERVER:
> +                     memcpy(&nbns1, data, 4);
> +                     break;
> +             case SECONDARY_NBNS_SERVER:
> +                     memcpy(&nbns2, data, 4);
> +                     break;
> +             default:
> +                     break;
> +             }
> +     }
> +

As mentioned above, if Primary / Secondary NBNS server is sent by the client, 
we need to Conf-Rej just those options to the client.  Any other unrecognized 
options should also be Conf-Rejected.  The order is important here, read the 
spec for details.  The IP Address, DNS1/DNS2 should not be Conf-Rejected.

> +     if (ipcp->is_server) {
> +             guint8 *options;
> +             guint16 len;
> +
> +             /* Reject if we have not assign client address yet */
> +             if (ipcp->peer_addr == 0 && ipcp->dns1 == 0 && ipcp->dns2 == 0)
> +                     goto reject;

Actually you should be NAKing here, not Rejecting.  Reject means you don't 
support this option at all.

> +
> +             /* Acknowledge client options if it matches with server options
> +              */
> +             if (ipcp->peer_addr == peer_addr &&
> +                             ipcp->dns1 == dns1 && ipcp->dns2 == dns2 &&
> +                             ipcp->nbns1 == nbns1 && ipcp->nbns2 == nbns2)
> +                     return RCR_ACCEPT;
> +
> +             /* Send client IP/DNS/NBNS information in the config options */
> +             options = ipcp_generate_peer_config_options(ipcp, &len);
> +             if (!options)
> +                     goto reject;
> +
> +             *new_len = len;
> +             *new_options = options;
> +
> +             return RCR_NAK;
> +     }
> +
> +     /* Client */
> +     if (peer_addr && ipcp->peer_addr == 0) {
> +             /* RFC 1332 section 3.3
> +              * As client, accept the server IP as peer's address
> +              */
> +             ipcp->peer_addr = peer_addr;
> +
>               return RCR_ACCEPT;
> +     }
> 
> +reject:
>       /* Reject all options */
>       *new_len = ntohs(packet->length) - sizeof(*packet);
>       *new_options = g_memdup(packet->data, *new_len);
> @@ -317,7 +446,7 @@ struct pppcp_data *ipcp_new(GAtPPP *ppp)
>       }
> 
>       pppcp_set_data(pppcp, ipcp);
> -     ipcp_reset_config_options(ipcp);
> +     ipcp_reset_client_config_options(ipcp);
>       pppcp_set_local_options(pppcp, ipcp->options, ipcp->options_len);
> 
>       return pppcp;
> 

Regards,
-Denis
_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to