#ifndef PPPOE_H
#define PPPOE_H	1

#include <stdio.h>		/* stdio               */
#include <stdlib.h>		/* strtoul(), realloc() */
#include <string.h>		/* memcpy()             */
#include <errno.h>		/* errno                */
#include <unistd.h>		/* STDIN_FILENO,exec    */
#include <sys/ioctl.h>		/* ioctl()              */
#include <sys/types.h>		/* socket types         */
#include <sys/time.h>
#include <sys/socket.h>		/* socket()             */
#include <net/if.h>		/* ifreq struct         */
#include <linux/sockios.h>	/* ifreq struct         */
#include <signal.h>
#include <sys/wait.h>

#include <net/ethernet.h>
#include <net/if_arp.h>
#include <netinet/in.h>

#include <assert.h>
#include <getopt.h>
#include <sys/select.h>

#include <sys/ioctl.h>

extern int errno;



#define PPPOEIOCSID  0x40047480
#define PPPOEIOGSID  0x40047481
#define PPPOEIOCDMAC 0x40047482
#define PPPOEIODID 0x40047483

#define CONNECTED 1
#define DISCONNECTED 0

struct session
  {
    int pid;			/* process ID  */
    int state;			/* Current state */
    int line;			/* PPP dev number */
    int sid;			/* session ID */
    char name[5];		/*name */
    char dmac[6];		/*destination MAC */
  };

static struct session ses_table[16];

#define VERSION_MAJOR 0
#define VERSION_MINOR 3
#define VERSION_DATE 991023

/* references: RFC 2516 */
/* ETHER_TYPE fields for PPPoE */

#define ETH_P_PPPOE_DISC 0x8863	/* discovery stage */
#define ETH_P_PPPOE_SESS 0x8864

/* ethernet broadcast address */
#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff"

/* PPPoE packet; includes Ethernet headers and such */
struct pppoe_packet
  {
    struct ethhdr ethhdr;	/* ethernet header */
    unsigned int ver:4;		/* pppoe version */
    unsigned int type:4;	/* pppoe type */
    unsigned int code:8;	/* pppoe code CODE_* */
    unsigned int session:16;	/* session id */
    unsigned short length;	/* payload length */
    /* payload follows */
  }__attribute__ ((packed));

/* maximum payload length */
#define MAX_PAYLOAD (1484 - sizeof(struct pppoe_packet))

/* PPPoE codes */
#define CODE_SESS 0x00		/* PPPoE session */
#define CODE_PADI 0x09		/* PPPoE Active Discovery Initiation */
#define CODE_PADO 0x07		/* PPPoE Active Discovery Offer */
#define CODE_PADR 0x19		/* PPPoE Active Discovery Request */
#define CODE_PADS 0x65		/* PPPoE Active Discovery Session-confirmation */
#define CODE_PADT 0xa7		/* PPPoE Active Discovery Terminate */

/* also need */
#define STATE_RUN (-1)

/* PPPoE tag; the payload is a sequence of these */
struct pppoe_tag
  {
    unsigned short type;	/* tag type TAG_* */
    unsigned short length;	/* tag length */
    /* payload follows */
  }__attribute__ ((packed));

/* PPPoE tag types */
#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_SERVICE_NAME_ERROR 0x0201
#define TAG_AC_SYSTEM_ERROR    0x0202
#define TAG_GENERIC_ERROR      0x0203

int disc_sock, sess_sock, socks[3];	/* raw socket we use */
char *if_name;			/* interface to use */

/*
   retransmit retries for the PADR and PADI packets
   during discovery
 */
int PADR_ret;
int PADI_ret;


#endif

