---
 Makefile.am           |    2 +-
 gatchat/gatppp.c      |   58 +++++++++-
 gatchat/gatppp.h      |    2 +
 gatchat/gsmdial.c     |    6 +
 gatchat/ppp.h         |   23 ++++
 gatchat/ppp_ipv6cp.c  |  306 +++++++++++++++++++++++++++++++++++++++++++++++++
 gatchat/test-server.c |   17 +++-
 7 files changed, 410 insertions(+), 4 deletions(-)
 create mode 100644 gatchat/ppp_ipv6cp.c

diff --git a/Makefile.am b/Makefile.am
index 83b7737..44fdfff 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -76,7 +76,7 @@ gatchat_sources = gatchat/gatchat.h gatchat/gatchat.c \
                                gatchat/ppp.h gatchat/ppp_cp.h \
                                gatchat/ppp_cp.c gatchat/ppp_lcp.c \
                                gatchat/ppp_auth.c gatchat/ppp_net.c \
-                               gatchat/ppp_ipcp.c
+                               gatchat/ppp_ipcp.c gatchat/ppp_ipv6cp.c
 
 gisi_sources = gisi/client.c gisi/client.h gisi/common.h \
                                gisi/iter.c gisi/iter.h \
diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
index f767f4a..41f9dff 100644
--- a/gatchat/gatppp.c
+++ b/gatchat/gatppp.c
@@ -62,6 +62,7 @@ struct _GAtPPP {
        enum ppp_phase phase;
        struct pppcp_data *lcp;
        struct pppcp_data *ipcp;
+       struct pppcp_data *ipv6cp;
        struct ppp_net *net;
        struct ppp_chap *chap;
        GAtHDLC *hdlc;
@@ -157,7 +158,8 @@ static inline gboolean ppp_drop_packet(GAtPPP *ppp, guint16 
protocol)
                return TRUE;
        case PPP_PHASE_NETWORK:
                if (protocol != LCP_PROTOCOL && protocol != CHAP_PROTOCOL &&
-                                       protocol != IPCP_PROTO)
+                                               protocol != IPCP_PROTO &&
+                                               protocol != IPV6CP_PROTO)
                        return TRUE;
                break;
        case PPP_PHASE_LINK_UP:
@@ -222,6 +224,10 @@ static void ppp_receive(const unsigned char *buf, gsize 
len, void *data)
        case IPCP_PROTO:
                pppcp_process_packet(ppp->ipcp, packet, len - offset);
                break;
+       case IPV6CP_PROTO:
+               if (ppp->ipv6cp)
+                       pppcp_process_packet(ppp->ipv6cp, packet, len - offset);
+               break;
        case CHAP_PROTOCOL:
                if (ppp->chap) {
                        ppp_chap_process_packet(ppp->chap, packet,
@@ -381,6 +387,13 @@ void ppp_auth_notify(GAtPPP *ppp, gboolean success)
 
        ppp_enter_phase(ppp, PPP_PHASE_NETWORK);
 
+       /* Send UP & OPEN events to the IPv6 CP */
+       if (ppp->ipv6cp) {
+               pppcp_signal_open(ppp->ipv6cp);
+               pppcp_signal_up(ppp->ipv6cp);
+               return;
+       }
+
        /* Send UP & OPEN events to the IPCP layer */
        pppcp_signal_open(ppp->ipcp);
        pppcp_signal_up(ppp->ipcp);
@@ -435,6 +448,28 @@ void ppp_ipcp_finished_notify(GAtPPP *ppp)
        pppcp_signal_close(ppp->lcp);
 }
 
+void ppp_ipv6cp_up_notify(GAtPPP *ppp, const char *local, const char *peer)
+{
+       DBG(ppp, "local: %s, peer: %s", local, peer);
+}
+
+void ppp_ipv6cp_down_notify(GAtPPP *ppp)
+{
+       DBG(ppp, "");
+}
+
+void ppp_ipv6cp_finished_notify(GAtPPP *ppp)
+{
+       DBG(ppp, "");
+
+       if (ppp->phase != PPP_PHASE_NETWORK)
+               return;
+
+       ppp->disconnect_reason = G_AT_PPP_REASON_IPV6CP_FAIL;
+       pppcp_signal_close(ppp->ipv6cp);
+       pppcp_signal_close(ppp->lcp);
+}
+
 void ppp_lcp_up_notify(GAtPPP *ppp)
 {
        /* Wait for the peer to send us a challenge if we expect auth */
@@ -732,6 +767,8 @@ void g_at_ppp_unref(GAtPPP *ppp)
 
        lcp_free(ppp->lcp);
        ipcp_free(ppp->ipcp);
+       if (ppp->ipv6cp)
+               ipv6cp_free(ppp->ipv6cp);
 
        if (ppp->ppp_dead_source) {
                g_source_remove(ppp->ppp_dead_source);
@@ -772,6 +809,25 @@ void g_at_ppp_set_pfc_enabled(GAtPPP *ppp, gboolean 
enabled)
        lcp_set_pfc_enabled(ppp->lcp, enabled);
 }
 
+void g_at_ppp_set_ipv6cp_info(GAtPPP *ppp, const char *local, const char *peer)
+{
+       struct in6_addr local_addr;
+       struct in6_addr peer_addr;
+
+       if (local)
+               inet_pton(AF_INET6, local, &local_addr);
+       else
+               memset(&local_addr, 0, sizeof(local_addr));
+
+       if (peer)
+               inet_pton(AF_INET6, peer, &peer_addr);
+       else
+               memset(&peer_addr, 0, sizeof(peer_addr));
+
+       ppp->ipv6cp = ipv6cp_new(ppp, (void *) &local_addr.s6_addr[8],
+                                               (void *) &peer_addr.s6_addr[8]);
+}
+
 static GAtPPP *ppp_init_common(gboolean is_server, guint32 ip)
 {
        GAtPPP *ppp;
diff --git a/gatchat/gatppp.h b/gatchat/gatppp.h
index b5a2234..9099d6b 100644
--- a/gatchat/gatppp.h
+++ b/gatchat/gatppp.h
@@ -37,6 +37,7 @@ typedef enum _GAtPPPDisconnectReason {
        G_AT_PPP_REASON_UNKNOWN,
        G_AT_PPP_REASON_AUTH_FAIL,      /* Failed to authenticate */
        G_AT_PPP_REASON_IPCP_FAIL,      /* Failed to negotiate IPCP */
+       G_AT_PPP_REASON_IPV6CP_FAIL,    /* Failed to negotiate IPV6CP */
        G_AT_PPP_REASON_NET_FAIL,       /* Failed to create tun */
        G_AT_PPP_REASON_PEER_CLOSED,    /* Peer initiated a close */
        G_AT_PPP_REASON_LINK_DEAD,      /* Link to the peer died */
@@ -81,6 +82,7 @@ void g_at_ppp_set_server_info(GAtPPP *ppp, const char 
*remote_ip,
 
 void g_at_ppp_set_acfc_enabled(GAtPPP *ppp, gboolean enabled);
 void g_at_ppp_set_pfc_enabled(GAtPPP *ppp, gboolean enabled);
+void g_at_ppp_set_ipv6cp_info(GAtPPP *ppp, const char *local, const char 
*peer);
 
 #ifdef __cplusplus
 }
diff --git a/gatchat/gsmdial.c b/gatchat/gsmdial.c
index be159eb..8f30309 100644
--- a/gatchat/gsmdial.c
+++ b/gatchat/gsmdial.c
@@ -59,6 +59,7 @@ static gchar *option_pppdump = NULL;
 static gboolean option_bluetooth = FALSE;
 static gboolean option_acfc = FALSE;
 static gboolean option_pfc = FALSE;
+static gchar *option_ipv6 = NULL;
 
 static GAtPPP *ppp;
 static GAtChat *control;
@@ -372,6 +373,9 @@ static void connect_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
        if (option_pppdump)
                g_at_ppp_set_recording(ppp, option_pppdump);
 
+       if (option_ipv6)
+               g_at_ppp_set_ipv6cp_info(ppp, option_ipv6, NULL);
+
        g_at_ppp_set_credentials(ppp, option_username, option_password);
 
        g_at_ppp_set_acfc_enabled(ppp, option_acfc);
@@ -687,6 +691,8 @@ static GOptionEntry options[] = {
                                "Use Protocol Field Compression" },
        { "acfc", 0, 0, G_OPTION_ARG_NONE, &option_acfc,
                                "Use Address & Control Field Compression" },
+       { "ipv6", '6', 0, G_OPTION_ARG_STRING, &option_ipv6,
+                               "Specify IPv6 address" },
        { NULL },
 };
 
diff --git a/gatchat/ppp.h b/gatchat/ppp.h
index a20fe85..5cb79f8 100644
--- a/gatchat/ppp.h
+++ b/gatchat/ppp.h
@@ -24,7 +24,9 @@
 #define LCP_PROTOCOL   0xc021
 #define CHAP_PROTOCOL  0xc223
 #define IPCP_PROTO     0x8021
+#define IPV6CP_PROTO   0x8057
 #define PPP_IP_PROTO   0x0021
+#define PPP_IPV6_PROTO 0x0057
 #define MD5            5
 
 #define DBG(p, fmt, arg...) do {                               \
@@ -44,6 +46,19 @@ struct ppp_header {
        guint8 info[0];
 } __attribute__((packed));
 
+struct eui64 {
+       union {
+               guint8 __e8[8];
+               guint16 __e16[4];
+               guint32 __e32[2];
+       } __u;
+#define e6_addr                __u.__e8
+#define e6_addr16      __u.__e16
+#define e6_addr32      __u.__e32
+};
+
+#define EUI64_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0 } } }
+
 struct packed_short {
        guint16 s;
 } __attribute__((packed));
@@ -95,6 +110,11 @@ void ipcp_free(struct pppcp_data *data);
 void ipcp_set_server_info(struct pppcp_data *ipcp, guint32 peer_addr,
                                guint32 dns1, guint32 dns2);
 
+/* IPv6 CP related functions */
+struct pppcp_data *ipv6cp_new(GAtPPP *ppp, const struct eui64 *local_addr,
+                               const struct eui64 *peer_addr);
+void ipv6cp_free(struct pppcp_data *data);
+
 /* CHAP related functions */
 struct ppp_chap *ppp_chap_new(GAtPPP *ppp, guint8 method);
 void ppp_chap_free(struct ppp_chap *chap);
@@ -120,6 +140,9 @@ void ppp_ipcp_up_notify(GAtPPP *ppp, const char *local, 
const char *peer,
                                        const char *dns1, const char *dns2);
 void ppp_ipcp_down_notify(GAtPPP *ppp);
 void ppp_ipcp_finished_notify(GAtPPP *ppp);
+void ppp_ipv6cp_up_notify(GAtPPP *ppp, const char *local, const char *peer);
+void ppp_ipv6cp_down_notify(GAtPPP *ppp);
+void ppp_ipv6cp_finished_notify(GAtPPP *ppp);
 void ppp_lcp_up_notify(GAtPPP *ppp);
 void ppp_lcp_down_notify(GAtPPP *ppp);
 void ppp_lcp_finished_notify(GAtPPP *ppp);
diff --git a/gatchat/ppp_ipv6cp.c b/gatchat/ppp_ipv6cp.c
new file mode 100644
index 0000000..b30d38a
--- /dev/null
+++ b/gatchat/ppp_ipv6cp.c
@@ -0,0 +1,306 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2009-2011  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <string.h>
+
+#include <glib.h>
+
+#include "gatppp.h"
+#include "ppp.h"
+
+#define IPV6CP_SUPPORTED_CODES ((1 << PPPCP_CODE_TYPE_CONFIGURE_REQUEST) | \
+                               (1 << PPPCP_CODE_TYPE_CONFIGURE_ACK) | \
+                               (1 << PPPCP_CODE_TYPE_CONFIGURE_NAK) | \
+                               (1 << PPPCP_CODE_TYPE_CONFIGURE_REJECT) | \
+                               (1 << PPPCP_CODE_TYPE_TERMINATE_REQUEST) | \
+                               (1 << PPPCP_CODE_TYPE_TERMINATE_ACK) | \
+                               (1 << PPPCP_CODE_TYPE_CODE_REJECT))
+
+enum ipv6cp_option_types {
+       IPV6CP_INTERFACE_ID             = 1,
+       IPV6CP_COMPRESSION_PROTO        = 2,
+};
+
+#define OPTIONS_COPY(_options, _len, _req, _type, _var, _opt_len)      \
+       if (_req) {                                                     \
+               _options[_len] = _type;                                 \
+               _options[_len + 1] = _opt_len + 2;                      \
+               memcpy(_options + _len + 2, _var, _opt_len);            \
+               _len += _opt_len + 2;                                   \
+       }
+
+/* We request only IPv6 Interface Id */
+#define MAX_IPV6CP_CONFIG_OPTION_SIZE  10
+#define MAX_IPV6CP_FAILURE             3
+
+struct ipv6cp_data {
+       guint8 options[MAX_IPV6CP_CONFIG_OPTION_SIZE];
+       guint16 options_len;
+       guint8 req_options;
+       struct eui64 local_addr;
+       struct eui64 peer_addr;
+};
+
+static const struct eui64 eui64_any = EUI64_ANY_INIT;
+
+static void ipv6cp_generate_config_options(struct ipv6cp_data *ipv6cp)
+{
+       guint16 len = 0;
+
+       OPTIONS_COPY(ipv6cp->options, len,
+                       ipv6cp->req_options & IPV6CP_INTERFACE_ID,
+                       IPV6CP_INTERFACE_ID, &ipv6cp->local_addr,
+                       sizeof(ipv6cp->local_addr));
+
+       ipv6cp->options_len = len;
+}
+
+static void ipv6cp_reset_config_options(struct ipv6cp_data *ipv6cp)
+{
+       ipv6cp->req_options = IPV6CP_INTERFACE_ID;
+
+       ipv6cp_generate_config_options(ipv6cp);
+}
+
+static void ipv6cp_up(struct pppcp_data *pppcp)
+{
+       struct ipv6cp_data *ipv6cp = pppcp_get_data(pppcp);
+       struct in6_addr local_addr, peer_addr;
+       char local[INET6_ADDRSTRLEN], peer[INET6_ADDRSTRLEN];
+
+       memset(&local_addr, 0, sizeof(local_addr));
+       memcpy(&local_addr.s6_addr[8], &ipv6cp->local_addr,
+                                       sizeof(ipv6cp->local_addr));
+       memset(&peer_addr, 0, sizeof(peer_addr));
+       memcpy(&peer_addr.s6_addr[8], &ipv6cp->peer_addr,
+                                       sizeof(ipv6cp->peer_addr));
+       ppp_ipv6cp_up_notify(pppcp_get_ppp(pppcp),
+               inet_ntop(AF_INET6, &local_addr, local, INET6_ADDRSTRLEN),
+               inet_ntop(AF_INET6, &peer_addr, peer, INET6_ADDRSTRLEN));
+}
+
+static void ipv6cp_down(struct pppcp_data *pppcp)
+{
+       struct ipv6cp_data *ipv6cp = pppcp_get_data(pppcp);
+
+       ipv6cp_reset_config_options(ipv6cp);
+
+       pppcp_set_local_options(pppcp, ipv6cp->options, ipv6cp->options_len);
+       ppp_ipv6cp_down_notify(pppcp_get_ppp(pppcp));
+}
+
+static void ipv6cp_finished(struct pppcp_data *pppcp)
+{
+       ppp_ipv6cp_finished_notify(pppcp_get_ppp(pppcp));
+}
+
+static enum rcr_result ipv6cp_peer_addr_check(struct ipv6cp_data *ipv6cp,
+                                               const void *data)
+{
+       if (memcmp(&eui64_any, data, sizeof(eui64_any)) == 0)
+               return RCR_NAK;
+
+       return RCR_ACCEPT;
+}
+
+static enum rcr_result ipv6cp_rcr(struct pppcp_data *pppcp,
+                                       const struct pppcp_packet *packet,
+                                       guint8 **new_options, guint16 *new_len)
+{
+       struct ipv6cp_data *ipv6cp = pppcp_get_data(pppcp);
+       struct ppp_option_iter iter;
+       enum rcr_result result = RCR_ACCEPT;
+       guint16 len = 0, max_len = ntohs(packet->length) - 4;
+       guint8 *options = g_new0(guint8, max_len);
+       gboolean copy = TRUE;
+
+       ppp_option_iter_init(&iter, packet);
+
+       while (ppp_option_iter_next(&iter) == TRUE) {
+               guint8 type = ppp_option_iter_get_type(&iter);
+               const guint8 *data = ppp_option_iter_get_data(&iter);
+
+               switch (type) {
+               case IPV6CP_INTERFACE_ID:
+                       if (result == RCR_ACCEPT) {
+
+                               result = ipv6cp_peer_addr_check(ipv6cp, data);
+
+                               if (result == RCR_ACCEPT)
+                                       memcpy(&ipv6cp->peer_addr, data,
+                                               sizeof(ipv6cp->peer_addr));
+                               else
+                                       data = ipv6cp->peer_addr.e6_addr;
+                       }
+                       break;
+               default:
+                       if (result == RCR_NAK) {
+                               copy = FALSE;
+                       } else if (result != RCR_REJECT) {
+                               result = RCR_REJECT;
+                               len = 0;
+                       }
+                       break;
+               }
+
+               OPTIONS_COPY(options, len, TRUE, type, data,
+                                       ppp_option_iter_get_length(&iter));
+       }
+
+       if (!len) {
+               g_free(options);
+               options = NULL;
+       }
+
+       *new_len = len;
+       *new_options = options;
+
+       return result;
+}
+
+static void ipv6cp_rca(struct pppcp_data *pppcp,
+                                       const struct pppcp_packet *packet)
+{
+       struct ipv6cp_data *ipv6cp = pppcp_get_data(pppcp);
+       struct ppp_option_iter iter;
+
+       ppp_option_iter_init(&iter, packet);
+
+       while (ppp_option_iter_next(&iter) == TRUE) {
+               const guint8 *data = ppp_option_iter_get_data(&iter);
+
+               switch (ppp_option_iter_get_type(&iter)) {
+               case IPV6CP_INTERFACE_ID:
+                       if (memcmp(&ipv6cp->local_addr, data,
+                                       sizeof(ipv6cp->local_addr)))
+                               DBG(pppcp_get_ppp(pppcp), "");
+                       break;
+               default:
+                       break;
+               }
+       }
+}
+
+static void ipv6cp_rcn_nak(struct pppcp_data *pppcp,
+                               const struct pppcp_packet *packet)
+{
+       struct ipv6cp_data *ipv6cp = pppcp_get_data(pppcp);
+       struct ppp_option_iter iter;
+
+       ppp_option_iter_init(&iter, packet);
+
+       while (ppp_option_iter_next(&iter) == TRUE) {
+               const guint8 *data = ppp_option_iter_get_data(&iter);
+
+               switch (ppp_option_iter_get_type(&iter)) {
+               case IPV6CP_INTERFACE_ID:
+                       memcpy(&ipv6cp->local_addr, data,
+                               sizeof(ipv6cp->local_addr));
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ipv6cp_generate_config_options(ipv6cp);
+       pppcp_set_local_options(pppcp, ipv6cp->options, ipv6cp->options_len);
+}
+
+static void ipv6cp_rcn_rej(struct pppcp_data *pppcp,
+                               const struct pppcp_packet *packet)
+{
+       struct ipv6cp_data *ipv6cp = pppcp_get_data(pppcp);
+       struct ppp_option_iter iter;
+
+       ppp_option_iter_init(&iter, packet);
+
+       while (ppp_option_iter_next(&iter) == TRUE) {
+               switch (ppp_option_iter_get_type(&iter)) {
+               case IPV6CP_INTERFACE_ID:
+                       ipv6cp->req_options &= ~IPV6CP_INTERFACE_ID;
+                       memset(&ipv6cp->local_addr, 0,
+                               sizeof(ipv6cp->local_addr));
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ipv6cp_generate_config_options(ipv6cp);
+       pppcp_set_local_options(pppcp, ipv6cp->options, ipv6cp->options_len);
+}
+
+struct pppcp_proto ipv6cp_proto = {
+       .proto                  = IPV6CP_PROTO,
+       .name                   = "ipv6cp",
+       .supported_codes        = IPV6CP_SUPPORTED_CODES,
+       .this_layer_up          = ipv6cp_up,
+       .this_layer_down        = ipv6cp_down,
+       .this_layer_finished    = ipv6cp_finished,
+       .rca                    = ipv6cp_rca,
+       .rcn_nak                = ipv6cp_rcn_nak,
+       .rcn_rej                = ipv6cp_rcn_rej,
+       .rcr                    = ipv6cp_rcr,
+};
+
+struct pppcp_data *ipv6cp_new(GAtPPP *ppp, const struct eui64 *local_addr,
+                                               const struct eui64 *peer_addr)
+{
+       struct ipv6cp_data *ipv6cp;
+       struct pppcp_data *pppcp;
+
+       ipv6cp = g_try_new0(struct ipv6cp_data, 1);
+       if (ipv6cp == NULL)
+               return NULL;
+
+       pppcp = pppcp_new(ppp, &ipv6cp_proto, FALSE, MAX_IPV6CP_FAILURE);
+       if (pppcp == NULL) {
+               g_free(ipv6cp);
+               return NULL;
+       }
+
+       memcpy(&ipv6cp->local_addr, local_addr, sizeof(ipv6cp->local_addr));
+       memcpy(&ipv6cp->peer_addr, peer_addr, sizeof(ipv6cp->peer_addr));
+
+       pppcp_set_data(pppcp, ipv6cp);
+
+       ipv6cp_reset_config_options(ipv6cp);
+
+       pppcp_set_local_options(pppcp, ipv6cp->options, ipv6cp->options_len);
+
+       return pppcp;
+}
+
+void ipv6cp_free(struct pppcp_data *data)
+{
+       struct ipv6cp_data *ipv6cp = pppcp_get_data(data);
+
+       g_free(ipv6cp);
+       pppcp_free(data);
+}
diff --git a/gatchat/test-server.c b/gatchat/test-server.c
index 6f1d06d..59bbbe1 100644
--- a/gatchat/test-server.c
+++ b/gatchat/test-server.c
@@ -58,6 +58,8 @@ static int modem_creg = 0;
 static int modem_cgreg = 0;
 static int network_status = 4;
 static int network_attach = 0;
+static const char *ipv6_local_addr = NULL;
+static const char *ipv6_peer_addr = NULL;
 
 struct sock_server{
        int server_sock;
@@ -176,6 +178,9 @@ static gboolean setup_ppp(GAtServer *server)
        g_at_ppp_set_server_info(ppp, "192.168.1.2",
                                        "10.10.10.10", "10.10.10.11");
 
+       if (ipv6_local_addr || ipv6_peer_addr)
+               g_at_ppp_set_ipv6cp_info(ppp, ipv6_local_addr, ipv6_peer_addr);
+
        return TRUE;
 }
 
@@ -1118,11 +1123,13 @@ static void usage(void)
 {
        g_print("test-server - AT Server testing\n"
                "Usage:\n");
-       g_print("\ttest-server [-t type]\n");
+       g_print("\ttest-server [-t type] [-6 addr]\n");
        g_print("Types:\n"
                "\t0: Pseudo TTY port (default)\n"
                "\t1: TCP sock at port 12346)\n"
                "\t2: Unix sock at ./server_sock\n");
+       g_print("-l\tSpecify local IPv6 address\n");
+       g_print("-p\tSpecify peer IPv6 address\n");
 }
 
 int main(int argc, char **argv)
@@ -1130,11 +1137,17 @@ int main(int argc, char **argv)
        int opt, signal_source;
        int type = 0;
 
-       while ((opt = getopt(argc, argv, "ht:")) != EOF) {
+       while ((opt = getopt(argc, argv, "hl:p:t:")) != EOF) {
                switch (opt) {
                case 't':
                        type = atoi(optarg);
                        break;
+               case 'l':
+                       ipv6_local_addr = optarg;
+                       break;
+               case 'p':
+                       ipv6_peer_addr = optarg;
+                       break;
                case 'h':
                        usage();
                        exit(1);
-- 
1.7.4.1

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to