gatppp: Refactor rx path
authorDenis Kenzior <denkenz@gmail.com>
Wed, 29 Jun 2011 08:32:51 +0000 (03:32 -0500)
committerDenis Kenzior <denkenz@gmail.com>
Wed, 29 Jun 2011 08:35:13 +0000 (03:35 -0500)
gatchat/gatppp.c
gatchat/ppp.h

index a108b2c..787f6a5 100644 (file)
@@ -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);
index 414d2df..fcd7aa8 100644 (file)
@@ -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);