From 7e5ccc18d77bb0919519747647f7f6559d313830 Mon Sep 17 00:00:00 2001 From: Guillaume Zajac Date: Thu, 19 May 2011 11:58:28 +0200 Subject: [PATCH] gatppp: Add new contructor to use external fd --- gatchat/gatppp.c | 33 ++++++++++++++++++++++++++++++++- gatchat/gatppp.h | 1 + gatchat/ppp.h | 2 +- gatchat/ppp_net.c | 43 ++++++++++++++++++++++++++++++------------- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c index f2f2484d..6d27dd6f 100644 --- a/gatchat/gatppp.c +++ b/gatchat/gatppp.c @@ -78,6 +78,7 @@ struct _GAtPPP { guint ppp_dead_source; GAtSuspendFunc suspend_func; gpointer suspend_data; + int fd; }; void ppp_debug(GAtPPP *ppp, const char *str) @@ -290,7 +291,7 @@ void ppp_auth_notify(GAtPPP *ppp, gboolean success) void ppp_ipcp_up_notify(GAtPPP *ppp, const char *local, const char *peer, const char *dns1, const char *dns2) { - ppp->net = ppp_net_new(ppp); + ppp->net = ppp_net_new(ppp, ppp->fd); if (ppp->net == NULL) { ppp->disconnect_reason = G_AT_PPP_REASON_NET_FAIL; @@ -316,6 +317,7 @@ void ppp_ipcp_down_notify(GAtPPP *ppp) return; ppp_net_free(ppp->net); + ppp->fd = -1; ppp->net = NULL; } @@ -522,6 +524,8 @@ void g_at_ppp_unref(GAtPPP *ppp) if (ppp->net) ppp_net_free(ppp->net); + else if (ppp->fd >= 0) + close(ppp->fd); if (ppp->chap) ppp_chap_free(ppp->chap); @@ -565,6 +569,8 @@ static GAtPPP *ppp_init_common(GAtHDLC *hdlc, gboolean is_server, guint32 ip) ppp->ref_count = 1; + ppp->fd = -1; + /* set options to defaults */ ppp->mru = DEFAULT_MRU; ppp->mtu = DEFAULT_MTU; @@ -657,3 +663,28 @@ GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local) return ppp; } + +GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd) +{ + GAtHDLC *hdlc; + GAtPPP *ppp; + guint32 ip; + + if (local == NULL) + ip = 0; + else if (inet_pton(AF_INET, local, &ip) != 1) + return NULL; + + hdlc = g_at_hdlc_new_from_io(io); + if (hdlc == NULL) + return NULL; + + ppp = ppp_init_common(hdlc, TRUE, ip); + + /* Set the fd value returned by ConnMan */ + ppp->fd = fd; + + g_at_hdlc_unref(hdlc); + + return ppp; +} diff --git a/gatchat/gatppp.h b/gatchat/gatppp.h index 9464ffd3..365123a2 100644 --- a/gatchat/gatppp.h +++ b/gatchat/gatppp.h @@ -54,6 +54,7 @@ GAtPPP *g_at_ppp_new(GIOChannel *modem); GAtPPP *g_at_ppp_new_from_io(GAtIO *io); GAtPPP *g_at_ppp_server_new(GIOChannel *modem, const char *local); GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local); +GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd); void g_at_ppp_open(GAtPPP *ppp); void g_at_ppp_set_connect_function(GAtPPP *ppp, GAtPPPConnectFunc callback, diff --git a/gatchat/ppp.h b/gatchat/ppp.h index 22809d8d..f8669446 100644 --- a/gatchat/ppp.h +++ b/gatchat/ppp.h @@ -102,7 +102,7 @@ void ppp_chap_free(struct ppp_chap *chap); void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet); /* TUN / Network related functions */ -struct ppp_net *ppp_net_new(GAtPPP *ppp); +struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd); const char *ppp_net_get_interface(struct ppp_net *net); void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet); void ppp_net_free(struct ppp_net *net); diff --git a/gatchat/ppp_net.c b/gatchat/ppp_net.c index 25bcfa47..52b35542 100644 --- a/gatchat/ppp_net.c +++ b/gatchat/ppp_net.c @@ -123,35 +123,52 @@ const char *ppp_net_get_interface(struct ppp_net *net) return net->if_name; } -struct ppp_net *ppp_net_new(GAtPPP *ppp) +struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd) { struct ppp_net *net; GIOChannel *channel = NULL; struct ifreq ifr; - int fd, err; + int err; net = g_try_new0(struct ppp_net, 1); - if (net == NULL) + if (net == NULL) { + if (fd >= 0) + close(fd); + return NULL; + } net->ppp_packet = ppp_packet_new(MAX_PACKET, PPP_IP_PROTO); if (net->ppp_packet == NULL) { + if (fd >= 0) + close(fd); + g_free(net); return NULL; } - /* open a tun interface */ - fd = open("/dev/net/tun", O_RDWR); - if (fd < 0) - goto error; + /* + * If the fd value is still the default one, + * open the tun interface and configure it. + */ + if (fd < 0) { + /* open a tun interface */ + fd = open("/dev/net/tun", O_RDWR); + if (fd < 0) + goto error; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - strcpy(ifr.ifr_name, "ppp%d"); + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + strcpy(ifr.ifr_name, "ppp%d"); - err = ioctl(fd, TUNSETIFF, (void *) &ifr); - if (err < 0) - goto error; + err = ioctl(fd, TUNSETIFF, (void *) &ifr); + if (err < 0) + goto error; + } else { + err = ioctl(fd, TUNGETIFF, (void *) &ifr); + if (err < 0) + goto error; + } net->if_name = strdup(ifr.ifr_name);