summaryrefslogtreecommitdiffstats
path: root/gatchat
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2011-06-29 03:32:51 -0500
committerDenis Kenzior <denkenz@gmail.com>2011-06-29 03:35:13 -0500
commitbc37c7465320e6f64693dbc1aec5cf4b250cb723 (patch)
tree897e5d08d16946ac1d70348eb6ec6adb7e6084de /gatchat
parent12338faabd67b949949b5de9bfe5076bfb35b614 (diff)
downloadofono-bc37c7465320e6f64693dbc1aec5cf4b250cb723.tar.bz2
gatppp: Refactor rx path
Diffstat (limited to 'gatchat')
-rw-r--r--gatchat/gatppp.c54
-rw-r--r--gatchat/ppp.h11
2 files changed, 32 insertions, 33 deletions
diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
index a108b2c3..787f6a53 100644
--- a/gatchat/gatppp.c
+++ b/gatchat/gatppp.c
@@ -170,38 +170,48 @@ static inline gboolean ppp_drop_packet(GAtPPP *ppp, guint16 protocol)
static void ppp_receive(const unsigned char *buf, gsize len, void *data)
{
GAtPPP *ppp = data;
- struct ppp_header *header = (struct ppp_header *) buf;
- gboolean acfc_frame = (header->address != PPP_ADDR_FIELD
- || header->control != PPP_CTRL);
- gboolean pfc_frame = FALSE;
+ unsigned int offset = 0;
guint16 protocol;
const guint8 *packet;
- if (acfc_frame) {
- protocol = ppp_acfc_proto(buf);
- packet = ppp_acfc_info(buf);
- } else {
- protocol = ppp_proto(buf);
- packet = ppp_info(buf);
- }
+ if (len == 0)
+ return;
- pfc_frame = (protocol != LCP_PROTOCOL && protocol != CHAP_PROTOCOL &&
- protocol != IPCP_PROTO && protocol != PPP_IP_PROTO);
+ if (buf[0] == PPP_ADDR_FIELD && len >= 2 && buf[1] == PPP_CTRL)
+ offset = 2;
- if (pfc_frame) {
- guint8 proto = (protocol >> 8) & 0xFF ;
- packet = packet - 1;
- /*
- * The only protocol that can be compressed is PPP_IP_PROTO
- * because first byte is 0x00.
- */
- if (proto == PPP_IP_COMPRESSED_PROTO)
- protocol = PPP_IP_PROTO;
+ if (len < offset + 1)
+ return;
+
+ /* From RFC 1661:
+ * the Protocol field uses an extension mechanism consistent with the
+ * ISO 3309 extension mechanism for the Address field; the Least
+ * Significant Bit (LSB) of each octet is used to indicate extension
+ * of the Protocol field. A binary "0" as the LSB indicates that the
+ * Protocol field continues with the following octet. The presence
+ * of a binary "1" as the LSB marks the last octet of the Protocol
+ * field.
+ *
+ * To check for compression we simply check the LSB of the first
+ * protocol byte.
+ */
+
+ if (buf[offset] & 0x1) {
+ protocol = buf[offset];
+ offset += 1;
+ } else {
+ if (len < offset + 2)
+ return;
+
+ protocol = get_host_short(buf + offset);
+ offset += 2;
}
if (ppp_drop_packet(ppp, protocol))
return;
+ packet = buf + offset;
+
switch (protocol) {
case PPP_IP_PROTO:
ppp_net_process_packet(ppp->net, packet);
diff --git a/gatchat/ppp.h b/gatchat/ppp.h
index 414d2dfc..fcd7aa8a 100644
--- a/gatchat/ppp.h
+++ b/gatchat/ppp.h
@@ -27,8 +27,6 @@
#define PPP_IP_PROTO 0x0021
#define MD5 5
-#define PPP_IP_COMPRESSED_PROTO 0x21
-
#define DBG(p, fmt, arg...) do { \
char *str = g_strdup_printf("%s:%s() " fmt, __FILE__, \
__FUNCTION__ , ## arg); \
@@ -81,18 +79,9 @@ static inline void __put_unaligned_short(void *p, guint16 val)
#define put_network_short(p, val) \
(__put_unaligned_short(p, htons(val)))
-#define ppp_info(packet) \
- (packet + 4)
-
#define ppp_proto(packet) \
(get_host_short(packet + 2))
-#define ppp_acfc_info(packet) \
- (packet + 2)
-
-#define ppp_acfc_proto(packet) \
- (get_host_short(packet))
-
/* LCP related functions */
struct pppcp_data *lcp_new(GAtPPP *ppp, gboolean dormant);
void lcp_free(struct pppcp_data *lcp);