#ifndef PPPOE_H
#define PPPOE_H 1
#define PPPOE_RFC2516_TYPE 0x01
#define PPPOE_RFC2516_VER 0x01
#define PPPOE_CODE_PADI 0x09
#define PPPOE_CODE_PADO 0x07
#define PPPOE_CODE_PADR 0x19
#define PPPOE_CODE_PADS 0x65
#define PPPOE_CODE_PADT 0xa7
#define PPPOE_TAG_END_OF_LIST 0x0000
#define PPPOE_TAG_SERVICE_NAME 0x0101
#define PPPOE_TAG_AC_NAME 0x0102
#define PPPOE_TAG_HOST_UNIQ 0x0103
#define PPPOE_TAG_AC_COOKIE 0x0104
#define PPPOE_TAG_VENDOR_SPECIFIC 0x0105
#define PPPOE_TAG_RELAY_SESSION_ID 0x0110
#define PPPOE_TAG_SERVICE_NAME_ERROR 0x0201
#define PPPOE_TAG_AC_SYSTEM_ERROR 0x0202
#define PPPOE_TAG_GENERIC_ERROR 0x0203
struct pppoe_header {
#if BYTE_ORDER == BIG_ENDIAN
uint8_t ver:4, type:4;
#else
uint8_t type:4, ver:4;
#endif
uint8_t code;
uint16_t session_id;
uint16_t length;
} __attribute__((__packed__));
struct pppoe_tlv {
uint16_t type;
uint16_t length;
uint8_t value[0];
} __attribute__((__packed__));
#include "pppoe_conf.h"
#define PPPOED_DEFAULT_LAYER2_LABEL "PPPoE"
#define PPPOED_CONFIG_BUFSIZ 65535
#define PPPOED_HOSTUNIQ_LEN 64
#define PPPOED_PHY_LABEL_SIZE 16
#define PPPOED_STATE_INIT 0
#define PPPOED_STATE_RUNNING 1
#define PPPOED_STATE_STOPPED 2
#define pppoed_is_stopped(pppoed) \
(((pppoed)->state == PPPOED_STATE_STOPPED)? 1 : 0)
#define pppoed_is_running(pppoed) \
(((pppoed)->state == PPPOED_STATE_RUNNING)? 1 : 0)
#define PPPOED_LISTENER_INVALID_INDEX UINT16_MAX
typedef struct _pppoed_listener {
int bpf;
struct event ev_bpf;
struct _pppoed *self;
u_char ether_addr[ETHER_ADDR_LEN];
uint16_t index;
char listen_ifname[IF_NAMESIZE];
char tun_name[PPPOED_PHY_LABEL_SIZE];
struct pppoe_conf *conf;
} pppoed_listener;
typedef struct _pppoed {
int id;
slist listener;
int state;
hash_table *session_hash;
slist session_free_list;
hash_table *acookie_hash;
uint32_t acookie_next;
uint32_t
listen_incomplete:1,
reserved:31;
} pppoed;
typedef struct _pppoe_session {
int state;
pppoed *pppoed;
void *ppp;
uint16_t session_id;
int acookie;
u_char ether_addr[ETHER_ADDR_LEN];
uint16_t listener_index;
struct ether_header ehdr;
int lcp_echo_interval;
int lcp_echo_max_failure;
struct event ev_disposing;
} pppoe_session;
#define PPPOE_SESSION_STATE_INIT 0
#define PPPOE_SESSION_STATE_RUNNING 1
#define PPPOE_SESSION_STATE_DISPOSING 2
#define pppoed_need_polling(pppoed) \
(((pppoed)->listen_incomplete != 0)? 1 : 0)
#ifdef __cplusplus
extern "C" {
#endif
int pppoe_session_init (pppoe_session *, pppoed *, int, int, u_char *);
void pppoe_session_fini (pppoe_session *);
void pppoe_session_stop (pppoe_session *);
int pppoe_session_recv_PADR (pppoe_session *, slist *);
int pppoe_session_recv_PADT (pppoe_session *, slist *);
void pppoe_session_input (pppoe_session *, u_char *, int);
void pppoe_session_disconnect (pppoe_session *);
int pppoed_add_listener (pppoed *, int, const char *, const char *);
int pppoed_reload_listeners(pppoed *);
int pppoed_init (pppoed *);
int pppoed_start (pppoed *);
void pppoed_stop (pppoed *);
void pppoed_uninit (pppoed *);
void pppoed_pppoe_session_close_notify(pppoed *, pppoe_session *);
const char *pppoed_tlv_value_string(struct pppoe_tlv *);
int pppoed_reload(pppoed *, struct pppoe_confs *);
#ifdef __cplusplus
}
#endif
#endif