-/* Debug flags */
-int DEB_DISC,DEB_DISC2;
-/*
- #define DEB_DISC (opt_debug & 0x0002)
- #define DEB_DISC2 (opt_debug & 0x0004)
-*/
-#define MAX_FNAME 256
-
-
-struct session;
-
-/* return <0 --> fatal error; abor
- return =0 --> ok, proceed
- return >0 --> ok, qui
-*/
-typedef int (*packet_cb_t)(struct session* ses,
- struct pppoe_packet *p_in,
- struct pppoe_packet **p_out);
-
-/* various override filter tags */
-struct filter {
- struct pppoe_tag *stag; /* service name tag override */
- struct pppoe_tag *ntag; /*AC name override */
- struct pppoe_tag *htag; /* hostuniq override */
- int num_restart;
- int peermode;
- char *fname;
- char *pppd;
-} __attribute__ ((packed));
-
-
-struct pppoe_tag *make_filter_tag(short type, short length, char* data);
-
-/* Session type definitions */
-#define SESSION_CLIENT 0
-#define SESSION_SERVER 1
-#define SESSION_RELAY 2
-
-struct session {
-
- /* Administrative */
- int type;
- int opt_debug;
- int detached;
- int np;
- int log_to_fd;
- int ifindex; /* index of device */
- char name[IFNAMSIZ]; /*dev name */
- struct pppoe_packet curr_pkt;
-
- packet_cb_t init_disc;
- packet_cb_t rcv_pado;
- packet_cb_t rcv_padi;
- packet_cb_t rcv_pads;
- packet_cb_t rcv_padr;
- packet_cb_t rcv_padt;
- packet_cb_t timeout;
-
-
- /* Generic */
- struct filter *filt;
- struct sockaddr_ll local;
- struct sockaddr_ll remote;
- struct sockaddr_pppox sp;
- int fd; /* fd of PPPoE socket */
-
-
- /* For client */
- int retransmits; /* Number of retransmission performed
- if < 0 , retransmissions disabled */
- int retries;
- int state;
- int opt_daemonize;
-
- /* For server */
- int fork;
-
- /* For forwarding */
- int fwd_sock;
- char fwd_name[IFNAMSIZ]; /* Name of device to forward to */
-} __attribute__ ((packed));
-
-/*
- retransmit retries for the PADR and PADI packets
- during discovery
-*/
-int PADR_ret;
-int PADI_ret;
-
-int log_to_fd;
-int ctrl_fd;
-int opt_debug;
-int opt_daemonize;
-
-
-/* Structure for keeping track of connection relays */
-struct pppoe_con{
- struct pppoe_con *next;
- int id;
- int connected;
- int cl_sock;
- int sv_sock;
- int ref_count;
- char client[ETH_ALEN];
- char server[ETH_ALEN];
- char key_len;
- char key[32];
+/* Ethernet frame types according to RFC 2516 */
+#define ETH_PPPOE_DISCOVERY 0x8863
+#define ETH_PPPOE_SESSION 0x8864
+
+/* But some brain-dead peers disobey the RFC, so frame types are variables */
+extern UINT16_t Eth_PPPOE_Discovery;
+extern UINT16_t Eth_PPPOE_Session;
+
+/* PPPoE codes */
+#define CODE_PADI 0x09
+#define CODE_PADO 0x07
+#define CODE_PADR 0x19
+#define CODE_PADS 0x65
+#define CODE_PADT 0xA7
+
+/* Extensions from draft-carrel-info-pppoe-ext-00 */
+/* I do NOT like PADM or PADN, but they are here for completeness */
+#define CODE_PADM 0xD3
+#define CODE_PADN 0xD4
+
+#define CODE_SESS 0x00
+
+/* PPPoE Tags */
+#define TAG_END_OF_LIST 0x0000
+#define TAG_SERVICE_NAME 0x0101
+#define TAG_AC_NAME 0x0102
+#define TAG_HOST_UNIQ 0x0103
+#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
+
+/* Extensions from draft-carrel-info-pppoe-ext-00 */
+/* I do NOT like these tags one little bit */
+#define TAG_HURL 0x111
+#define TAG_MOTM 0x112
+#define TAG_IP_ROUTE_ADD 0x121
+
+/* Discovery phase states */
+#define STATE_SENT_PADI 0
+#define STATE_RECEIVED_PADO 1
+#define STATE_SENT_PADR 2
+#define STATE_SESSION 3
+#define STATE_TERMINATED 4
+
+/* How many PADI/PADS attempts? */
+#define MAX_PADI_ATTEMPTS 3
+
+/* Initial timeout for PADO/PADS */
+#define PADI_TIMEOUT 5
+
+/* States for scanning PPP frames */
+#define STATE_WAITFOR_FRAME_ADDR 0
+#define STATE_DROP_PROTO 1
+#define STATE_BUILDING_PACKET 2
+
+/* Special PPP frame characters */
+#define FRAME_ESC 0x7D
+#define FRAME_FLAG 0x7E
+#define FRAME_ADDR 0xFF
+#define FRAME_CTRL 0x03
+#define FRAME_ENC 0x20
+
+#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 */
+ unsigned int vertype:8; /* PPPoE Version and Type (must both be 1) */
+ unsigned int code:8; /* PPPoE code */
+ unsigned int session:16; /* PPPoE session */
+ unsigned int length:16; /* Payload length */
+ unsigned char payload[ETH_JUMBO_LEN]; /* A bit of room to spare */
+} PPPoEPacket;
+
+#define PPPOE_VER(vt) ((vt) >> 4)
+#define PPPOE_TYPE(vt) ((vt) & 0xf)
+#define PPPOE_VER_TYPE(v, t) (((v) << 4) | (t))
+
+/* 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_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_JUMBO_LEN]; /* A LOT of room to spare */
+} PPPoETag;
+/* Header size of a PPPoE tag */
+#define TAG_HDR_SIZE 4
+
+/* Chunk to read from stdin */
+#define READ_CHUNK 4096
+
+/* Function passed to parsePacket */
+typedef void ParseFunc(UINT16_t type,
+ UINT16_t len,
+ unsigned char *data,
+ void *extra);
+
+#define PPPINITFCS16 0xffff /* Initial FCS value */
+
+/* Keep track of the state of a connection -- collect everything in
+ one spot */
+
+typedef struct PPPoEConnectionStruct {
+ int discoveryState; /* Where we are in discovery */
+ int discoverySocket; /* Raw socket for discovery frames */
+ 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 */
+ PPPoETag hostUniq; /* Use Host-Uniq tag */
+ int numPADOs; /* Number of PADO packets received */
+ PPPoETag cookie; /* We have to send this if we get it */
+ PPPoETag relayId; /* Ditto */
+ int error; /* Error packet received */
+ int discoveryTimeout; /* Timeout for discovery packets */
+ int discoveryAttempts; /* Number of discovery attempts */
+ int seenMaxPayload;
+ int storedmtu; /* Stored MTU */
+ int storedmru; /* Stored MRU */
+ int mtu;
+ int mru;
+} PPPoEConnection;
+
+/* Structure used to determine acceptable PADO or PADS packet */
+struct PacketCriteria {
+ PPPoEConnection *conn;
+ int acNameOK;
+ int serviceNameOK;
+ int seenACName;
+ int seenServiceName;