1/*********************************************************************** 2* 3* pppoe.h 4* 5* Declaration of various PPPoE constants 6* 7* Copyright (C) 2000 Roaring Penguin Software Inc. 8* 9* This program may be distributed according to the terms of the GNU 10* General Public License, version 2 or (at your option) any later version. 11* 12* $Id: pppoe.h,v 1.1.1.1 2008/10/15 03:31:00 james26_jang Exp $ 13* 14***********************************************************************/ 15 16#ifdef __sun__ 17#define __EXTENSIONS__ 18#endif 19 20#include "config.h" 21 22#include <stdio.h> /* For FILE */ 23#include <sys/types.h> /* For pid_t */ 24 25/* How do we access raw Ethernet devices? */ 26#undef USE_LINUX_PACKET 27#undef USE_BPF 28 29#if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H) 30#define USE_LINUX_PACKET 1 31#elif defined(HAVE_NET_BPF_H) 32#define USE_BPF 1 33#elif defined(HAVE_SYS_DLPI_H) 34#define USE_DLPI 35#endif 36 37/* Sanity check */ 38#if !defined(USE_BPF) && !defined(USE_LINUX_PACKET) && !defined(USE_DLPI) 39#error Unknown method for accessing raw Ethernet frames 40#endif 41 42#ifdef HAVE_SYS_CDEFS_H 43#include <sys/cdefs.h> 44#endif 45 46#ifdef HAVE_SYS_SOCKET_H 47#include <sys/socket.h> 48#endif 49 50#ifdef HAVE_NET_IF_H 51#include <net/if.h> 52#endif 53 54#ifdef HAVE_NET_IF_TYPES_H 55#include <net/if_types.h> 56#endif 57 58#ifdef HAVE_NET_IF_DL_H 59#include <net/if_dl.h> 60#endif 61 62/* I'm not sure why this is needed... I do not have OpenBSD */ 63#if defined(__OpenBSD__) 64#include <net/ppp_defs.h> 65#include <net/if_ppp.h> 66#endif 67 68#ifdef USE_BPF 69extern int bpfSize; 70struct PPPoEPacket; 71void sessionDiscoveryPacket(struct PPPoEPacket *packet); 72#define BPF_BUFFER_IS_EMPTY (bpfSize <= 0) 73#define BPF_BUFFER_HAS_DATA (bpfSize > 0) 74#define ethhdr ether_header 75#define h_dest ether_dhost 76#define h_source ether_shost 77#define h_proto ether_type 78#define ETH_DATA_LEN ETHERMTU 79#define ETH_ALEN ETHER_ADDR_LEN 80#else 81#undef USE_BPF 82#define BPF_BUFFER_IS_EMPTY 1 83#define BPF_BUFFER_HAS_DATA 0 84#endif 85 86#ifdef USE_DLPI 87#include <sys/ethernet.h> 88#define ethhdr ether_header 89#define ETH_DATA_LEN ETHERMTU 90#define ETH_ALEN ETHERADDRL 91#define h_dest ether_dhost.ether_addr_octet 92#define h_source ether_shost.ether_addr_octet 93#define h_proto ether_type 94 95/* cloned from dltest.h */ 96#define MAXDLBUF 8192 97#define MAXDLADDR 1024 98#define MAXWAIT 15 99#define OFFADDR(s, n) (u_char*)((char*)(s) + (int)(n)) 100#define CASERET(s) case s: return ("s") 101 102#endif 103 104/* Define various integer types -- assumes a char is 8 bits */ 105#if SIZEOF_UNSIGNED_SHORT == 2 106typedef unsigned short UINT16_t; 107#elif SIZEOF_UNSIGNED_INT == 2 108typedef unsigned int UINT16_t; 109#else 110#error Could not find a 16-bit integer type 111#endif 112 113#if SIZEOF_UNSIGNED_SHORT == 4 114typedef unsigned short UINT32_t; 115#elif SIZEOF_UNSIGNED_INT == 4 116typedef unsigned int UINT32_t; 117#elif SIZEOF_UNSIGNED_LONG == 4 118typedef unsigned long UINT32_t; 119#else 120#error Could not find a 16-bit integer type 121#endif 122 123#ifdef HAVE_LINUX_IF_ETHER_H 124#include <linux/if_ether.h> 125#endif 126 127#include <netinet/in.h> 128 129#ifdef HAVE_NETINET_IF_ETHER_H 130#include <sys/types.h> 131 132#ifdef HAVE_SYS_SOCKET_H 133#include <sys/socket.h> 134#endif 135#ifndef HAVE_SYS_DLPI_H 136#include <netinet/if_ether.h> 137#endif 138#endif 139 140 141 142/* Ethernet frame types according to RFC 2516 */ 143#define ETH_PPPOE_DISCOVERY 0x8863 144#define ETH_PPPOE_SESSION 0x8864 145 146/* But some brain-dead peers disobey the RFC, so frame types are variables */ 147extern UINT16_t Eth_PPPOE_Discovery; 148extern UINT16_t Eth_PPPOE_Session; 149 150/* PPPoE codes */ 151#define CODE_PADI 0x09 152#define CODE_PADO 0x07 153#define CODE_PADR 0x19 154#define CODE_PADS 0x65 155#define CODE_PADT 0xA7 156#define CODE_SESS 0x00 157 158/* PPPoE Tags */ 159#define TAG_END_OF_LIST 0x0000 160#define TAG_SERVICE_NAME 0x0101 161#define TAG_AC_NAME 0x0102 162#define TAG_HOST_UNIQ 0x0103 163#define TAG_AC_COOKIE 0x0104 164#define TAG_VENDOR_SPECIFIC 0x0105 165#define TAG_RELAY_SESSION_ID 0x0110 166#define TAG_SERVICE_NAME_ERROR 0x0201 167#define TAG_AC_SYSTEM_ERROR 0x0202 168#define TAG_GENERIC_ERROR 0x0203 169 170/* Discovery phase states */ 171#define STATE_SENT_PADI 0 172#define STATE_RECEIVED_PADO 1 173#define STATE_SENT_PADR 2 174#define STATE_SESSION 3 175#define STATE_TERMINATED 4 176 177/* How many PADI/PADS attempts? */ 178#define MAX_PADI_ATTEMPTS 3 179 180/* Initial timeout for PADO/PADS */ 181#define PADI_TIMEOUT 5 182 183/* States for scanning PPP frames */ 184#define STATE_WAITFOR_FRAME_ADDR 0 185#define STATE_DROP_PROTO 1 186#define STATE_BUILDING_PACKET 2 187 188/* Special PPP frame characters */ 189#define FRAME_ESC 0x7D 190#define FRAME_FLAG 0x7E 191#define FRAME_ADDR 0xFF 192#define FRAME_CTRL 0x03 193#define FRAME_ENC 0x20 194 195#define IPV4ALEN 4 196#define SMALLBUF 256 197 198/* A PPPoE Packet, including Ethernet headers */ 199struct PPPoEPacket { 200 struct ethhdr ethHdr; /* Ethernet header */ 201 unsigned int ver:4; /* PPPoE Version (must be 1) */ 202 unsigned int type:4; /* PPPoE Type (must be 1) */ 203 unsigned int code:8; /* PPPoE code */ 204 unsigned int session:16; /* PPPoE session */ 205 unsigned int length:16; /* Payload length */ 206 unsigned char payload[ETH_DATA_LEN]; /* A bit of room to spare */ 207}; 208 209/* Header size of a PPPoE packet */ 210#define PPPOE_OVERHEAD 6 /* type, code, session, length */ 211#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD) 212#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD) 213 214/* PPPoE Tag */ 215 216struct PPPoETag { 217 unsigned int type:16; /* tag type */ 218 unsigned int length:16; /* Length of payload */ 219 unsigned char payload[ETH_DATA_LEN]; /* A LOT of room to spare */ 220}; 221/* Header size of a PPPoE tag */ 222#define TAG_HDR_SIZE 4 223 224/* Chunk to read from stdin */ 225#define READ_CHUNK 4096 226 227/* Function passed to parsePacket */ 228typedef void ParseFunc(UINT16_t type, 229 UINT16_t len, 230 unsigned char *data, 231 void *extra); 232 233/* Structure used to determine acceptable PADO or PADS packet */ 234struct PacketCriteria { 235 int acNameOK; 236 int serviceNameOK; 237}; 238 239/* Structures used by PPPoE server */ 240struct ClientSession { 241 pid_t pid; /* PID of child handling session */ 242 unsigned char ip[IPV4ALEN]; /* IP address of peer */ 243 UINT16_t sess; /* Session number */ 244 unsigned char eth[ETH_ALEN]; /* Peer's Ethernet address */ 245}; 246 247#define PPPINITFCS16 0xffff /* Initial FCS value */ 248 249/* Function Prototypes */ 250UINT16_t etherType(struct PPPoEPacket *packet); 251int openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr); 252void sendPacket(int sock, struct PPPoEPacket *pkt, int size); 253void receivePacket(int sock, struct PPPoEPacket *pkt, int *size); 254void fatalSys(char const *str); 255void fatal(char const *str); 256void printErr(char const *str); 257void dumpPacket(FILE *fp, struct PPPoEPacket *packet); 258void dumpHex(FILE *fp, unsigned char const *buf, int len); 259int parsePacket(struct PPPoEPacket *packet, ParseFunc *func, void *extra); 260void syncReadFromPPP(struct PPPoEPacket *packet); 261void asyncReadFromPPP(struct PPPoEPacket *packet); 262void asyncReadFromEth(int sock, int clampMss); 263void syncReadFromEth(int sock, int clampMss); 264char *strDup(char const *str); 265void sendPADT(void); 266void sendSessionPacket(struct PPPoEPacket *packet, int len); 267void initPPP(void); 268void clampMSS(struct PPPoEPacket *packet, char const *dir, int clampMss); 269UINT16_t computeTCPChecksum(unsigned char *ipHdr, unsigned char *tcpHdr); 270UINT16_t pppFCS16(UINT16_t fcs, unsigned char *cp, int len); 271 272#define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0); 273 274