1#include <stdio.h> 2#include <sys/time.h> 3#include <sys/types.h> 4#include <sys/file.h> 5#include <unistd.h> 6#include <getopt.h> 7#include <stdlib.h> 8#include <sys/socket.h> 9#include <netinet/in.h> 10#include <arpa/inet.h> 11#include <signal.h> 12#include <time.h> 13#include <string.h> 14#include <sys/ioctl.h> 15#include <net/if.h> 16#include <errno.h> 17#include <netinet/udp.h> 18#include <netinet/ip.h> 19#include <netpacket/packet.h> 20//#include <net/ethernet.h> 21#include <features.h> 22 23#include <sys/uio.h> 24#include <fcntl.h> 25#include <sys/cdefs.h> 26#include <net/ppp_defs.h> 27#include <net/if_ppp.h> 28#include <linux/if_ether.h> 29//#include <netinet/if_ether.h> 30#include <ctype.h> 31 32 33/************************************/ 34/* Defaults _you_ may want to tweak */ 35/************************************/ 36 37/* the period of time the client is allowed to use that address */ 38#define LEASE_TIME (60*60*24*10) /* 10 days of seconds */ 39 40/* where to find the DHCP server configuration file */ 41#define DHCPD_CONF_FILE "/etc/udhcpd.conf" 42 43/*****************************************************************/ 44/* Do not modify below here unless you know what you are doing!! */ 45/*****************************************************************/ 46 47/* DHCP protocol -- see RFC 2131 */ 48#define SERVER_PORT 67 49#define CLIENT_PORT 68 50 51#define DHCP_MAGIC 0x63825363 52 53/* DHCP option codes (partial list) */ 54#define DHCP_PADDING 0x00 55#define DHCP_SUBNET 0x01 56#define DHCP_TIME_OFFSET 0x02 57#define DHCP_ROUTER 0x03 58#define DHCP_TIME_SERVER 0x04 59#define DHCP_NAME_SERVER 0x05 60#define DHCP_DNS_SERVER 0x06 61#define DHCP_LOG_SERVER 0x07 62#define DHCP_COOKIE_SERVER 0x08 63#define DHCP_LPR_SERVER 0x09 64#define DHCP_HOST_NAME 0x0c 65#define DHCP_BOOT_SIZE 0x0d 66#define DHCP_DOMAIN_NAME 0x0f 67#define DHCP_SWAP_SERVER 0x10 68#define DHCP_ROOT_PATH 0x11 69#define DHCP_IP_TTL 0x17 70#define DHCP_MTU 0x1a 71#define DHCP_BROADCAST 0x1c 72#define DHCP_NTP_SERVER 0x2a 73#define DHCP_WINS_SERVER 0x2c 74#define DHCP_REQUESTED_IP 0x32 75#define DHCP_LEASE_TIME 0x33 76#define DHCP_OPTION_OVER 0x34 77#define DHCP_MESSAGE_TYPE 0x35 78#define DHCP_SERVER_ID 0x36 79#define DHCP_PARAM_REQ 0x37 80#define DHCP_MESSAGE 0x38 81#define DHCP_MAX_SIZE 0x39 82#define DHCP_T1 0x3a 83#define DHCP_T2 0x3b 84#define DHCP_VENDOR 0x3c 85#define DHCP_CLIENT_ID 0x3d 86 87#define DHCP_END 0xFF 88 89 90#define BOOTREQUEST 1 91#define BOOTREPLY 2 92 93#define ETH_10MB 1 94#define ETH_10MB_LEN 6 95#define DHCPDISCOVER 1 96#define DHCPOFFER 2 97#define DHCPREQUEST 3 98#define DHCPDECLINE 4 99#define DHCPACK 5 100#define DHCPNAK 6 101#define DHCPRELEASE 7 102#define DHCPINFORM 8 103 104#define BROADCAST_FLAG 0x8000 105 106#define OPTION_FIELD 0 107#define FILE_FIELD 1 108#define SNAME_FIELD 2 109 110/* miscellaneous defines */ 111#define MAC_BCAST_ADDR (unsigned char *) "\xff\xff\xff\xff\xff\xff" 112#define OPT_CODE 0 113#define OPT_LEN 1 114#define OPT_DATA 2 115 116#define INIT_SELECTING 0 117#define REQUESTING 1 118#define BOUND 2 119#define RENEWING 3 120#define REBINDING 4 121#define INIT_REBOOT 5 122#define RENEW_REQUESTED 6 123#define RELEASED 7 124#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" 125#define VERSION "0.9.8-pre" 126 127struct client_config_t { 128 char foreground; /* Do not fork */ 129 char quit_after_lease; /* Quit after obtaining lease */ 130 char abort_if_no_lease; /* Abort if no lease */ 131 char background_if_no_lease; /* Fork to background if no lease */ 132 char *interface; /* The name of the interface to use */ 133 char *pidfile; /* Optionally store the process ID */ 134 char *script; /* User script to run at dhcp events */ 135 unsigned char *clientid; /* Optional client id to use */ 136 unsigned char *hostname; /* Optional hostname to use */ 137 int ifindex; /* Index number of the interface to use */ 138 unsigned char arp[6]; /* Our arp address */ 139}; 140 141static struct client_config_t client_config = { 142 /* Default options. */ 143 abort_if_no_lease: 0, 144 foreground: 0, 145 quit_after_lease: 0, 146 background_if_no_lease: 0, 147 interface: "eth0", 148 pidfile: NULL, 149 script: DEFAULT_SCRIPT, 150 clientid: NULL, 151 hostname: NULL, 152 ifindex: 0, 153 arp: "\0\0\0\0\0\0", /* appease gcc-3.0 */ 154}; 155 156struct dhcpMessage { 157 u_int8_t op; 158 u_int8_t htype; 159 u_int8_t hlen; 160 u_int8_t hops; 161 u_int32_t xid; 162 u_int16_t secs; 163 u_int16_t flags; 164 u_int32_t ciaddr; 165 u_int32_t yiaddr; 166 u_int32_t siaddr; 167 u_int32_t giaddr; 168 u_int8_t chaddr[16]; 169 u_int8_t sname[64]; 170 u_int8_t file[128]; 171 u_int32_t cookie; 172 u_int8_t options[308]; /* 312 - cookie */ 173}; 174 175struct udp_dhcp_packet { 176 struct iphdr ip; 177 struct udphdr udp; 178 struct dhcpMessage data; 179}; 180 181#define TYPE_MASK 0x0F 182 183enum { 184 OPTION_IP=1, 185 OPTION_IP_PAIR, 186 OPTION_STRING, 187 OPTION_BOOLEAN, 188 OPTION_U8, 189 OPTION_U16, 190 OPTION_S16, 191 OPTION_U32, 192 OPTION_S32 193}; 194 195#define OPTION_REQ 0x10 /* have the client request this option */ 196#define OPTION_LIST 0x20 /* There can be a list of 1 or more of these */ 197 198struct dhcp_option { 199 char name[10]; 200 char flags; 201 unsigned char code; 202}; 203 204static int state; 205//static unsigned long requested_ip; /* = 0 */ 206//static unsigned long server_addr; 207//static unsigned long timeout; 208//static int packet_num; /* = 0 */ 209static int cfd; 210//static int signal_pipe[2]; 211 212#define LISTEN_NONE 0 213#define LISTEN_KERNEL 1 214#define LISTEN_RAW 2 215static int listen_mode; 216 217/* supported options are easily added here */ 218static struct dhcp_option options[] = { 219 /* name[10] flags code */ 220 {"subnet", OPTION_IP | OPTION_REQ, 0x01}, 221 {"timezone", OPTION_S32, 0x02}, 222 {"router", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x03}, 223 {"timesvr", OPTION_IP | OPTION_LIST, 0x04}, 224 {"namesvr", OPTION_IP | OPTION_LIST, 0x05}, 225 {"dns", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x06}, 226 {"logsvr", OPTION_IP | OPTION_LIST, 0x07}, 227 {"cookiesvr", OPTION_IP | OPTION_LIST, 0x08}, 228 {"lprsvr", OPTION_IP | OPTION_LIST, 0x09}, 229 {"hostname", OPTION_STRING | OPTION_REQ, 0x0c}, 230 {"bootsize", OPTION_U16, 0x0d}, 231 {"domain", OPTION_STRING | OPTION_REQ, 0x0f}, 232 {"swapsvr", OPTION_IP, 0x10}, 233 {"rootpath", OPTION_STRING, 0x11}, 234 {"ipttl", OPTION_U8, 0x17}, 235 {"mtu", OPTION_U16, 0x1a}, 236 {"broadcast", OPTION_IP | OPTION_REQ, 0x1c}, 237 {"ntpsrv", OPTION_IP | OPTION_LIST, 0x2a}, 238 {"wins", OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2c}, 239 {"requestip", OPTION_IP, 0x32}, 240 {"lease", OPTION_U32, 0x33}, 241 {"dhcptype", OPTION_U8, 0x35}, 242 {"serverid", OPTION_IP, 0x36}, 243 {"message", OPTION_STRING, 0x38}, 244 {"tftp", OPTION_STRING, 0x42}, 245 {"bootfile", OPTION_STRING, 0x43}, 246 {"", 0x00, 0x00} 247}; 248 249/* Lengths of the different option types */ 250static int option_lengths[] = { 251 [OPTION_IP] = 4, 252 [OPTION_IP_PAIR] = 8, 253 [OPTION_BOOLEAN] = 1, 254 [OPTION_STRING] = 1, 255 [OPTION_U8] = 1, 256 [OPTION_U16] = 2, 257 [OPTION_S16] = 2, 258 [OPTION_U32] = 4, 259 [OPTION_S32] = 4 260}; 261 262u_int16_t checksum(void *addr, int count); 263 264int listen_socket(unsigned int ip, int port, char *inf); 265 266int raw_socket(int ifindex); 267int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip, int source_port, 268 u_int32_t dest_ip, int dest_port, unsigned char *dest_arp, int ifindex); 269 270unsigned char *get_option(struct dhcpMessage *packet, int code); 271int get_packet(struct dhcpMessage *packet, int fd); 272int get_raw_packet(struct dhcpMessage *payload, int fd); 273int end_option(unsigned char *optionptr); 274 275int add_option_string(unsigned char *optionptr, unsigned char *string); 276 277int add_simple_option(unsigned char *optionptr, unsigned char code, u_int32_t data); 278 279void init_header(struct dhcpMessage *packet, char type); 280 281static void init_packet(struct dhcpMessage *packet, char type); 282 283static void add_requests(struct dhcpMessage *packet); 284 285int send_dhcp_discover(unsigned long xid); 286 287int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp); 288 289unsigned long random_xid(void); 290 291static void change_mode(int new_mode); 292 293 294 295 296 297/********************************** ppp *************************************************/ 298 299#define DEFAULT_IF "eth0" 300#define BPF_BUFFER_IS_EMPTY 1 301#define BPF_BUFFER_HAS_DATA 0 302 303typedef unsigned short UINT16_t; 304 305typedef unsigned int UINT32_t; 306 307/* Ethernet frame types according to RFC 2516 */ 308#define ETH_PPPOE_DISCOVERY 0x8863 309#define ETH_PPPOE_SESSION 0x8864 310 311/* But some brain-dead peers disobey the RFC, so frame types are variables */ 312 313static UINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; 314static UINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; 315 316/* PPPoE codes */ 317#define CODE_PADI 0x09 318#define CODE_PADO 0x07 319#define CODE_PADR 0x19 320#define CODE_PADS 0x65 321#define CODE_PADT 0xA7 322 323/* Extensions from draft-carrel-info-pppoe-ext-00 */ 324/* I do NOT like PADM or PADN, but they are here for completeness */ 325#define CODE_PADM 0xD3 326#define CODE_PADN 0xD4 327 328#define CODE_SESS 0x00 329 330/* PPPoE Tags */ 331#define TAG_END_OF_LIST 0x0000 332#define TAG_SERVICE_NAME 0x0101 333#define TAG_AC_NAME 0x0102 334#define TAG_HOST_UNIQ 0x0103 335#define TAG_AC_COOKIE 0x0104 336#define TAG_VENDOR_SPECIFIC 0x0105 337#define TAG_RELAY_SESSION_ID 0x0110 338#define TAG_SERVICE_NAME_ERROR 0x0201 339#define TAG_AC_SYSTEM_ERROR 0x0202 340#define TAG_GENERIC_ERROR 0x0203 341 342/* Extensions from draft-carrel-info-pppoe-ext-00 */ 343/* I do NOT like these tags one little bit */ 344#define TAG_HURL 0x111 345#define TAG_MOTM 0x112 346#define TAG_IP_ROUTE_ADD 0x121 347/* Discovery phase states */ 348#define STATE_SENT_PADI 0 349#define STATE_RECEIVED_PADO 1 350#define STATE_SENT_PADR 2 351#define STATE_SESSION 3 352#define STATE_TERMINATED 4 353 354/* How many PADI/PADS attempts? */ 355#define MAX_PADI_ATTEMPTS 3 356 357/* Initial timeout for PADO/PADS */ 358#define PADI_TIMEOUT 5 359/* States for scanning PPP frames */ 360#define STATE_WAITFOR_FRAME_ADDR 0 361#define STATE_DROP_PROTO 1 362#define STATE_BUILDING_PACKET 2 363 364/* Special PPP frame characters */ 365#define FRAME_ESC 0x7D 366#define FRAME_FLAG 0x7E 367#define FRAME_ADDR 0xFF 368#define FRAME_CTRL 0x03 369#define FRAME_ENC 0x20 370 371#define IPV4ALEN 4 372#define SMALLBUF 256 373 374/* A PPPoE Packet, including Ethernet headers */ 375typedef struct PPPoEPacketStruct { 376 struct ethhdr ethHdr; /* Ethernet header */ 377//#ifdef PACK_BITFIELDS_REVERSED 378// unsigned int type:4; /* PPPoE Type (must be 1) */ 379// unsigned int ver:4; /* PPPoE Version (must be 1) */ 380//#else 381 unsigned int ver:4; /* PPPoE Version (must be 1) */ 382 unsigned int type:4; /* PPPoE Type (must be 1) */ 383//#endif 384 unsigned int code:8; /* PPPoE code */ 385 unsigned int session:16; /* PPPoE session */ 386 unsigned int length:16; /* Payload length */ 387 unsigned char payload[ETH_DATA_LEN]; /* A bit of room to spare */ 388} PPPoEPacket; 389 390/* Header size of a PPPoE packet */ 391#define PPPOE_OVERHEAD 6 /* type, code, session, length */ 392#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD) 393#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD) 394#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - 2) 395 396/* PPPoE Tag */ 397 398typedef struct PPPoETagStruct { 399 unsigned int type:16; /* tag type */ 400 unsigned int length:16; /* Length of payload */ 401 unsigned char payload[ETH_DATA_LEN]; /* A LOT of room to spare */ 402} PPPoETag; 403 404/* Header size of a PPPoE tag */ 405#define TAG_HDR_SIZE 4 406 407/* Chunk to read from stdin */ 408#define READ_CHUNK 4096 409 410/* Function passed to parsePacket */ 411typedef void ParseFunc(UINT16_t type, 412 UINT16_t len, 413 unsigned char *data, 414 void *extra); 415 416#define PPPINITFCS16 0xffff /* Initial FCS value */ 417 418/* Keep track of the state of a connection -- collect everything in 419 one spot */ 420 421typedef struct PPPoEConnectionStruct { 422 int discoveryState; /* Where we are in discovery */ 423 int discoverySocket; /* Raw socket for discovery frames */ 424 int sessionSocket; /* Raw socket for session frames */ 425 unsigned char myEth[ETH_ALEN]; /* My MAC address */ 426 unsigned char peerEth[ETH_ALEN]; /* Peer's MAC address */ 427 UINT16_t session; /* Session ID */ 428 char *ifName; /* Interface name */ 429 char *serviceName; /* Desired service name, if any */ 430 char *acName; /* Desired AC name, if any */ 431 int synchronous; /* Use synchronous PPP */ 432 int useHostUniq; /* Use Host-Uniq tag */ 433 int printACNames; /* Just print AC names */ 434 int skipDiscovery; /* Skip discovery */ 435 int noDiscoverySocket; /* Don't even open discovery socket */ 436 int killSession; /* Kill session and exit */ 437 FILE *debugFile; /* Debug file for dumping packets */ 438 int numPADOs; /* Number of PADO packets received */ 439 PPPoETag cookie; /* We have to send this if we get it */ 440 PPPoETag relayId; /* Ditto */ 441} PPPoEConnection; 442/* Structure used to determine acceptable PADO or PADS packet */ 443struct PacketCriteria { 444 PPPoEConnection *conn; 445 int acNameOK; 446 int serviceNameOK; 447 int seenACName; 448 int seenServiceName; 449}; 450 451#define CHECK_ROOM(cursor, start, len) \ 452do {\ 453 if (((cursor)-(start))+(len) > MAX_PPPOE_PAYLOAD) { \ 454 fprintf(stderr, "Would create too-long packet\n"); \ 455 return; \ 456 } \ 457} while(0) 458 459/* True if Ethernet address is broadcast or multicast */ 460#define NOT_UNICAST(e) ((e[0] & 0x01) != 0) 461#define BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) == 0xFF) 462#define NOT_BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) != 0xFF) 463 464static char const RCSID[] = 465"$Id: dp.h,v 1.1.1.1 2008/10/15 03:31:33 james26_jang Exp $"; 466 467 468char *strDup(char const *str); 469 470#define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0); 471 472int 473openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr); 474 475void 476dumpHex(FILE *fp, unsigned char const *buf, int len); 477 478UINT16_t 479etherType(PPPoEPacket *packet); 480 481//void 482//dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir); 483 484int 485parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra); 486 487void 488parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, 489 void *extra); 490 491int 492packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet); 493 494void 495parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, 496 void *extra); 497 498int 499sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size); 500 501int 502receivePacket(int sock, PPPoEPacket *pkt, int *size); 503 504void 505sendPADI(PPPoEConnection *conn); 506 507void 508waitForPADO(PPPoEConnection *conn, int timeout); 509 510void 511discovery(PPPoEConnection *conn); 512 513int discover_all(); 514