Add support for recording PPP sessions in pppdump format

This commit is contained in:
Marcel Holtmann 2010-04-01 13:47:25 -07:00
parent ef82241deb
commit 544c02da49
5 changed files with 62 additions and 5 deletions

View File

@ -28,6 +28,7 @@
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <glib.h>
@ -44,7 +45,7 @@ void g_at_ppp_open(GAtPPP *ppp)
}
void g_at_ppp_set_credentials(GAtPPP *ppp, const char *username,
const char *passwd)
const char *passwd)
{
auth_set_credentials(ppp->auth, username, passwd);
}
@ -78,6 +79,21 @@ void g_at_ppp_set_debug(GAtPPP *ppp, GAtDebugFunc func, gpointer user_data)
ppp->debug_data = user_data;
}
void g_at_ppp_set_recording(GAtPPP *ppp, const char *filename)
{
if (ppp == NULL)
return;
if (ppp->record_fd > fileno(stderr))
close(ppp->record_fd);
if (filename == NULL)
return;
ppp->record_fd = open(filename, O_WRONLY | O_CREAT | O_APPEND,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
}
void g_at_ppp_shutdown(GAtPPP *ppp)
{
/* close the ppp link */
@ -98,6 +114,9 @@ void g_at_ppp_unref(GAtPPP *ppp)
* we can't free the link yet, because we need to terminate
* the link first.
*/
if (ppp->record_fd > fileno(stderr))
close(ppp->record_fd);
}
GAtPPP *g_at_ppp_new(GIOChannel *modem)
@ -146,5 +165,7 @@ GAtPPP *g_at_ppp_new(GIOChannel *modem)
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
ppp_cb, ppp);
ppp->record_fd = -1;
return ppp;
}

View File

@ -48,11 +48,12 @@ void g_at_ppp_set_connect_function(GAtPPP *ppp, GAtPPPConnectFunc callback,
void g_at_ppp_set_disconnect_function(GAtPPP *ppp, GAtDisconnectFunc func,
gpointer user_data);
void g_at_ppp_set_debug(GAtPPP *ppp, GAtDebugFunc func, gpointer user_data);
void g_at_ppp_set_recording(GAtPPP *ppp, const char *filename);
void g_at_ppp_shutdown(GAtPPP *ppp);
void g_at_ppp_ref(GAtPPP *ppp);
void g_at_ppp_unref(GAtPPP *ppp);
void g_at_ppp_set_credentials(GAtPPP *ppp, const char *username,
const char *passwd);
const char *passwd);
#ifdef __cplusplus
}
#endif

View File

@ -54,6 +54,7 @@ static gboolean option_legacy = FALSE;
static gboolean option_ppp = FALSE;
static gchar *option_username = NULL;
static gchar *option_password = NULL;
static gchar *option_pppdump = NULL;
static GAtPPP *ppp;
static GAtChat *control;
@ -271,6 +272,9 @@ static void connect_cb(gboolean ok, GAtResult *result, gpointer user_data)
}
g_at_ppp_set_debug(ppp, gsmdial_debug, "PPP");
if (option_pppdump)
g_at_ppp_set_recording(ppp, option_pppdump);
g_at_ppp_set_credentials(ppp, option_username, option_password);
/* set connect and disconnect callbacks */
@ -581,7 +585,9 @@ static GOptionEntry options[] = {
{ "username", 'u', 0, G_OPTION_ARG_STRING, &option_username,
"Specify PPP username" },
{ "password", 'w', 0, G_OPTION_ARG_STRING, &option_password,
"Specifiy PPP password" },
"Specify PPP password" },
{ "pppdump", 'D', 0, G_OPTION_ARG_STRING, &option_pppdump,
"Specify pppdump filename" },
{ NULL },
};

View File

@ -28,6 +28,7 @@
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <glib.h>
@ -295,6 +296,30 @@ static void ppp_feed(GAtPPP *ppp, guint8 *data, gsize len)
ppp_recv(ppp);
}
static void ppp_record(GAtPPP *ppp, gboolean in, guint8 *data, guint16 length)
{
guint16 len = htons(length);
guint32 ts;
struct timeval now;
unsigned char id;
int err;
if (ppp->record_fd < 0)
return;
gettimeofday(&now, NULL);
ts = htonl(now.tv_sec & 0xffffffff);
id = 0x07;
err = write(ppp->record_fd, &id, 1);
err = write(ppp->record_fd, &ts, 4);
id = in ? 0x02 : 0x01;
err = write(ppp->record_fd, &id, 1);
err = write(ppp->record_fd, &len, 2);
err = write(ppp->record_fd, data, length);
}
/*
* transmit out through the lower layer interface
*
@ -325,6 +350,7 @@ void ppp_transmit(GAtPPP *ppp, guint8 *packet, guint infolen)
*/
status = g_io_channel_write_chars(ppp->modem, (gchar *) frame,
framelen, &bytes_written, &error);
ppp_record(ppp, FALSE, frame, bytes_written);
g_free(frame);
}
@ -343,8 +369,10 @@ gboolean ppp_cb(GIOChannel *channel, GIOCondition cond, gpointer data)
if (cond & G_IO_IN) {
status = g_io_channel_read_chars(channel, buf, 256,
&bytes_read, &error);
if (bytes_read > 0)
ppp_feed(ppp, (guint8 *)buf, bytes_read);
if (bytes_read > 0) {
ppp_feed(ppp, (guint8 *) buf, bytes_read);
ppp_record(ppp, TRUE, (guint8 *) buf, bytes_read);
}
if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN)
return FALSE;
}

View File

@ -139,6 +139,7 @@ struct _GAtPPP {
gint modem_watch;
GAtDebugFunc debugf;
gpointer debug_data;
int record_fd;
};
gboolean ppp_cb(GIOChannel *channel, GIOCondition cond, gpointer data);