]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/rp-pppoe/pppoe.h
pppd: Use a compile test to detect crypt.h (#198)
[ppp.git] / pppd / plugins / rp-pppoe / pppoe.h
index a4cf28a9dc0bc99fdb9afa73677d01671004b544..e2dc2ff9c00260d8437274941db0eb3ee20c7d97 100644 (file)
@@ -9,18 +9,18 @@
 * This program may be distributed according to the terms of the GNU
 * General Public License, version 2 or (at your option) any later version.
 *
-* $Id: pppoe.h,v 1.3 2008/06/09 08:34:23 paulus Exp $
+* $Id: pppoe.h,v 1.4 2008/06/15 04:35:50 paulus Exp $
 *
 ***********************************************************************/
 
 #include "config.h"
 
-#if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H)
-#define _POSIX_SOURCE 1 /* For sigaction defines */
-#endif
-
 #include <stdio.h>             /* For FILE */
 #include <sys/types.h>         /* For pid_t */
+#include <ctype.h>
+#include <string.h>
+
+#include "pppd/pppd.h"         /* For error */
 
 /* How do we access raw Ethernet devices? */
 #undef USE_LINUX_PACKET
 #error Unknown method for accessing raw Ethernet frames
 #endif
 
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
 
+/* This has to be included before Linux 4.8's linux/in.h
+ * gets dragged in. */
+#include <netinet/in.h>
+
 /* Ugly header files on some Linux boxes... */
 #if defined(HAVE_LINUX_IF_H)
 #include <linux/if.h>
@@ -82,9 +82,7 @@ typedef unsigned long UINT32_t;
 
 #ifdef HAVE_LINUX_IF_ETHER_H
 #include <linux/if_ether.h>
-#endif
-
-#include <netinet/in.h>
+#else
 
 #ifdef HAVE_NETINET_IF_ETHER_H
 #include <sys/types.h>
@@ -96,8 +94,7 @@ typedef unsigned long UINT32_t;
 #include <netinet/if_ether.h>
 #endif
 #endif
-
-
+#endif
 
 /* Ethernet frame types according to RFC 2516 */
 #define ETH_PPPOE_DISCOVERY 0x8863
@@ -129,6 +126,7 @@ extern UINT16_t Eth_PPPOE_Session;
 #define TAG_AC_COOKIE          0x0104
 #define TAG_VENDOR_SPECIFIC    0x0105
 #define TAG_RELAY_SESSION_ID   0x0110
+#define TAG_PPP_MAX_PAYLOAD    0x0120
 #define TAG_SERVICE_NAME_ERROR 0x0201
 #define TAG_AC_SYSTEM_ERROR    0x0202
 #define TAG_GENERIC_ERROR      0x0203
@@ -167,6 +165,13 @@ extern UINT16_t Eth_PPPOE_Session;
 #define IPV4ALEN     4
 #define SMALLBUF   256
 
+/* There are other fixed-size buffers preventing
+   this from being increased to 16110. The buffer
+   sizes would need to be properly de-coupled from
+   the default MRU. For now, getting up to 1500 is
+   enough. */
+#define ETH_JUMBO_LEN 1508
+
 /* A PPPoE Packet, including Ethernet headers */
 typedef struct PPPoEPacketStruct {
     struct ethhdr ethHdr;      /* Ethernet header */
@@ -174,7 +179,7 @@ typedef struct PPPoEPacketStruct {
     unsigned int code:8;       /* PPPoE code */
     unsigned int session:16;   /* PPPoE session */
     unsigned int length:16;    /* Payload length */
-    unsigned char payload[ETH_DATA_LEN]; /* A bit of room to spare */
+    unsigned char payload[ETH_JUMBO_LEN]; /* A bit of room to spare */
 } PPPoEPacket;
 
 #define PPPOE_VER(vt)          ((vt) >> 4)
@@ -184,15 +189,18 @@ typedef struct PPPoEPacketStruct {
 /* Header size of a PPPoE packet */
 #define PPPOE_OVERHEAD 6  /* type, code, session, length */
 #define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD)
-#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD)
-#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - 2)
+#define MAX_PPPOE_PAYLOAD (ETH_JUMBO_LEN - PPPOE_OVERHEAD)
+#define PPP_OVERHEAD 2  /* protocol */
+#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - PPP_OVERHEAD)
+#define TOTAL_OVERHEAD (PPPOE_OVERHEAD + PPP_OVERHEAD)
+#define ETH_PPPOE_MTU (ETH_DATA_LEN - TOTAL_OVERHEAD)
 
 /* PPPoE Tag */
 
 typedef struct PPPoETagStruct {
     unsigned int type:16;      /* tag type */
     unsigned int length:16;    /* Length of payload */
-    unsigned char payload[ETH_DATA_LEN]; /* A LOT of room to spare */
+    unsigned char payload[ETH_JUMBO_LEN]; /* A LOT of room to spare */
 } PPPoETag;
 /* Header size of a PPPoE tag */
 #define TAG_HDR_SIZE 4
@@ -217,12 +225,14 @@ typedef struct PPPoEConnectionStruct {
     int sessionSocket;         /* Raw socket for session frames */
     unsigned char myEth[ETH_ALEN]; /* My MAC address */
     unsigned char peerEth[ETH_ALEN]; /* Peer's MAC address */
+    unsigned char req_peer_mac[ETH_ALEN]; /* required peer MAC address */
+    unsigned char req_peer;    /* require mac addr to match req_peer_mac */
     UINT16_t session;          /* Session ID */
     char *ifName;              /* Interface name */
     char *serviceName;         /* Desired service name, if any */
     char *acName;              /* Desired AC name, if any */
     int synchronous;           /* Use synchronous PPP */
-    int useHostUniq;           /* Use Host-Uniq tag */
+    PPPoETag hostUniq;         /* Use Host-Uniq tag */
     int printACNames;          /* Just print AC names */
     FILE *debugFile;           /* Debug file for dumping packets */
     int numPADOs;              /* Number of PADO packets received */
@@ -231,6 +241,10 @@ typedef struct PPPoEConnectionStruct {
     int error;                 /* Error packet received */
     int debug;                 /* Set to log packets sent and received */
     int discoveryTimeout;       /* Timeout for discovery packets */
+    int discoveryAttempts;      /* Number of discovery attempts */
+    int seenMaxPayload;
+    int mtu;                   /* Stored MTU */
+    int mru;                   /* Stored MRU */
 } PPPoEConnection;
 
 /* Structure used to determine acceptable PADO or PADS packet */
@@ -275,6 +289,32 @@ void pppoe_printpkt(PPPoEPacket *packet,
                    void (*printer)(void *, char *, ...), void *arg);
 void pppoe_log_packet(const char *prefix, PPPoEPacket *packet);
 
+static inline int parseHostUniq(const char *uniq, PPPoETag *tag)
+{
+    unsigned i, len = strlen(uniq);
+
+#define hex(x) \
+    (((x) <= '9') ? ((x) - '0') : \
+        (((x) <= 'F') ? ((x) - 'A' + 10) : \
+            ((x) - 'a' + 10)))
+
+    if (!len || len % 2 || len / 2 > sizeof(tag->payload))
+        return 0;
+
+    for (i = 0; i < len; i += 2) {
+        if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1]))
+            return 0;
+
+        tag->payload[i / 2] = (char)(hex(uniq[i]) << 4 | hex(uniq[i+1]));
+    }
+
+#undef hex
+
+    tag->type = htons(TAG_HOST_UNIQ);
+    tag->length = htons(len / 2);
+    return 1;
+}
+
 #define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
 
 #define CHECK_ROOM(cursor, start, len) \