1/* 2 * pppoe, a PPP-over-Ethernet redirector 3 * Copyright (C) 1999 Luke Stras <stras@ecf.toronto.edu> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * 19 * Revision History 20 * 1999/09/22 stras Initial version 21 * 1999/09/24 stras Changed header files for greater portability 22 * 1999/10/02 stras Added more logging, bug fixes 23 * 1999/10/02 mr Port to bpf/OpenBSD; starvation fixed; efficiency fixes 24 * 1999/10/18 stras added BUGGY_AC code, partial forwarding 25 */ 26 27#include <sys/types.h> 28/* foxconn wklin added start, 07/26/2007 */ 29#include <sys/stat.h> 30/* foxconn wklin added end, 07/26/2007 */ 31#include <sys/socket.h> 32#include <netinet/in.h> 33#include <sys/time.h> /* wklin added, 01/10/2007 */ 34/* Foxconn modified start Winster Chan 11/25/2005 */ 35/* #include <net/if.h> */ 36#include "pppoe.h" 37/* Foxconn modified end Winster Chan 11/25/2005 */ 38#include <sys/sysinfo.h> /*added by EricHuang, 01/11/2007*/ 39 40#ifdef __linux__ 41#include <net/if_arp.h> 42#endif /* __linux__ */ 43#if defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ < 6 44#include <linux/if_ether> 45#else 46#include <netinet/if_ether.h> 47#endif 48 49#include <assert.h> 50#ifdef __linux__ 51#include <getopt.h> 52#endif 53#include <signal.h> 54#include <stdio.h> 55#include <stdlib.h> 56#include <string.h> 57#include <unistd.h> 58 59/* #include <sys/time.h> */ 60#include <time.h> 61#include <sys/ioctl.h> 62#include <sys/wait.h> 63 64 65#ifdef USE_BPF 66#ifndef ETH_ALEN 67#define ETH_ALEN 6 68#endif /* ETH_ALEN */ 69/* set this to desired size - you may not get this */ 70int bpf_buf_size = 65536; 71#include <net/bpf.h> 72#include <fcntl.h> 73#include <nlist.h> 74#include <kvm.h> 75unsigned char local_ether[ETH_ALEN]; /* need to this filter packets */ 76#endif /* USE_BPF */ 77 78#include <errno.h> 79#ifdef __linux__ 80extern int errno; 81#endif 82 83/* used as the size for a packet buffer */ 84/* should be > 2 * size of max packet size */ 85#define PACKETBUF (4096 + 30) 86/* Foxconn added start Winster Chan 11/25/2005 */ 87#define TAGBUF 128 88/* Foxconn added end Winster Chan 11/25/2005 */ 89 90/* Foxconn added start, Winster Chan, 06/26/2006 */ 91static int poxfd = -1; 92static int pppfd = -1; 93unsigned short sessId = 0; 94char dstMac[ETH_ALEN]; 95/* Foxconn added start, Winster Chan, 06/26/2006 */ 96 97char *service_name = NULL; /* foxconn wklin added, 03/27/2007 */ 98 99#define VERSION_MAJOR 0 100#define VERSION_MINOR 3 101 102/* references: RFC 2516 */ 103/* ETHER_TYPE fields for PPPoE */ 104 105#define ETH_P_PPPOE_DISC 0x8863 /* discovery stage */ 106#define ETH_P_PPPOE_SESS 0x8864 /* session stage */ 107 108/* ethernet broadcast address */ 109#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff" 110 111/* PPPoE packet; includes Ethernet headers and such */ 112struct pppoe_packet { 113#ifdef __linux__ 114 struct ethhdr ethhdr; /* ethernet header */ 115#else 116 struct ether_header ethhdr; /* ethernet header */ 117#endif 118 unsigned int ver:4; /* pppoe version */ 119 unsigned int type:4; /* pppoe type */ 120 unsigned int code:8; /* pppoe code CODE_* */ 121 unsigned int session:16; /* session id */ 122 unsigned short length; /* payload length */ 123 /* payload follows */ 124}; 125 126/* maximum payload length */ 127#define MAX_PAYLOAD (1484 - sizeof(struct pppoe_packet)) 128 129/* PPPoE codes */ 130#define CODE_SESS 0x00 /* PPPoE session */ 131#define CODE_PADI 0x09 /* PPPoE Active Discovery Initiation */ 132#define CODE_PADO 0x07 /* PPPoE Active Discovery Offer */ 133#define CODE_PADR 0x19 /* PPPoE Active Discovery Request */ 134#define CODE_PADS 0x65 /* PPPoE Active Discovery Session-confirmation */ 135#define CODE_PADT 0xa7 /* PPPoE Active Discovery Terminate */ 136 137/* also need */ 138#define STATE_RUN (-1) 139 140/* PPPoE tag; the payload is a sequence of these */ 141struct pppoe_tag { 142 unsigned short type; /* tag type TAG_* */ 143 unsigned short length; /* tag length */ 144 /* payload follows */ 145} __attribute__ ((packed)); /*added by EricHuang, 07/23/2007*/ 146 147/* Foxconn added start Winster Chan 11/25/2005 */ 148#define TAG_STRUCT_SIZE sizeof(struct pppoe_tag) 149#define PPP_PPPOE_SESSION "/tmp/ppp/pppoe_session" 150#define PPP_PPPOE2_SESSION "/tmp/ppp/pppoe2_session" 151/*#define PPP_PPPOE_IFNAME "/tmp/ppp/pppoe_ifname"*/ 152/* Foxconn added end Winster Chan 11/25/2005 */ 153 154/* PPPoE tag types */ 155#define TAG_END_OF_LIST 0x0000 156#define TAG_SERVICE_NAME 0x0101 157#define TAG_AC_NAME 0x0102 158#define TAG_HOST_UNIQ 0x0103 159#define TAG_AC_COOKIE 0x0104 160#define TAG_VENDOR_SPECIFIC 0x0105 161#define TAG_RELAY_SESSION_ID 0x0110 162#define TAG_SERVICE_NAME_ERROR 0x0201 163#define TAG_AC_SYSTEM_ERROR 0x0202 164#define TAG_GENERIC_ERROR 0x0203 165 166/* globals */ 167int opt_verbose = 0; /* logging */ 168int opt_fwd = 0; /* forward invalid packets */ 169int opt_fwd_search = 0; /* search for next packet when forwarding */ 170#ifdef MULTIPLE_PPPOE 171#define log_file stderr 172#else 173FILE *log_file = NULL; 174#endif 175FILE *error_file = NULL; 176#ifdef MULTIPLE_PPPOE 177int ppp_ifunit = 0; /* foxconn wklin added, 08/16/2007 */ 178#endif 179pid_t sess_listen = 0, pppd_listen = 0; /* child processes */ 180int disc_sock = 0, sess_sock = 0; /* PPPoE sockets */ 181char src_addr[ETH_ALEN]; /* source hardware address */ 182char dst_addr[ETH_ALEN]; /* destination hardware address */ 183char *if_name = NULL; /* interface to use */ 184int session = 0; /* identifier for our session */ 185int clean_child = 0; /* flag set when SIGCHLD received */ 186/* Foxconn added start Winster Chan 11/25/2005 */ 187char pado_tags[TAGBUF]; /* TAGs of PADO */ 188int pado_tag_size = 0; 189typedef struct { 190 unsigned short usPadLen; /* Tag length in type of unsigned short */ 191 int nPadLen; /* Tag length in type of integer */ 192 char *pPadStart; /* Start point of tag payload */ 193} sPadxTag, *pPadxTag; 194/* Foxconn added end Winster Chan 11/25/2005 */ 195#ifdef NEW_WANDETECT 196int bWanDetect = 0;/* Foxconn added by Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 197#endif 198 199/* Winster Chan debugtest */ 200#define DEBUG_PRINT_PACKET 0 201#define DEBUG_SEND_PACKET 0 202#define BUFRING 5 /* 40 */ /* foxconn wklin modified, 08/13/2007 */ 203#define DEBUG_PRINT 0 204#define PPPOE_DEBUG_FILE "/tmp/ppp/pppoeDbg" 205FILE *fp0; 206pid_t main_pid, sess_pid, pppd_pid; 207 208 209typedef struct { 210 /* unsigned char *pBufAddr; */ 211 unsigned char packetBuf[PACKETBUF]; 212} sPktBuf, *pPktBuf; 213 214void 215print_hex(unsigned char *buf, int len) 216{ 217 int i; 218 219 if (opt_verbose == 0) 220 return; 221 222 for (i = 0; i < len; i++) 223 fprintf(log_file, "%02x ", (unsigned char)*(buf+i)); 224 225 fprintf(log_file, "\n"); 226} 227 228void 229print_packet(struct pppoe_packet *p) 230{ 231 int i; 232 struct pppoe_tag *t = (struct pppoe_tag*)(p + 1); 233 struct pppoe_tag tag; /* needed to avoid alignment problems */ 234 char *buf; 235 time_t tm; 236 237 if (opt_verbose == 0) 238 return; 239 240 time(&tm); 241 242 fprintf(log_file, "Ethernet header:\n"); 243 fprintf(log_file, "h_dest: "); 244#ifdef __linux__ 245 for (i = 0; i < 6; i++) 246 fprintf(log_file, "%02x:", (unsigned)p->ethhdr.h_dest[i]); 247#else 248 for (i = 0; i < 6; i++) 249 fprintf(log_file, "%02x:", (unsigned)p->ethhdr.ether_dhost[i]); 250#endif 251 fprintf(log_file, "\nh_source: "); 252#ifdef __linux__ 253 for (i = 0; i < 6; i++) 254 fprintf(log_file, "%02x:", (unsigned)p->ethhdr.h_source[i]); 255#else 256 for (i = 0; i < 6; i++) 257 fprintf(log_file, "%02x:", (unsigned)p->ethhdr.ether_shost[i]); 258#endif 259 260#ifdef __linux__ 261 fprintf(log_file, "\nh_proto: 0x%04x ", 262 (unsigned)ntohs(p->ethhdr.h_proto)); 263#else 264 fprintf(log_file, "\nh_proto: 0x%04x ", 265 (unsigned)ntohs(p->ethhdr.ether_type)); 266#endif 267 268#ifdef __linux__ 269 switch((unsigned)ntohs(p->ethhdr.h_proto)) 270#else 271 switch((unsigned)ntohs(p->ethhdr.ether_type)) 272#endif 273 { 274 case ETH_P_PPPOE_DISC: 275 fprintf(log_file, "(PPPOE Discovery)\n"); 276 break; 277 case ETH_P_PPPOE_SESS: 278 fprintf(log_file, "(PPPOE Session)\n"); 279 break; 280 default: 281 fprintf(log_file, "(Unknown)\n"); 282 } 283 284 fprintf(log_file, "PPPoE header: \nver: 0x%01x type: 0x%01x code: 0x%02x " 285 "session: 0x%04x length: 0x%04x ", (unsigned)p->ver, 286 (unsigned)p->type, (unsigned)p->code, (unsigned)p->session, 287 (unsigned)ntohs(p->length)); 288 289 switch(p->code) 290 { 291 case CODE_PADI: 292 fprintf(log_file, "(PADI)\n"); 293 break; 294 case CODE_PADO: 295 fprintf(log_file, "(PADO)\n"); 296 break; 297 case CODE_PADR: 298 fprintf(log_file, "(PADR)\n"); 299 break; 300 case CODE_PADS: 301 fprintf(log_file, "(PADS)\n"); 302 break; 303 case CODE_PADT: 304 fprintf(log_file, "(PADT)\n"); 305 break; 306 default: 307 fprintf(log_file, "(Unknown)\n"); 308 } 309 310#ifdef __linux__ 311 if (ntohs(p->ethhdr.h_proto) != ETH_P_PPPOE_DISC) 312#else 313 if (ntohs(p->ethhdr.ether_type) != ETH_P_PPPOE_DISC) 314#endif 315 { 316 print_hex((unsigned char *)(p+1), ntohs(p->length)); 317 return; 318 } 319 320 321 while (t < (struct pppoe_tag *)((char *)(p+1) + ntohs(p->length))) 322 { 323 /* no guarantee in PPPoE spec that t is aligned at all... */ 324 memcpy(&tag,t,sizeof(tag)); 325 fprintf(log_file, "PPPoE tag:\ntype: %04x length: %04x ", 326 ntohs(tag.type), ntohs(tag.length)); 327 switch(ntohs(tag.type)) 328 { 329 case TAG_END_OF_LIST: 330 fprintf(log_file, "(End of list)\n"); 331 break; 332 case TAG_SERVICE_NAME: 333 fprintf(log_file, "(Service name)\n"); 334 break; 335 case TAG_AC_NAME: 336 fprintf(log_file, "(AC Name)\n"); 337 break; 338 case TAG_HOST_UNIQ: 339 fprintf(log_file, "(Host Uniq)\n"); 340 break; 341 case TAG_AC_COOKIE: 342 fprintf(log_file, "(AC Cookie)\n"); 343 break; 344 case TAG_VENDOR_SPECIFIC: 345 fprintf(log_file, "(Vendor Specific)\n"); 346 break; 347 case TAG_RELAY_SESSION_ID: 348 fprintf(log_file, "(Relay Session ID)\n"); 349 break; 350 case TAG_SERVICE_NAME_ERROR: 351 fprintf(log_file, "(Service Name Error)\n"); 352 break; 353 case TAG_AC_SYSTEM_ERROR: 354 fprintf(log_file, "(AC System Error)\n"); 355 break; 356 case TAG_GENERIC_ERROR: 357 fprintf(log_file, "(Generic Error)\n"); 358 break; 359 default: 360 fprintf(log_file, "(Unknown)\n"); 361 } 362 if (ntohs(tag.length) > 0) { 363 switch (ntohs(tag.type)) 364 { 365 case TAG_SERVICE_NAME: 366 case TAG_AC_NAME: 367 case TAG_SERVICE_NAME_ERROR: 368 case TAG_AC_SYSTEM_ERROR: 369 case TAG_GENERIC_ERROR: /* ascii data */ 370 buf = malloc(ntohs(tag.length) + 1); 371 memset(buf, 0, ntohs(tag.length)+1); 372 strncpy(buf, (char *)(t+1), ntohs(tag.length)); 373 buf[ntohs(tag.length)] = '\0'; 374 fprintf(log_file, "data (UTF-8): %s\n", buf); 375 free(buf); 376 break; 377 378 case TAG_HOST_UNIQ: 379 case TAG_AC_COOKIE: 380 case TAG_RELAY_SESSION_ID: 381 fprintf(log_file, "data (bin): "); 382 for (i = 0; i < ntohs(tag.length); i++) 383 fprintf(log_file, "%02x", (unsigned)*((char *)(t+1) + i)); 384 fprintf(log_file, "\n"); 385 break; 386 387 default: 388 fprintf(log_file, "unrecognized data\n"); 389 } 390 t = (struct pppoe_tag *)((char *)(t+1)+ntohs(tag.length)); 391 } 392 } 393} 394 395/* Foxconn added start, Winster Chan, 06/26/2006 */ 396#ifndef MULTIPLE_PPPOE 397/************************************************************************** 398** Function: addr_itox() 399** Description: Convert the <int> address value getting from file to 400** <unsigned char> address type. 401** Parameters: (unsigned char *) daddr -- destination address value 402** (int *) saddr -- source address value 403** (int) convlen -- convert length 404** Return: none. 405**************************************************************************/ 406static void addr_itox(unsigned char *daddr, int *saddr, int convlen) 407{ 408 int i; 409 410 for (i = 0; i < convlen; i++) 411 daddr[i] = (unsigned char)saddr[i]; 412} 413#endif 414/************************************************************************** 415** Function: pptp_pppox_open() 416** Description: Open socket to kernel pppox driver, and open ppp device 417** Parameters: (int *) poxfd -- pointer of file descriptor for pppox 418** (int *) pppfd -- pointer of file descriptor for ppp device 419** Return: none. 420**************************************************************************/ 421void pptp_pppox_open(int *poxfd, int *pppfd) 422{ 423#ifdef MULTIPLE_PPPOE 424 /* Open socket to pppox kernel module */ 425 426 *poxfd = socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_OE); 427 if (*poxfd >= 0) 428 { 429 /* Open ppp device */ 430 *pppfd = open("/dev/ppp", O_RDWR); 431 if (*pppfd < 0) 432 { /* on error */ 433 fprintf(stderr, "pppoe: error opening pppfd.\n"); 434 close(*poxfd); 435 } 436 else 437 return; 438 } 439 else 440 { 441 fprintf(stderr, "pppoe: error opening poxfd.\n"); 442 } 443 *poxfd = -1; 444 *pppfd = -1; 445#else 446 /* Open socket to pppox kernel module */ 447 *poxfd = socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_OE); 448 if (*poxfd >= 0) { 449 /* Open ppp device */ 450 *pppfd = open("/dev/ppp", O_RDWR); 451 } 452 else { 453 *poxfd = -1; 454 *pppfd = -1; 455 } 456#endif 457} 458 459/************************************************************************** 460** Function: pptp_pppox_get_info() 461** Description: Get the essential information for connecting pptp kernel 462** module. Such as Source IP, Destination IP, Remote MAC 463** address, Device name, call_id, and peer_call_id, etc. 464** Parameters: none. 465** Return: (struct sockaddr_pppox)sp_info -- structure of information. 466**************************************************************************/ 467struct sockaddr_pppox pptp_pppox_get_info(void) 468{ 469 struct sockaddr_pppox sp_info; 470 char devName[16]; 471 strcpy(devName, if_name); 472 memset(&sp_info, 0, sizeof(struct sockaddr_pppox)); 473 sp_info.sa_family = AF_PPPOX; 474 sp_info.sa_protocol = PX_PROTO_OE; 475 sp_info.sa_addr.pppoe.sid = sessId; /* PPPoE session ID */ 476 memcpy(sp_info.sa_addr.pppoe.remote, dstMac, ETH_ALEN); /* Remote MAC address */ 477 memcpy(sp_info.sa_addr.pppoe.dev, devName, strlen(devName)); 478 479 return sp_info; 480} 481 482/************************************************************************** 483** Function: pptp_pppox_connect() 484** Description: Actually connect to pppox kernel module with the structure 485** got by pptp_pppox_get_info(). 486** Parameters: (int *) poxfd -- pointer of file descriptor for pppox 487** (int *) pppfd -- pointer of file descriptor for ppp device 488** Return: (int)err -- Fail = -1 489** Success = 0. 490**************************************************************************/ 491/* foxconn wklin modified start, 07/31/2007 */ 492int pptp_pppox_connect(int *poxfd, int *pppfd) 493{ 494 struct sockaddr_pppox lsp; 495 int err = -1; 496 int chindex; 497 int flags; 498 499 memset(&lsp, 0, sizeof(struct sockaddr_pppox)); 500 lsp = pptp_pppox_get_info(); 501 502 if (*poxfd >= 0) { 503 /* Connect pptp kernel connection */ 504 err = connect(*poxfd, (struct sockaddr*)&lsp, 505 sizeof(struct sockaddr_pppox)); 506 if (err == 0) { 507 /* Get PPP channel */ 508 if (ioctl(*poxfd, PPPIOCGCHAN, &chindex) == -1) { 509 fprintf(stderr, "Couldn't get channel number"); 510 return -1; 511 } 512 513 if (*pppfd >= 0) { 514 /* Attach to PPP channel */ 515 if ((err = ioctl(*pppfd, PPPIOCATTCHAN, &chindex)) < 0) { 516 fprintf(stderr, "Couldn't attach to channel"); 517 return -1; 518 } 519#ifdef MULTIPLE_PPPOE 520 if (ioctl(*pppfd, PPPIOCCONNECT, &ppp_ifunit) < 0) { 521 fprintf(stderr, "Couldn't attach to PPP unit %d.\n", ppp_ifunit); 522 return -1; 523 } 524#endif 525 flags = fcntl(*pppfd, F_GETFL); 526 if (flags == -1 || fcntl(*pppfd, F_SETFL, flags | O_NONBLOCK) == -1) { 527 fprintf(stderr, "Couldn't set /dev/ppp (channel) to nonblock"); 528 return -1; 529 } 530 } 531 else { 532 fprintf(stderr, "Couldn't reopen /dev/ppp"); 533 return -1; 534 } 535 } 536 else { 537 fprintf(stderr, "Couldn't connect pppox, err: %d, %s", err, strerror(errno)); 538 return -1; 539 } 540 } 541 return 0; 542} 543/* foxconn wklin modified end, 07/31/2007 */ 544 545/************************************************************************** 546** Function: pptp_pppox_release() 547** Description: Release the connection between user program and pppox kernel 548** driver with ioctl() and connect(), and clear the 549** essential information in kernel. 550** Parameters: (int *) poxfd -- pointer of file descriptor for pppox 551** (int *) pppfd -- pointer of file descriptor for ppp device 552** Return: (int)err -- Fail = -1 553** Success = 0. 554**************************************************************************/ 555void pptp_pppox_release(int *poxfd, int *pppfd) 556{ 557 struct sockaddr_pppox lsp; 558 int err = -1; 559 560 if (*poxfd >= 0) { 561 memset(&lsp, 0, sizeof(struct sockaddr_pppox)); 562 lsp = pptp_pppox_get_info(); 563 if (*pppfd >= 0) { 564 /* Detach from PPP */ 565 if (ioctl(*pppfd, PPPIOCDETACH) < 0) 566 ; /* fprintf(stderr, "pptp_pppox_release ioctl(PPPIOCDETACH) 567 failed\n"); */ /* foxconn wklin removed, 07/26/2007 */ 568 } 569 570 /* Release pptp kernel connection */ 571 lsp.sa_addr.pppoe.sid = 0; 572 err = connect(*poxfd, (struct sockaddr*)&lsp, 573 sizeof(struct sockaddr_pppox)); 574 if (err != 0) 575 fprintf(stderr, "Couldn't connect to pptp kernel module\n"); 576 } 577 else 578 fprintf(stderr, "Couldn't connect socket to pppox\n"); 579} 580/* Foxconn added end, Winster Chan, 06/26/2006 */ 581 582int 583open_interface(char *if_name, unsigned short type, char *hw_addr) 584{ 585 int optval = 1, rv; 586 struct ifreq ifr; 587 588 if ((rv = socket(PF_INET, SOCK_PACKET, htons(type))) < 0) { 589 perror("pppoe: socket"); 590 return -1; 591 } 592 593 if (setsockopt(rv, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { 594 perror("pppoe: setsockopt"); 595 return -1; 596 } 597 598 if (hw_addr != NULL) { 599 strncpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); 600 601 if (ioctl(rv, SIOCGIFHWADDR, &ifr) < 0) { 602 perror("pppoe: ioctl(SIOCGIFHWADDR)"); 603 return -1; 604 } 605 606 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { 607 fprintf(error_file, "pppoe: interface %s is not Ethernet!\n", if_name); 608 return -1; 609 } 610 memcpy(hw_addr, ifr.ifr_hwaddr.sa_data, sizeof(ifr.ifr_hwaddr.sa_data)); 611 } 612 return rv; 613} 614 615/* Foxconn added start Winster Chan 12/02/2005 */ 616int 617get_padx_tag(struct pppoe_tag *pTag, int nLen, pPadxTag pTagStruc, const unsigned short tagType) 618{ 619 int bExitLoop = 0, nSearchLen = 0, bTagFound = 0; 620 struct pppoe_tag *pNextTag; 621 622 pTagStruc->usPadLen = 0; 623 pTagStruc->nPadLen = 0; 624 pTagStruc->pPadStart = NULL; 625 626 while (!bExitLoop && (nSearchLen < nLen)) { 627 if (htons(pTag->type) == tagType) { 628 pTagStruc->usPadLen = pTag->length; 629 pTagStruc->nPadLen = (int)(htons(pTag->length)); 630 pTagStruc->pPadStart = (char *)pTag + TAG_STRUCT_SIZE; 631 bExitLoop = 1; 632 bTagFound = 1; 633 } 634 else { 635 pNextTag = (struct pppoe_tag *)((char *)pTag + 636 (TAG_STRUCT_SIZE + (int)(htons(pTag->length)))); 637 nSearchLen += (int)((TAG_STRUCT_SIZE + (int)(htons(pTag->length)))); 638 pTag = pNextTag; 639 } 640 } 641 642 return bTagFound; 643} 644/* Foxconn added end Winster Chan 12/02/2005 */ 645 646int 647create_padi(struct pppoe_packet *packet, const char *src, const char *name) 648{ 649 int size; 650 651 if (packet == NULL) 652 return 0; 653 654 /* printf("Winster: create_padi\n"); */ 655 656 size = sizeof(struct pppoe_packet) + sizeof(struct pppoe_tag); 657 if (name != NULL) 658 size += strlen(name); 659 660#ifdef __linux__ 661 memcpy(packet->ethhdr.h_dest, MAC_BCAST_ADDR, 6); 662 memcpy(packet->ethhdr.h_source, src, 6); 663 packet->ethhdr.h_proto = htons(ETH_P_PPPOE_DISC); 664#else 665 memcpy(packet->ethhdr.ether_dhost, MAC_BCAST_ADDR, 6); 666 memcpy(packet->ethhdr.ether_shost, src, 6); 667 packet->ethhdr.ether_type = htons(ETH_P_PPPOE_DISC); 668#endif 669 packet->ver = 1; 670 packet->type = 1; 671 packet->code = CODE_PADI; 672 packet->session = 0; 673 packet->length = htons(size - sizeof(struct pppoe_packet)); 674 675 /* fill out a blank service-name tag */ 676 (*(struct pppoe_tag *)(packet+1)).type = htons(TAG_SERVICE_NAME); 677 (*(struct pppoe_tag *)(packet+1)).length = name ? htons(strlen(name)) : 0; 678 if (name != NULL) 679 memcpy((char *)(packet + 1) + sizeof(struct pppoe_tag), name, 680 strlen(name)); 681 682 return size; 683} 684 685int 686create_padr(struct pppoe_packet *packet, const char *src, const char *dst, 687 char *name) 688{ 689 int size; 690 /* Foxconn added start Winster Chan 11/25/2005 */ 691 char *pCookieStart = NULL; 692 int nCookieSize = 0; 693 int nNameSize = 0; 694 unsigned short usCookieSize = 0; 695 sPadxTag sTag; 696 /* Foxconn added end Winster Chan 11/25/2005 */ 697 /* Foxconn add start, Max Ding, 09/22/2008 for @add TAG_RELAY_SESSION_ID */ 698 char *pRelaySessionIdStart = NULL; 699 int nRelaySessionIdSize = 0; 700 unsigned short usRelaySessionIdSize = 0; 701 char *pPacketPoint = packet; 702 /* Foxconn add end, Max Ding, 09/22/2008 */ 703 704 if (packet == NULL) 705 return 0; 706 707 size = sizeof(struct pppoe_packet) + TAG_STRUCT_SIZE; 708 if (name != NULL) { 709 size += strlen(name); 710 /* Foxconn added start Winster Chan 11/25/2005 */ 711 nNameSize = strlen(name); 712 /* Foxconn added end Winster Chan 11/25/2005 */ 713 } 714 715 /* Foxconn added start Winster Chan 12/02/2005 */ 716 /* Add length of AC cookie to packet size */ 717 if (get_padx_tag((struct pppoe_tag *)pado_tags, pado_tag_size, &sTag, TAG_AC_COOKIE)) { 718 nCookieSize = sTag.nPadLen; 719 usCookieSize = sTag.usPadLen; 720 pCookieStart = sTag.pPadStart; 721 size += (int)(TAG_STRUCT_SIZE + sTag.nPadLen); 722 } 723 /* Foxconn added end Winster Chan 12/02/2005 */ 724 /* Foxconn add start, Max Ding, 09/22/2008 for @add TAG_RELAY_SESSION_ID */ 725 if (get_padx_tag((struct pppoe_tag *)pado_tags, pado_tag_size, &sTag, TAG_RELAY_SESSION_ID)) { 726 nRelaySessionIdSize = sTag.nPadLen; 727 usRelaySessionIdSize = sTag.usPadLen; 728 pRelaySessionIdStart = sTag.pPadStart; 729 size += (int)(TAG_STRUCT_SIZE + sTag.nPadLen); 730 } 731 /* Foxconn add end, Max Ding, 09/22/2008 */ 732 733#ifdef __linux__ 734 memcpy(packet->ethhdr.h_dest, dst, 6); 735 memcpy(packet->ethhdr.h_source, src, 6); 736 packet->ethhdr.h_proto = htons(ETH_P_PPPOE_DISC); 737#else 738 memcpy(packet->ethhdr.ether_dhost, dst, 6); 739 memcpy(packet->ethhdr.ether_shost, src, 6); 740 packet->ethhdr.ether_type = htons(ETH_P_PPPOE_DISC); 741#endif 742 packet->ver = 1; 743 packet->type = 1; 744 packet->code = CODE_PADR; 745 packet->session = 0; 746 packet->length = htons(size - sizeof(struct pppoe_packet)); 747 748 /* fill out a blank service-name tag */ 749 (*(struct pppoe_tag *)(packet+1)).type = htons(TAG_SERVICE_NAME); 750 (*(struct pppoe_tag *)(packet+1)).length = name ? htons(strlen(name)) : 0; 751 if (name != NULL) 752 memcpy((char *)(packet + 1) + TAG_STRUCT_SIZE, name, 753 strlen(name)); 754 755 pPacketPoint = (char *)(packet+1)+TAG_STRUCT_SIZE+nNameSize;/* Foxconn added by Max Ding, 09/23/2008 @add TAG_RELAY_SESSION_ID */ 756 /* foxconn modified start, wklin, 03/27/2007, winster doesn't count name len */ 757 /* Foxconn added start Winster Chan 11/25/2005 */ 758 /* fill out the AC cookie tag from PADO */ 759 if (nCookieSize > 0) { 760 (*(struct pppoe_tag *)((char *)(packet+1)+TAG_STRUCT_SIZE+ 761 nNameSize)).type = htons(TAG_AC_COOKIE); 762 (*(struct pppoe_tag *)((char *)(packet+1)+TAG_STRUCT_SIZE+ 763 nNameSize)).length = usCookieSize; 764 memcpy((char *)(packet+1)+(2*TAG_STRUCT_SIZE)+nNameSize, 765 (char *)pCookieStart, nCookieSize); 766 pPacketPoint = (char *)(packet+1)+(2*TAG_STRUCT_SIZE)+nNameSize+nCookieSize;/* Foxconn added by Max Ding, 09/23/2008 @add TAG_RELAY_SESSION_ID */ 767 } 768 /* Foxconn added end Winster Chan 11/25/2005 */ 769 /* foxconn modified end, wklin, 03/27/2007 */ 770 /* Foxconn add start, Max Ding, 09/22/2008 for @add TAG_RELAY_SESSION_ID */ 771 if (nRelaySessionIdSize > 0) { 772 (*(struct pppoe_tag *)(pPacketPoint)).type = htons(TAG_RELAY_SESSION_ID); 773 (*(struct pppoe_tag *)(pPacketPoint)).length = usRelaySessionIdSize; 774 memcpy((pPacketPoint+TAG_STRUCT_SIZE), 775 (char *)pRelaySessionIdStart, nRelaySessionIdSize); 776 pPacketPoint += TAG_STRUCT_SIZE + nRelaySessionIdSize; 777 } 778 /* Foxconn add end, Max Ding, 09/22/2008 */ 779 780 memset(((char *)packet) + size, 0, 14); 781 return size; 782} 783 784/* Foxconn added end Winster Chan 12/02/2005 */ 785int 786create_padt(struct pppoe_packet *packet, const char *src, const char *dst, unsigned short nSessId) 787{ 788 int size; 789 char *pCookieStart = NULL; 790 int nCookieSize = 0; 791 unsigned short usCookieSize = 0; 792 sPadxTag sTag; 793 794 if (packet == NULL) 795 return 0; 796 797 size = sizeof(struct pppoe_packet) + TAG_STRUCT_SIZE; 798 799 if (get_padx_tag((struct pppoe_tag *)pado_tags, pado_tag_size, &sTag, TAG_AC_COOKIE)) { 800 nCookieSize = sTag.nPadLen; 801 usCookieSize = sTag.usPadLen; 802 pCookieStart = sTag.pPadStart; 803 size += (int)(TAG_STRUCT_SIZE + sTag.nPadLen); 804 } 805 806#ifdef __linux__ 807 memcpy(packet->ethhdr.h_dest, dst, 6); 808 memcpy(packet->ethhdr.h_source, src, 6); 809 packet->ethhdr.h_proto = htons(ETH_P_PPPOE_DISC); 810#else 811 memcpy(packet->ethhdr.ether_dhost, dst, 6); 812 memcpy(packet->ethhdr.ether_shost, src, 6); 813 packet->ethhdr.ether_type = htons(ETH_P_PPPOE_DISC); 814#endif 815 packet->ver = 1; 816 packet->type = 1; 817 packet->code = CODE_PADT; 818 /*packet->session = session;*/ 819 packet->session = nSessId; 820 packet->length = htons(size - sizeof(struct pppoe_packet)); 821 822 /* fill out a blank generic-error tag */ 823 (*(struct pppoe_tag *)(packet+1)).type = htons(TAG_GENERIC_ERROR); 824 (*(struct pppoe_tag *)(packet+1)).length = 0; 825 826 /* fill out the AC cookie tag from PADO */ 827 if (nCookieSize > 0) { 828 (*(struct pppoe_tag *)((char *)(packet+1)+TAG_STRUCT_SIZE)).type 829 = htons(TAG_AC_COOKIE); 830 (*(struct pppoe_tag *)((char *)(packet+1)+TAG_STRUCT_SIZE)).length 831 = usCookieSize; 832 memcpy((char *)(packet+1)+(2*TAG_STRUCT_SIZE), 833 (char *)pCookieStart, nCookieSize); 834 } 835 836 memset(((char *)packet) + size, 0, 14); 837 return size; 838} 839/* Foxconn added end Winster Chan 12/02/2005 */ 840 841/* Foxconn added start pling 09/09/2009 */ 842int create_lcp_terminate_request 843( 844 struct pppoe_packet *packet, 845 const char *src, const char *dst, 846 unsigned short sess_id 847) 848{ 849 int size; 850 struct pppoe_packet *ppp_data_start; 851 char ppp_data[] = 852 { 853 0xc0, 0x21, /* PPP Link Control Protocol */ 854 0x05, /* Code: Terminate request */ 855 0x01, /* Identifier */ 856 0x00, 0x10, /* Length: 16 */ 857 0x55, 0x73, 0x65, 0x72, 0x20, /* "user " */ 858 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74 /* "request" */ 859 }; 860 861 if (packet == NULL) 862 return 0; 863 864 size = sizeof(struct pppoe_packet) + sizeof(ppp_data); 865 866#ifdef __linux__ 867 memcpy(packet->ethhdr.h_dest, dst, 6); 868 memcpy(packet->ethhdr.h_source, src, 6); 869 packet->ethhdr.h_proto = htons(ETH_P_PPPOE_SESS); 870#else 871 memcpy(packet->ethhdr.ether_dhost, dst, 6); 872 memcpy(packet->ethhdr.ether_shost, src, 6); 873 packet->ethhdr.ether_type = htons(ETH_P_PPPOE_SESS); 874#endif 875 packet->ver = 1; 876 packet->type = 1; 877 packet->code = CODE_SESS; 878 packet->session = sess_id; 879 packet->length = htons(size - sizeof(struct pppoe_packet)); 880 881 ppp_data_start = packet + 1; 882 memcpy(ppp_data_start, ppp_data, sizeof(ppp_data)); 883 884 memset(((char *)packet) + size, 0, 14); 885 return size; 886} 887/* Foxconn added end pling 09/09/2009 */ 888 889unsigned short fcstab[256] = { 890 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 891 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 892 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 893 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 894 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 895 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 896 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 897 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 898 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 899 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 900 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 901 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 902 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 903 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 904 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 905 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 906 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 907 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 908 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 909 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 910 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 911 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 912 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 913 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 914 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 915 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 916 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 917 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 918 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 919 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 920 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 921 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 922}; 923 924#define PPPINITFCS16 0xffff /* Initial FCS value */ 925#define PPPGOODFCS16 0xf0b8 /* Good final FCS value */ 926/* 927 * Calculate a new fcs given the current fcs and the new data. 928 */ 929unsigned short pppfcs16(register unsigned short fcs, 930 register unsigned char * cp, 931 register int len) 932{ 933/* assert(sizeof (unsigned short) == 2); 934 assert(((unsigned short) -1) > 0); */ 935 936 while (len--) 937 fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff]; 938 939 return (fcs); 940} 941 942#define FRAME_ESC 0x7d 943#define FRAME_FLAG 0x7e 944#define FRAME_ADDR 0xff 945#define FRAME_CTL 0x03 946#define FRAME_ENC 0x20 947 948#define ADD_OUT(c) { *out++ = (c); n++; if (opt_verbose) fprintf(log_file, "%x ", (c)); } 949 950void encode_ppp(int fd, unsigned char *buf, int len) 951{ 952 static int first = 0; 953 unsigned char out_buf[PACKETBUF]; 954 unsigned char *out = out_buf; 955 unsigned char header[2], tail[2]; 956 int i,n; 957 unsigned short fcs; 958#ifndef MULTIPLE_PPPOE 959 time_t tm; 960#endif 961 header[0] = FRAME_ADDR; 962 header[1] = FRAME_CTL; 963 fcs = pppfcs16(PPPINITFCS16, header, 2); 964 fcs = pppfcs16(fcs, buf, len) ^ 0xffff; 965 tail[0] = fcs & 0x00ff; 966 tail[1] = (fcs >> 8) & 0x00ff; 967#ifndef MULTIPLE_PPPOE 968 if (opt_verbose) 969 { 970 time(&tm); 971 fprintf(log_file, "%sWriting to pppd: \n", ctime(&tm)); 972 } 973#endif 974 n = 0; 975 if (!first) { 976 ADD_OUT(FRAME_FLAG); 977 first = 1; 978 } 979 ADD_OUT(FRAME_ADDR); /* the header - which is constant */ 980 ADD_OUT(FRAME_ESC); 981 ADD_OUT(FRAME_CTL ^ FRAME_ENC); 982 983 for (i = 0; i < len; i++) 984 if (buf[i] == FRAME_FLAG || buf[i] == FRAME_ESC || buf[i] < 0x20) 985 { 986 ADD_OUT(FRAME_ESC); 987 ADD_OUT(buf[i] ^ FRAME_ENC); 988 } 989 else 990 ADD_OUT(buf[i]); 991 992 for (i = 0; i < 2; i++) { 993 if (tail[i] == FRAME_FLAG || tail[i] == FRAME_ESC || tail[i] < 0x20) { 994 ADD_OUT(FRAME_ESC); 995 ADD_OUT(tail[i] ^ FRAME_ENC); 996 } else 997 ADD_OUT(tail[i]); 998 } 999 ADD_OUT(FRAME_FLAG); 1000 1001 write(fd, out_buf, n); 1002 1003#ifndef MULTIPLE_PPPOE 1004 if (opt_verbose) 1005 fprintf(log_file, "\n"); 1006#endif 1007} 1008 1009int 1010create_sess(struct pppoe_packet *packet, const char *src, const char *dst, 1011 unsigned char *buf, int bufsize, int sess, int *bufRemain) 1012{ 1013 int size; 1014 int i, o = 0; 1015 int nBufLen = 0; 1016 int nTotalLen = 0, nAllLen = 0; 1017 int nTemp = 0; 1018 unsigned short usTotalLen = 0x0; 1019 unsigned char bufLen[2]; 1020 1021 /* Clear the length of remain buffer */ 1022 *bufRemain = 0; 1023 1024 if (opt_fwd || !((buf[0] == FRAME_FLAG) || (buf[0] == FRAME_ADDR))) 1025 { 1026 if (opt_fwd_search) /* search for a valid packet */ 1027 { 1028 while (*buf++ != FRAME_FLAG && bufsize != 0) 1029 bufsize--; 1030 if (bufsize == 0) { 1031 fprintf(error_file, "create_sess: bufsize == 0\n"); 1032 return 0; 1033 } 1034 } 1035 else 1036 { 1037 /* fprintf(error_file, "create_sess: invalid data\n"); */ /* foxconn wklin 1038 removed, 1039 07/26/2007 1040 */ 1041 return 0; 1042 } 1043 } 1044 1045 bufLen[0] = 0x0; 1046 bufLen[1] = 0x0; 1047 if (bufsize <= 4) { 1048 *bufRemain = bufsize; 1049 return 0; 1050 } 1051 else { 1052 nTemp = (buf[0] == FRAME_FLAG) ? 4 : 3; 1053 for (i = nTemp; i < bufsize; i++) { 1054 if (buf[i] == FRAME_ESC) { 1055 if ((o == 4) || (o == 5)) 1056 bufLen[o-4] = buf[++i] ^ FRAME_ENC; 1057 else 1058 ++i; 1059 } 1060 else { 1061 if ((o == 4) || (o == 5)) 1062 bufLen[o-4] = buf[i]; 1063 } 1064 o++; 1065 1066 /* Get the total length from IP packet header */ 1067 if (o == 6) { 1068 usTotalLen = ntohs(*(unsigned short *)bufLen); 1069 nTotalLen = (int)usTotalLen; 1070 nAllLen = nTotalLen + 5; 1071 } 1072 1073 /* Get the total buffer length of packet */ 1074 if ((o >= 6) && (o == nAllLen)) { 1075 nBufLen = i + 1; 1076 break; 1077 } 1078 } 1079 1080 if ((o < nAllLen) || (o < 6)) { 1081 *bufRemain = bufsize; 1082 return 0; 1083 } 1084 o = 0; 1085 } 1086 1087 /* for (i = (buf[0] == FRAME_FLAG ? 4 : 3); i < bufsize; i++) { */ 1088 for (i = nTemp; i < bufsize; i++) { 1089 if (buf[i] == FRAME_ESC) { 1090 buf[o++] = buf[++i] ^ FRAME_ENC; 1091 } 1092 else { 1093 buf[o++] = buf[i]; 1094 } 1095 1096 if (o == nAllLen) 1097 break; 1098 } /* End for() */ 1099 1100 /* Compute the length of remain buffer */ 1101 *bufRemain = bufsize - nBufLen; 1102 1103 bufsize = nTotalLen + 2; 1104 1105 if (packet == NULL) { 1106 return 0; 1107 } 1108 1109 size = sizeof(struct pppoe_packet) + bufsize; 1110 1111#ifdef __linux__ 1112 memcpy(packet->ethhdr.h_dest, dst, 6); 1113 memcpy(packet->ethhdr.h_source, src, 6); 1114 packet->ethhdr.h_proto = htons(ETH_P_PPPOE_SESS); 1115#else 1116 memcpy(packet->ethhdr.ether_dhost, dst, 6); 1117 memcpy(packet->ethhdr.ether_shost, src, 6); 1118 packet->ethhdr.ether_type = htons(ETH_P_PPPOE_SESS); 1119#endif 1120 packet->ver = 1; 1121 packet->type = 1; 1122 packet->code = CODE_SESS; 1123 packet->session = sess; 1124 packet->length = htons(size - sizeof(struct pppoe_packet)); 1125 1126 return size; 1127} 1128 1129int 1130send_packet(int sock, struct pppoe_packet *packet, int len, const char *ifn) 1131{ 1132 struct sockaddr addr; 1133 int c; 1134#ifndef MULTIPLE_PPPOE 1135 time_t tm; 1136#endif 1137 memset(&addr, 0, sizeof(addr)); 1138 strcpy(addr.sa_data, ifn); 1139 1140#ifndef MULTIPLE_PPPOE 1141 if (opt_verbose == 1) 1142 { 1143 time(&tm); 1144 fprintf(log_file, "%sSending ", ctime(&tm)); 1145 print_packet(packet); 1146 fputc('\n', log_file); 1147 } 1148#endif 1149 1150 if ((c = sendto(sock, packet, len, 0, &addr, sizeof(addr))) < 0) { 1151 /* fprintf(error_file, "send_packet c[%d] = sendto(len = %d)\n", c, len); */ 1152 perror("pppoe: sendto (send_packet)"); 1153 } 1154 1155 return c; 1156} 1157#ifdef MULTIPLE_PPPOE 1158int 1159read_packet_nowait(int sock, struct pppoe_packet *packet, int *len) 1160{ 1161 socklen_t fromlen = PACKETBUF; 1162 1163 if (recvfrom(sock, packet, PACKETBUF, 0, 1164 NULL /*(struct sockaddr *)&from*/, &fromlen) < 0) { 1165 perror("pppoe: recv (read_packet_nowait)"); 1166 return -1; 1167 } 1168 1169 return sock; 1170} 1171 1172int 1173read_packet(int sock, struct pppoe_packet *packet, int *len) 1174{ 1175 socklen_t fromlen = PACKETBUF; 1176 fd_set fdset; 1177 struct timeval tma; 1178 1179 FD_ZERO(&fdset); 1180 FD_SET(sock, &fdset); 1181 tma.tv_usec = 0; 1182 tma.tv_sec = 3; /* wait for 3 seconds at most */ 1183 while(1) { 1184 if (select(sock + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, 1185 &tma) <= 0) { 1186 return -1; /* timeout or error */ 1187 } else if (FD_ISSET(sock, &fdset)) { 1188 if (recvfrom(sock, packet, PACKETBUF, 0, 1189 NULL /*(struct sockaddr *)&from*/, &fromlen) < 0) { 1190 perror("pppoe: recv (read_packet)"); 1191 return -1; 1192 } else if (memcmp(packet->ethhdr.h_dest,src_addr,sizeof(src_addr))!=0){ 1193 /* fprintf(stderr, "pppoe: received a packet not for me.\n");*/ 1194 continue; 1195 } 1196 } 1197 return sock; 1198 } 1199} 1200#endif 1201#ifndef MULTIPLE_PPPOE 1202/* foxconn wklin added start, 08/10/2007 */ 1203int 1204read_packet2(int sock, struct pppoe_packet *packet, int *len) 1205{ 1206#if defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ < 6 1207 int fromlen = PACKETBUF; 1208#else 1209 socklen_t fromlen = PACKETBUF; 1210#endif 1211 time_t tm; 1212 1213 if (recvfrom(sock, packet, PACKETBUF, 0, 1214 NULL /*(struct sockaddr *)&from*/, &fromlen) < 0) { 1215 perror("pppoe: recv (read_packet2)"); 1216 return -1; 1217 } 1218 1219 if (opt_verbose) 1220 { 1221 time(&tm); 1222 fprintf(log_file, "Received packet at %s", ctime(&tm)); 1223 print_packet(packet); 1224 fputc('\n', log_file); 1225 } 1226 1227 return sock; 1228} 1229/* foxconn wklin added end, 08/10/2007 */ 1230 1231int 1232read_packet(int sock, struct pppoe_packet *packet, int *len) 1233{ 1234/* struct sockaddr_in from; */ 1235#if defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ < 6 1236 int fromlen = PACKETBUF; 1237#else 1238 socklen_t fromlen = PACKETBUF; 1239#endif 1240 time_t tm; 1241 1242 time(&tm); 1243 1244 while(1) { 1245 /* wklin modified start, 01/10/2007 */ 1246 fd_set fdset; 1247 struct timeval tm; 1248 1249 FD_ZERO(&fdset); 1250 FD_SET(sock, &fdset); 1251 tm.tv_usec = 0; 1252 tm.tv_sec = 3; /* wait for 3 seconds */ 1253 if (select(sock + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, &tm) <= 0) { 1254 return -1; /* timeout or error */ 1255 } else if (FD_ISSET(sock, &fdset)) { 1256 if (recvfrom(sock, packet, PACKETBUF, 0, 1257 NULL /*(struct sockaddr *)&from*/, &fromlen) < 0) { 1258 perror("pppoe: recv (read_packet)"); 1259 return -1; 1260 } 1261 } 1262 /* wklin modified end, 01/10/2007 */ 1263 if (opt_verbose) 1264 { 1265 fprintf(log_file, "Received packet at %s", ctime(&tm)); 1266 print_packet(packet); 1267 fputc('\n', log_file); 1268 } 1269 1270 return sock; 1271 } 1272} 1273#endif 1274 1275void sigchild(int src) { 1276 clean_child = 1; 1277} 1278 1279void cleanup_and_exit(int status) { 1280#ifdef MULTIPLE_PPPOE 1281 if (pppfd > 0) 1282 close(pppfd); 1283 if (poxfd > 0) 1284 close(poxfd); 1285 if (disc_sock > 0) 1286 close(disc_sock); 1287 if (sess_sock > 0) 1288 close(sess_sock); 1289 close(1); 1290 1291 exit(status); 1292#else 1293 /* Foxconn modified start, Winster Chan, 06/26/2006 */ 1294#ifdef NEW_WANDETECT 1295 if (!bWanDetect) /* Foxconn added by Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 1296#endif 1297 { 1298 pptp_pppox_release(&poxfd, &pppfd); 1299 close(pppfd); pppfd = -1; 1300 close(poxfd); poxfd = -1; 1301 } 1302 /* Foxconn modified end, Winster Chan, 06/26/2006 */ 1303 1304 close(disc_sock); 1305#ifdef NEW_WANDETECT 1306 if (!bWanDetect) /* Foxconn added by Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 1307#endif 1308 close(sess_sock); 1309 close(1); 1310 1311 exit(status); 1312#endif 1313} 1314 1315void sigint(int src) 1316{ 1317#ifdef MULTIPLE_PPPOE 1318 struct pppoe_packet *packet = NULL; 1319 int pkt_size; 1320 FILE *fp; 1321 1322 /* Foxconn modified start pling 10/08/2009 */ 1323 /* Don't reference pppd_listen any more as this var is not used. */ 1324 /* if (disc_sock >= 0 && (pppd_listen >= 0)) { */ 1325 if (disc_sock > 0) { 1326 /* Foxconn modified end pling 10/08/2009 */ 1327 /* allocate packet once */ 1328 packet = malloc(PACKETBUF); 1329 assert(packet != NULL); 1330 1331 /* send PADT */ 1332 if ((pkt_size = create_padt(packet, src_addr, dst_addr, session)) == 0) { 1333 fprintf(stderr, "pppoe: unable to create PADT packet\n"); 1334 if (packet != NULL) 1335 free(packet); 1336 exit(1); 1337 } 1338 if (send_packet(disc_sock, packet, pkt_size+14, if_name) < 0) { 1339 fprintf(stderr, "pppoe: unable to send PADT packet\n"); 1340 if (packet != NULL) 1341 free(packet); 1342 exit(1); 1343 } else { 1344 ; /* fprintf(stderr, "PPPOE: PADT sent*\n"); */ 1345 } 1346 } 1347 1348 if (ppp_ifunit == 0) 1349 fp = fopen(PPP_PPPOE_SESSION, "w+"); 1350 else 1351 fp = fopen(PPP_PPPOE2_SESSION, "w+"); 1352 1353 if (fp) { 1354 /* Clear the PPPoE server MAC address and Session ID */ 1355 fprintf(fp, "%02x:%02x:%02x:%02x:%02x:%02x %d\n", 1356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0); 1357 fclose(fp); 1358 } 1359 1360 if (packet != NULL) 1361 free(packet); 1362 cleanup_and_exit(1); 1363#else 1364 /* Foxconn added start Winster Chan 12/02/2005 */ 1365 struct pppoe_packet *packet = NULL; 1366 int pkt_size; 1367 FILE *fp; 1368 time_t tm; 1369 1370 /* Foxconn modified start pling 10/08/2009 */ 1371 /* Don't reference pppd_listen any more as this var is not used. */ 1372 /* if (disc_sock && (pppd_listen > 0)) { */ 1373 if (disc_sock > 0) { 1374 /* Foxconn modified end pling 10/08/2009 */ 1375 /* allocate packet once */ 1376 packet = malloc(PACKETBUF); 1377 assert(packet != NULL); 1378 1379 /* send PADT */ 1380 if ((pkt_size = create_padt(packet, src_addr, dst_addr, session)) == 0) { 1381 fprintf(stderr, "pppoe: unable to create PADT packet\n"); 1382 /* exit(1); */ 1383 } 1384 if (send_packet(disc_sock, packet, pkt_size+14, if_name) < 0) { 1385 fprintf(stderr, "pppoe: unable to send PADT packet\n"); 1386 /* exit(1); */ 1387 } else { 1388 time(&tm); 1389 fprintf(stderr, "PPPOE: PADT sent* %s\n",ctime(&tm)); /* foxconn wklin added, 07/26/2007 */ 1390 } 1391 } 1392 /* Foxconn added end Winster Chan 12/02/2005 */ 1393 1394 /* Foxconn added start Winster Chan 12/05/2005 */ 1395 if (!(fp = fopen(PPP_PPPOE_SESSION, "w"))) { 1396 perror(PPP_PPPOE_SESSION); 1397 } 1398 else { 1399 /* Clear the PPPoE server MAC address and Session ID */ 1400 fprintf(fp, "%02x:%02x:%02x:%02x:%02x:%02x %d\n", 1401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0); 1402 fclose(fp); 1403 } 1404 1405 if (packet != NULL) 1406 free(packet); 1407 1408 /* Foxconn added end Winster Chan 12/05/2005 */ 1409 cleanup_and_exit(1); 1410#endif 1411} 1412 1413/*Foxconn added start James 11/12/2008 @new_internet_detection*/ 1414#ifdef NEW_WANDETECT 1415void sigint2(int src) 1416{ 1417 struct pppoe_packet *packet = NULL; 1418 int pkt_size; 1419 FILE *fp; 1420 time_t tm; 1421 1422 /* allocate packet once */ 1423 packet = malloc(PACKETBUF); 1424 assert(packet != NULL); 1425 1426 /* Foxconn added start pling 09/09/2009 */ 1427 /* Send LCP terminate request first, before PADT, 1428 * to make the PPP server terminates our session. 1429 */ 1430 if ((pkt_size = create_lcp_terminate_request(packet, 1431 src_addr, dst_addr, session)) == 0) { 1432 fprintf(stderr, "pppoe: unable to create LCP terminate req packet\n"); 1433 } else { 1434 sleep(1); 1435 if (send_packet(disc_sock, packet, pkt_size+14, if_name) < 0) { 1436 fprintf(stderr, "pppoe: unable to send PADT packet\n"); 1437 } else { 1438 time(&tm); 1439 fprintf(stderr, "PPPOE: LCP Terminate Req sent* %s\n",ctime(&tm)); 1440 sleep(1); 1441 } 1442 } 1443 /* Foxconn added end pling 09/09/2009 */ 1444 1445 /* send PADT */ 1446 if ((pkt_size = create_padt(packet, src_addr, dst_addr, session)) == 0) { 1447 fprintf(stderr, "pppoe: unable to create PADT packet\n"); 1448 /* exit(1); */ 1449 } 1450 if (send_packet(disc_sock, packet, pkt_size+14, if_name) < 0) { 1451 fprintf(stderr, "pppoe: unable to send PADT packet\n"); 1452 /* exit(1); */ 1453 } else { 1454 time(&tm); 1455 fprintf(stderr, "PPPOE: PADT sent* %s\n",ctime(&tm)); /* foxconn wklin added, 07/26/2007 */ 1456 } 1457 1458 /* Foxconn added end Winster Chan 12/02/2005 */ 1459 1460 /* Foxconn added start Winster Chan 12/05/2005 */ 1461 if (!(fp = fopen(PPP_PPPOE_SESSION, "w"))) { 1462 perror(PPP_PPPOE_SESSION); 1463 } 1464 else { 1465 /* Clear the PPPoE server MAC address and Session ID */ 1466 fprintf(fp, "%02x:%02x:%02x:%02x:%02x:%02x %d\n", 1467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0); 1468 fclose(fp); 1469 } 1470 if (packet != NULL) 1471 free(packet); 1472 1473 /* Foxconn added end Winster Chan 12/05/2005 */ 1474 cleanup_and_exit(1); 1475 1476} 1477#endif 1478/* Foxconn added end James 11/12/2008 @new_internet_detection */ 1479 1480void sess_handler(void) { 1481 /* pull packets of sess_sock and feed to pppd */ 1482 static struct pppoe_packet *packet = NULL; 1483 int pkt_size; 1484 1485#ifdef BUGGY_AC 1486/* the following code deals with buggy AC software which sometimes sends 1487 duplicate packets */ 1488#define DUP_COUNT 10 1489#define DUP_LENGTH 20 1490 static unsigned char dup_check[DUP_COUNT][DUP_LENGTH]; 1491 int i, ptr = 0; 1492#endif /* BUGGY_AC */ 1493 1494 if (!packet) { 1495#ifdef BUGGY_AC 1496 memset(dup_check, 0, sizeof(dup_check)); 1497#endif 1498 /* allocate packet once */ 1499 packet = malloc(PACKETBUF); 1500 assert(packet != NULL); 1501 } 1502 1503 /* while(1) */ 1504 { 1505#ifdef MULTIPLE_PPPOE 1506 if (read_packet_nowait(sess_sock,packet,&pkt_size) != sess_sock) 1507#else 1508 if (read_packet2(sess_sock,packet,&pkt_size) != sess_sock) 1509#endif 1510 return; 1511#ifdef __linux__ 1512 if (memcmp(packet->ethhdr.h_source, dst_addr, sizeof(dst_addr)) != 0) 1513#else 1514 if (memcmp(packet->ethhdr.ether_shost, dst_addr, sizeof(dst_addr)) != 0) 1515#endif 1516 return; /* packet not from AC */ 1517#ifdef MULTIPLE_PPPOE 1518 if (memcmp(packet->ethhdr.h_dest, src_addr, sizeof(src_addr)) != 0) { 1519 /* fprintf(stderr, "pppoe: received a session packet not for 1520 * me.\n"); */ 1521 return; 1522 } 1523#endif 1524 if (packet->session != session) 1525 return; /* discard other sessions */ 1526#ifdef __linux__ 1527 if (packet->ethhdr.h_proto != htons(ETH_P_PPPOE_SESS)) 1528 { 1529 fprintf(log_file, "pppoe: invalid session proto %x detected\n", 1530 ntohs(packet->ethhdr.h_proto)); 1531 return; 1532 } 1533#else 1534 if (packet->ethhdr.ether_type != htons(ETH_P_PPPOE_SESS)) 1535 { 1536 fprintf(log_file, "pppoe: invalid session proto %x detected\n", 1537 ntohs(packet->ethhdr.ether_type)); 1538 return; 1539 } 1540#endif 1541 if (packet->code != CODE_SESS) { 1542 fprintf(log_file, "pppoe: invalid session code %x\n", packet->code); 1543 return; 1544 } 1545#if BUGGY_AC 1546 /* we need to go through a list of recently-received packets to 1547 make sure the AC hasn't sent us a duplicate */ 1548 for (i = 0; i < DUP_COUNT; i++) 1549 if (memcmp(packet, dup_check[i], sizeof(dup_check[0])) == 0) 1550 return; /* we've received a dup packet */ 1551#define min(a,b) ((a) < (b) ? (a) : (b)) 1552 memcpy(dup_check[ptr], packet, min(ntohs(packet->length), 1553 sizeof(dup_check[0]))); 1554 ptr = ++ptr % DUP_COUNT; 1555#endif /* BUGGY_AC */ 1556 1557 encode_ppp(1, (unsigned char *)(packet+1), ntohs(packet->length)); 1558 } 1559} 1560 1561void pppd_handler(void) { 1562 /* take packets from pppd and feed them to sess_sock */ 1563 struct pppoe_packet *packet = NULL; 1564#ifndef MULTIPLE_PPPOE 1565 time_t tm; 1566#endif 1567 static sPktBuf pktBuf[BUFRING]; /* foxconn wklin modified, use static */ 1568 int nPkt = 0; 1569 /* unsigned char buf[PACKETBUF]; */ 1570 int len, pkt_size; 1571 int i, bufRemain = 0, bufPos; 1572 unsigned char *currBufStart; 1573 static int first_in = 1; /* foxconn wklin added, 08/10/2007 */ 1574 1575 if (first_in) { 1576 first_in = 0; 1577 /* Clear data buffer */ 1578 for (i=0; i<BUFRING; i++) { 1579 memset(pktBuf[i].packetBuf, 0x0, sizeof(pktBuf[i].packetBuf)); 1580 } 1581 } 1582 1583 { 1584 /* Read in data buffer, Maximum size is 4095 bytes for evey one read() */ 1585 if ((len = read(0, &(pktBuf[nPkt].packetBuf[(20+bufRemain)]), (4095-bufRemain))) < 0) { 1586 perror("pppoe"); 1587 fprintf(error_file, "pppd_handler: read packet error len < 0\n"); 1588 /* exit(1); */ 1589 return; 1590 } 1591 if (len == 0) { 1592 /* foxconn wklin modified start, 07/27/2007 */ 1593 /* fprintf(error_file, "pppd_handler: read packet len = 0 bytes\n"); */ 1594 /* usleep(10000);*/ /* sleep 10ms */ 1595 /* foxconn wklin modified end, 07/27/2007 */ 1596 /* continue; */ 1597 return; 1598 } 1599 /* Append the length of previous remained data */ 1600 len += bufRemain; 1601#ifndef MULTIPLE_PPPOE 1602 if (opt_verbose == 1) { 1603 time(&tm); 1604 fprintf(log_file, "\n%sInput of %d bytes:\n", ctime(&tm), len); 1605 /*print_hex(buf, len);*/ 1606 print_hex(pktBuf[nPkt].packetBuf, len); 1607 fputc('\n', log_file); 1608 } 1609#endif 1610 bufPos = 0; 1611 packet = &(pktBuf[nPkt].packetBuf[0]); 1612 currBufStart = &(pktBuf[nPkt].packetBuf[20]); 1613 do { 1614 /* Segment and compose packet from buffer */ 1615 if ((pkt_size = create_sess(packet, src_addr, dst_addr, currBufStart, len, 1616 session, &bufRemain)) == 0) { 1617 /* Copy incomplete content to next buffer */ 1618 if (bufRemain > 0) { 1619 if ((nPkt+1) < BUFRING) { 1620 memcpy(&(pktBuf[nPkt+1].packetBuf[20]), 1621 &(pktBuf[nPkt].packetBuf[(4115-bufRemain)]), /* 4115 = 4095 + 20 */ 1622 bufRemain); 1623 } 1624 else { 1625 memcpy(&(pktBuf[0].packetBuf[20]), 1626 &(pktBuf[(BUFRING-1)].packetBuf[(4115-bufRemain)]), /* 4115 = 4095 + 20 */ 1627 bufRemain); 1628 } 1629 } 1630 break; 1631 } 1632 1633 len -= bufRemain; 1634 1635 /* Send the completely composed packet */ 1636 if (send_packet(sess_sock, packet, pkt_size, if_name) < 0) { 1637 fprintf(error_file, "pppd_handler: unable to send PPPoE packet\n"); 1638 /* exit(1); */ 1639 return; 1640 } 1641 1642 /* Check if all the contents of buffer were processed */ 1643 if (bufRemain <= 0) { 1644 break; 1645 } 1646 else { 1647 /* Renew the positions of packet header and data buffer */ 1648 bufPos += len; 1649 currBufStart = &(pktBuf[nPkt].packetBuf[bufPos+20]); 1650 packet = &(pktBuf[nPkt].packetBuf[bufPos]); 1651 len = bufRemain; 1652 } 1653 } while (bufRemain > 0); 1654 1655 /* Process next read buffer */ 1656 nPkt++; 1657 if (nPkt >= BUFRING) 1658 nPkt = 0; 1659 1660 } 1661} 1662#ifdef MULTIPLE_PPPOE 1663/* Foxconn Bob Guo added start 10/25/2007*/ 1664#define SERVER_RECORD_FILE "/tmp/ppp/PPPoE_server_record" 1665#define UPTIME_FILE "/proc/uptime" 1666 1667static int checkServerRecord(unsigned char *pServerMac) 1668{ 1669 FILE *fp=NULL; 1670 char line[64]; 1671 char macAddr[32]; 1672 char *token; 1673 int iTimeStamp = 0; 1674 1675 fp = fopen(SERVER_RECORD_FILE, "r"); 1676 if(fp == NULL) 1677 { 1678 goto _exit; 1679 } 1680 1681 sprintf(macAddr, "%02x:%02x:%02x:%02x:%02x:%02x", *pServerMac, *(pServerMac+1), *(pServerMac+2), 1682 *(pServerMac+3), *(pServerMac+4), *(pServerMac+5)); 1683 1684 while (fgets(line, sizeof(line), fp)) 1685 { 1686 if( strncmp(line, macAddr, strlen(macAddr)) == 0) 1687 { 1688 /* the mac address exist in the list */ 1689 token = strtok(line, " "); 1690 if(token == NULL) 1691 goto _exit; 1692 token = strtok(NULL, " "); 1693 if(token) 1694 { 1695 iTimeStamp = atoi(token); 1696 } 1697 break; 1698 } 1699 } 1700 1701_exit: 1702 1703 if(fp) 1704 fclose(fp); 1705 1706 return iTimeStamp; 1707} 1708 1709static void updateServerRecord(unsigned char *pServerMac) 1710{ 1711 FILE *fp=NULL, *fp_uptime=NULL; 1712 char line[64]; 1713 char macAddr[32]; 1714 char uptime[32]; 1715 char *token; 1716 int bFound; 1717 1718 fp = fopen(SERVER_RECORD_FILE, "r+"); 1719 if(fp == NULL) 1720 { 1721 fp = fopen(SERVER_RECORD_FILE, "w+"); 1722 if(fp == NULL) 1723 goto _exit; 1724 } 1725 1726 sprintf(macAddr, "%02x:%02x:%02x:%02x:%02x:%02x", *pServerMac, *(pServerMac+1), *(pServerMac+2), 1727 *(pServerMac+3), *(pServerMac+4), *(pServerMac+5)); 1728 1729 fp_uptime = fopen(UPTIME_FILE, "r"); 1730 if(fp_uptime == NULL) 1731 goto _exit; 1732 1733 if(fgets(line, sizeof(line), fp_uptime)) 1734 { 1735 token = strtok(line, " .\t\n"); 1736 if(token == NULL) 1737 goto _exit; 1738 1739 int i = atoi(token); 1740 sprintf(uptime, "%010d", i); 1741 } 1742 1743 bFound = 0; 1744 1745 while (fgets(line, sizeof(line), fp)) 1746 { 1747 if( strncmp(line, macAddr, strlen(macAddr)) == 0) 1748 { 1749 /* the mac address exist in the list */ 1750 bFound = 1; 1751 break; 1752 } 1753 } 1754 1755 if(bFound) 1756 { 1757 int ioffset = 0 - (strlen(line)); 1758 fseek(fp, ioffset, SEEK_CUR); 1759 } 1760 else 1761 { 1762 fseek(fp, 0, SEEK_END); 1763 } 1764 fprintf(fp, "%s %s\n", macAddr, uptime); 1765 1766_exit: 1767 if(fp) 1768 fclose(fp); 1769 if(fp_uptime) 1770 fclose(fp_uptime); 1771 1772} 1773 1774/* Foxconn Bob Guo added end 10/25/2007 */ 1775#endif 1776int main(int argc, char **argv) 1777{ 1778 struct pppoe_packet *packet = NULL; 1779#ifdef MULTIPLE_PPPOE 1780 /* Foxconn Bob Guo added start 10/25/2007*/ 1781 struct pppoe_packet *packet2 = NULL; 1782 struct pppoe_packet *packet_temp = NULL; 1783 int pkt2_size; 1784 int iOldestTimeStamp, iTimeStamp; 1785 /* Foxconn Bob Guo added end 10/25/2007*/ 1786#endif 1787 int pkt_size; 1788 /* Foxconn added start Winster Chan 12/05/2005 */ 1789 FILE *fp; 1790 char buf[64]; 1791 /* Foxconn added end Winster Chan 12/05/2005 */ 1792 int fd; /* wklin added, 07/26/2007 */ 1793 1794 int opt; 1795 int ret_sock; /* foxconn wklin added, 12/27/2007 */ 1796 1797 /* foxconn wklin added start, 08/10/2007 */ 1798 fd_set allfdset; 1799#ifndef MULTIPLE_PPPOE 1800 struct timeval alltm; 1801#endif 1802 /* foxconn wklin added end, 08/10/2007 */ 1803 time_t tm; 1804 1805#ifdef NEW_WANDETECT 1806 bWanDetect = 0;/* Foxconn added by Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 1807#endif 1808 1809 /* initialize error_file here to avoid glibc2.1 issues */ 1810 error_file = stderr; 1811 1812 /* foxconn wklin added start, 07/26/2007 */ 1813 fd = open("/dev/console", O_WRONLY); 1814 if (fd != -1) 1815 dup2(fd, 2); 1816 /* foxconn wklin added end, 07/26/2007 */ 1817 1818 /* parse options */ 1819 /* foxconn wklin modified, 03/27/2007, add service name option S */ 1820#ifdef MULTIPLE_PPPOE 1821 /* while ((opt = getopt(argc, argv, "I:L:VE:F:S:P:")) != -1) */ 1822 while ((opt = getopt(argc, argv, "I:L:VE:F:S:R:P:")) != -1)/* Foxconn modified by Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 1823#else 1824 /* while ((opt = getopt(argc, argv, "I:L:VE:F:S:")) != -1) */ 1825 while ((opt = getopt(argc, argv, "I:L:VE:F:S:R:")) != -1)/* Foxconn modified by Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 1826#endif 1827 switch(opt) 1828 { 1829 case 'F': /* sets invalid forwarding */ 1830 if (*optarg == 'a') /* always forward */ 1831 opt_fwd = 1; 1832 else if (*optarg == 's') /* search for flag */ 1833 opt_fwd_search = 1; 1834 else 1835 fprintf(stderr, "Invalid forward option %c\n", *optarg); 1836 break; 1837 1838 case 'I': /* sets interface */ 1839 if (if_name != NULL) 1840 free(if_name); 1841 /* foxconn wklin modified, 03/27/2007 */ 1842 if ((if_name=malloc(strlen(optarg)+1)) == NULL) 1843 { 1844 fprintf(stderr, "malloc\n"); 1845 exit(1); 1846 } 1847 strcpy(if_name, optarg); 1848#ifndef MULTIPLE_PPPOE 1849 /* wklin added start, 01/15/2007 */ 1850 if (log_file != NULL) 1851 fclose(log_file); 1852 if ((log_file=fopen("/dev/null", "w")) == NULL) { 1853 fprintf(stderr, "fopen\n"); 1854 exit(1); 1855 } 1856 /* wklin added end, 01/15/2007 */ 1857#endif 1858 break; 1859 1860 case 'L': /* log file */ 1861 opt_verbose = 1; 1862 if (log_file != NULL) 1863 fclose(log_file); 1864 if ((log_file=fopen(optarg, "w")) == NULL) 1865 { 1866 fprintf(stderr, "fopen\n"); 1867 exit(1); 1868 } 1869 if (setvbuf(log_file, NULL, _IONBF, 0) != 0) 1870 { 1871 fprintf(stderr, "setvbuf\n"); 1872 exit(1); 1873 } 1874 break; 1875 case 'V': /* version */ 1876 printf("pppoe version %d.%d\n", VERSION_MAJOR, VERSION_MINOR); 1877 exit(0); 1878 break; 1879 case 'E': /* error file */ 1880 if ((error_file = fopen(optarg, "w")) == NULL) 1881 { 1882 fprintf(stderr, "fopen\n"); 1883 exit(1); 1884 } 1885 if (setvbuf(error_file, NULL, _IONBF, 0) != 0) 1886 { 1887 fprintf(stderr, "setvbuf\n"); 1888 exit(1); 1889 } 1890 break; 1891 /* foxconn wklin added start, 03/27/2007, service name */ 1892 case 'S': /* set service name*/ 1893 if (service_name != NULL) 1894 free(service_name); 1895 if ((service_name=malloc(strlen(optarg)+1)) == NULL) { 1896#ifdef MULTIPLE_PPPOE 1897 fprintf(stderr, "pppoe: malloc error.\n"); 1898#else 1899 fprintf(stderr, "malloc\n"); 1900#endif 1901 exit(1); 1902 } 1903 strcpy(service_name, optarg); 1904 break; 1905 /* foxconn wklin added end, 03/27/2007 */ 1906#ifdef MULTIPLE_PPPOE 1907 /* foxconn wklin added start, 08/16/2007, service name */ 1908 case 'P': /* ppp ifunit */ 1909 ppp_ifunit = 1; 1910 break; 1911 /* foxconn wklin added end, 08/16/2007 */ 1912#endif 1913 /* Foxconn add start, Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 1914 case 'R': /* wan detect purpose */ 1915#ifdef NEW_WANDETECT 1916 bWanDetect = 1; 1917#endif 1918 break; 1919 /* Foxconn add end, Max Ding, 04/23/2009 */ 1920 default: 1921 fprintf(stderr, "Unknown option %c\n", optopt); 1922 exit(1); 1923 } 1924 1925 /* allocate packet once */ 1926 packet = malloc(PACKETBUF); 1927 assert(packet != NULL); 1928 1929 /* create the raw socket we need */ 1930 1931 signal(SIGINT, sigint); 1932 signal(SIGTERM, sigint); 1933#ifdef NEW_WANDETECT 1934 signal(SIGUSR1, sigint2);/*Foxconn added James 11/11/2008 @new_internet_detection*/ 1935#endif 1936 1937#ifndef MULTIPLE_PPPOE 1938#ifdef NEW_WANDETECT 1939 if (!bWanDetect) /* Foxconn added by Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 1940#endif 1941 { 1942 /* Foxconn added start, Winster Chan, 06/26/2006 */ 1943 pptp_pppox_open(&poxfd, &pppfd); 1944 /* Foxconn added end, Winster Chan, 06/26/2006 */ 1945 } 1946#endif 1947 1948 if ((disc_sock = open_interface(if_name,ETH_P_PPPOE_DISC,src_addr)) < 0) 1949 { 1950 fprintf(error_file, "pppoe: unable to create raw socket\n"); 1951#ifdef MULTIPLE_PPPOE 1952 exit(1); 1953#else 1954 return 1; 1955#endif 1956 } 1957#ifdef MULTIPLE_PPPOE 1958 /* initiate connection */ 1959 if (ppp_ifunit == 0) 1960 fp = fopen(PPP_PPPOE_SESSION, "r"); 1961 else /* ifunit == 1 */ 1962 fp = fopen(PPP_PPPOE2_SESSION, "r"); 1963 1964 if (fp) { 1965#else 1966 /* initiate connection */ 1967 1968 /* Foxconn added start Winster Chan 12/05/2005 */ 1969 if (!(fp = fopen(PPP_PPPOE_SESSION, "r"))) { 1970 ; /* perror(PPP_PPPOE_SESSION); */ /* foxconn wklin removed, 08/13/2007 */ 1971 } 1972 else { 1973#endif 1974 unsigned int nMacAddr[ETH_ALEN]; 1975 int nSessId, i; 1976 char cMacAddr[ETH_ALEN]; 1977 unsigned short usSessId; 1978 1979 /* Init variables */ 1980 for (i=0; i<ETH_ALEN; i++) { 1981 nMacAddr[i] = 0; 1982 cMacAddr[i] = 0x0; 1983 } 1984 nSessId = 0; 1985 1986 /* Get the PPPoE server MAC address and Session ID from file */ 1987 if(fgets(buf, sizeof(buf), fp)) { 1988 sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x %d", 1989 &nMacAddr[0], &nMacAddr[1], &nMacAddr[2], 1990 &nMacAddr[3], &nMacAddr[4], &nMacAddr[5], 1991 &nSessId); 1992 1993 /* Transfer types of data */ 1994 for (i=0; i<ETH_ALEN; i++) { 1995 cMacAddr[i] = (char)nMacAddr[i]; 1996 } 1997 usSessId = (unsigned short)nSessId; 1998 1999 /* Check if the previous MAC address and Session ID exist. */ 2000 if (!((cMacAddr[0]==0x0) && (cMacAddr[1]==0x0) && (cMacAddr[2]==0x0) && 2001 (cMacAddr[3]==0x0) && (cMacAddr[4]==0x0) && (cMacAddr[5]==0x0)) && 2002 (htons(usSessId) != 0x0)) { 2003 2004 /* send PADT to server to clear the previous connection */ 2005 if ((pkt_size = create_padt(packet, src_addr, cMacAddr, 2006 (unsigned short)htons(usSessId))) == 0) { 2007 fprintf(stderr, "pppoe: unable to create PADT packet\n"); 2008 fclose(fp); 2009 /*exit(1);*/ 2010#ifdef MULTIPLE_PPPOE 2011 exit(1); 2012#else 2013 cleanup_and_exit(1); /* foxconn modified by EricHuang, 05/24/2007 */ 2014#endif 2015 } 2016 if (send_packet(disc_sock, packet, pkt_size+14, if_name) < 0) { 2017 fprintf(stderr, "pppoe: unable to send PADT packet\n"); 2018 fclose(fp); 2019#ifdef MULTIPLE_PPPOE 2020 exit(1); 2021#else 2022 /*exit(1);*/ 2023 cleanup_and_exit(1); /* foxconn modified by EricHuang, 05/24/2007 */ 2024#endif 2025 } else { 2026#ifdef MULTIPLE_PPPOE 2027 ; /* fprintf(stderr, "PPPOE: PADT sent\n"); */ 2028#else 2029 time(&tm); 2030 fprintf(stderr, "PPPOE: PADT sent %s\n",ctime(&tm)); /* foxconn wklin added, 07/26/2007 */ 2031#endif 2032 } 2033 2034 /* Foxconn modified start, Winster Chan, 06/26/2006 */ 2035 /*pptp_pppox_release(&poxfd, &pppfd);*/ /* foxconn removed by EricHuang, 05/24/2007 */ 2036 /* Foxconn modified end, Winster Chan, 06/26/2006 */ 2037 2038 /* Waiting 3 seconds for server finishing the termination */ 2039 sleep(3); 2040 } 2041 } 2042 fclose(fp); 2043 } 2044 /* Foxconn added end Winster Chan 12/05/2005 */ 2045#ifdef MULTIPLE_PPPOE 2046 memset(dst_addr, 0, sizeof(dst_addr)); 2047 2048resend_padi: 2049#endif 2050 /* start the PPPoE session */ 2051 /* foxconn wklin modified, 03/27/2007, add service name */ 2052 if ((pkt_size = create_padi(packet, src_addr, service_name)) == 0) { 2053 fprintf(stderr, "pppoe: unable to create PADI packet\n"); 2054 exit(1); 2055 } 2056 /* send the PADI packet */ 2057 if (send_packet(disc_sock, packet, pkt_size, if_name) < 0) { 2058 fprintf(stderr, "pppoe: unable to send PADI packet\n"); 2059 exit(1); 2060 } 2061 2062 time(&tm); /* foxconn wklin added, 12/27/2007 */ 2063 /* wait for PADO */ 2064 while ((ret_sock = read_packet(disc_sock, packet, &pkt_size)) != disc_sock || 2065 (packet->code != CODE_PADO )) { /* foxconn wklin modified, 12/27/2007 */ 2066#ifndef MULTIPLE_PPPOE 2067 fprintf(log_file, "pppoe: unexpected packet %x\n", 2068 packet->code); 2069#endif 2070 /* foxconn wklin added start, 12/27/2007 */ 2071 if (ret_sock == disc_sock && 2072 (packet->code == CODE_PADI || packet->code == CODE_PADR)) { 2073 if (time(NULL) - tm < 3) 2074 continue; 2075 2076 } 2077 /* foxconn wklin added end, 12/27/2007 */ 2078 /* wklin added start, 01/10/2007 */ 2079 /* fprintf(stderr, "pppoe: resend PADI\n"); */ 2080 /* start the PPPoE session */ 2081 /* foxconn wklin modified, 03/27/2007, add service name */ 2082 if ((pkt_size = create_padi(packet, src_addr, service_name)) == 0) { 2083 fprintf(stderr, "pppoe: unable to create PADI packet\n"); 2084 exit(1); 2085 } 2086 /* send the PADI packet */ 2087 if (send_packet(disc_sock, packet, pkt_size, if_name) < 0) { 2088 fprintf(stderr, "pppoe: unable to send PADI packet\n"); 2089 exit(1); 2090 } 2091 /* wklin added end, 01/10/2007 */ 2092 time(&tm); /* foxconn wklin added, 12/27/2007 */ 2093#ifndef MULTIPLE_PPPOE 2094 continue; 2095#endif 2096 } 2097#ifdef MULTIPLE_PPPOE 2098 /* foxconn Bob Guo added start 10/25/2007 */ 2099 2100 iOldestTimeStamp = checkServerRecord(packet->ethhdr.h_source); 2101 if(iOldestTimeStamp) 2102 { 2103 packet2 = malloc(PACKETBUF); 2104 if(packet2) 2105 { 2106 while( read_packet(disc_sock, packet2, &pkt2_size) == disc_sock ) 2107 { 2108 if(packet2->code == CODE_PADO) 2109 { 2110 iTimeStamp = checkServerRecord(packet2->ethhdr.h_source); 2111 if(iTimeStamp < iOldestTimeStamp) 2112 { 2113 packet_temp = packet; 2114 packet = packet2; 2115 packet2 = packet_temp; 2116 pkt_size = pkt2_size; 2117 } 2118 } 2119 } 2120 free(packet2); 2121 } 2122 } 2123 /* foxconn Bob Guo added end 10/25/2007 */ 2124#endif 2125 /* Foxconn added start pling 12/20/2006 */ 2126 /* Touch a file on /tmp to indicate PADO is received */ 2127 if (1) 2128 { 2129 FILE *fp; 2130 struct sysinfo info; 2131#ifdef MULTIPLE_PPPOE 2132 /* fprintf(stderr, "PPPOE%d: PADO received\n", ppp_ifunit); */ 2133#else 2134 /* foxconn wklin modified start, 07/26/2007 */ 2135 /* system("echo \"DEBUG: PADO received\" > /dev/console"); */ 2136 time(&tm); 2137 fprintf(stderr, "PPPOE: PADO received %s\n", ctime(&tm)); 2138 /* foxconn wklin modified end, 07/26/2007 */ 2139#endif 2140 if ((fp = fopen("/tmp/PADO", "w")) != NULL) { 2141 sysinfo(&info); /* save current time in file */ 2142 fprintf(fp, "%ld", info.uptime); 2143 fclose(fp); 2144 } 2145 } 2146 /* Foxconn added end ling 12/20/2006 */ 2147 2148 2149#ifdef __linux__ 2150 memcpy(dst_addr, packet->ethhdr.h_source, sizeof(dst_addr)); 2151#else 2152 memcpy(dst_addr, packet->ethhdr.ether_shost, sizeof(dst_addr)); 2153#endif 2154 /* Foxconn added start Winster Chan 11/25/2005 */ 2155 /* Stored tags of PADO */ 2156 memset(pado_tags, 0x0, sizeof(pado_tags)); 2157 if ((htons(packet->length) < 0) || (htons(packet->length) > sizeof(pado_tags))) { 2158 pado_tag_size = sizeof(pado_tags); 2159 } 2160 else { 2161 pado_tag_size = (int)(htons(packet->length)); 2162 } 2163 memcpy((char *)pado_tags, (char *)(packet + 1), pado_tag_size); 2164 /* Foxconn added end Winster Chan 11/25/2005 */ 2165 2166 /* send PADR */ 2167 /* foxconn wklin modified, 03/27/2007, add service name */ 2168 if ((pkt_size = create_padr(packet, src_addr, dst_addr, service_name)) == 0) { 2169 fprintf(stderr, "pppoe: unable to create PADR packet\n"); 2170 exit(1); 2171 } 2172 if (send_packet(disc_sock, packet, pkt_size+14, if_name) < 0) { 2173 fprintf(stderr, "pppoe: unable to send PADR packet\n"); 2174 exit(1); 2175 } 2176 2177 /* foxconn wklin modified start, 07/31/2008 */ 2178 /* 0. Process only packets from our target pppoe server. 2179 * 1. track the time when sending PADR. 2180 * 2. If received PADO, resend PADR (needed?). 2181 * 3. If retried for 5 times, send PADT. 2182 * 4. If wait for more than 10 seconds after sending the previous PADR, 2183 * send PADT. 2184 */ 2185 time(&tm); 2186 /* wait for PADS */ 2187#ifdef __linux__ 2188 while ((ret_sock=read_packet(disc_sock, packet, &pkt_size)) != disc_sock || 2189 (memcmp(packet->ethhdr.h_source, dst_addr, sizeof(dst_addr)) != 0) || 2190 (packet->code != CODE_PADS && packet->code != CODE_PADT)) 2191#else 2192 while (read_packet(disc_sock, packet, &pkt_size) != disc_sock || 2193 (memcmp(packet->ethhdr.ether_shost, 2194 dst_addr, sizeof(dst_addr)) != 0)) 2195#endif 2196 { 2197 static int retried=0; /* wklin added, 01/26/2007 */ 2198 2199 if (ret_sock != disc_sock) { 2200 if (time(NULL)-tm > 10) { 2201 retried = 0; 2202 packet->code = CODE_PADT; /* fake packet */ 2203 break; 2204 } 2205 else 2206 continue; 2207 } 2208 /* Resend PADR only if it's from our target pppoe server and 2209 * the code is PADO, otherwise ignore the received packet. 2210 */ 2211 if (memcmp(packet->ethhdr.h_source, dst_addr, sizeof(dst_addr)) == 0) { 2212 if (packet->code != CODE_PADO) { /* PADI? PADR? */ 2213 retried = 0; 2214 packet->code = CODE_PADT; /* fake packet */ 2215 break; 2216 } 2217 2218 /* Received PADO */ 2219 if (retried++ == 5) { 2220 retried = 0; 2221 packet->code = CODE_PADT; 2222 break; 2223 } 2224 2225 /* Foxconn add start James 04/10/2009 */ 2226 /*if we recieve two PADO(from the same MAC) in 2 seconds, we only send one PADR.*/ 2227 if (time(NULL) - tm < 2) 2228 continue; 2229 /* Foxconn add end James 04/10/2009 */ 2230 2231 /* send PADR */ 2232 /* foxconn wklin modified, 03/27/2007, add service name */ 2233 if ((pkt_size = create_padr(packet, src_addr, dst_addr, service_name)) == 0) { 2234 fprintf(stderr, "pppoe: unable to create PADR packet\n"); 2235 exit(1); 2236 } 2237 if (send_packet(disc_sock, packet, pkt_size+14, if_name) < 0) { 2238 fprintf(stderr, "pppoe: unable to send PADR packet\n"); 2239 exit(1); 2240 } 2241 time(&tm); /* track the time when sending PADR */ 2242 } 2243 /* else.. packets not from target server */ 2244#ifndef MULTIPLE_PPPOE 2245 /* wklin modified end, 01/26/2007 */ 2246 continue; 2247#endif 2248 } /* end while waiting PADS */ 2249 /* foxconn wklin modified end, 07/31/2008 */ 2250 2251 /* foxconn James added start, 11/12/2008 @new_internet_detection */ 2252#ifdef NEW_WANDETECT 2253 if (bWanDetect && packet->code == CODE_PADS) 2254 { 2255 FILE *fp; 2256 struct sysinfo info; 2257 2258 time(&tm); 2259 fprintf(stderr, "PPPOE: PADS received %s\n", ctime(&tm)); 2260 if ((fp = fopen("/tmp/PADS", "w")) != NULL) { 2261 sysinfo(&info); /* save current time in file */ 2262 fprintf(fp, "%ld", info.uptime); 2263 fclose(fp); 2264 } 2265 } 2266#endif 2267 /* foxconn James added end, 11/12/2008 @new_internet_detection */ 2268 2269 if (packet->code == CODE_PADT) /* early termination */ 2270 { 2271#ifdef MULTIPLE_PPPOE 2272 sleep(3); 2273 goto resend_padi; 2274#else 2275 cleanup_and_exit(0); 2276#endif 2277 } 2278 2279 session = packet->session; 2280 2281 /* foxconn wklin added start, 07/31/2007 */ 2282 if (session == 0) { /* PADS generic error */ 2283 sleep(3); /* wait for 3 seconds and exit, retry */ 2284#ifdef MULTIPLE_PPPOE 2285 goto resend_padi; 2286#else 2287 cleanup_and_exit(0); 2288#endif 2289 } 2290 2291 /* Foxconn add start, Max Ding, 04/23/2009 not use pppd to reduce memory usage */ 2292#ifdef NEW_WANDETECT 2293 if (bWanDetect) 2294 { 2295 /* Create PADT to end it */ 2296 sigint2(SIGUSR1); 2297 /*cleanup_and_exit(0);*/ 2298 } 2299#endif 2300 /* Foxconn add end, Max Ding, 04/23/2009 */ 2301 2302 time(&tm); 2303#ifdef MULTIPLE_PPPOE 2304 fprintf(stderr, "PPPOE%d: PADS received (%d) %s\n", 2305 ppp_ifunit, ntohs(session), ctime(&tm)); 2306 /* Foxconn Bob Guo added start 10/25/2007*/ 2307 updateServerRecord(packet->ethhdr.h_source); 2308 /* Foxconn Bob Guo added end 10/25/2007*/ 2309#else 2310 fprintf(stderr, "PPPOE: session id = %d, %s\n", htons(session), ctime(&tm)); 2311#endif 2312 2313 /* foxconn wklin added end, 07/31/2007 */ 2314 2315 if ((sess_sock = open_interface(if_name,ETH_P_PPPOE_SESS,NULL)) < 0) { 2316 fprintf(log_file, "pppoe: unable to create raw socket\n"); 2317#ifdef MULTIPLE_PPPOE 2318 exit(1); 2319#else 2320 cleanup_and_exit(1); 2321#endif 2322 } 2323 2324 /* Foxconn added start, Winster Chan, 06/26/2006 */ 2325 memcpy(dstMac, dst_addr, ETH_ALEN); 2326 sessId = packet->session; 2327 2328 /* Connect pptp kernel module */ 2329 2330#ifdef MULTIPLE_PPPOE 2331 pptp_pppox_open(&poxfd, &pppfd); 2332 2333 if (poxfd == -1) { 2334 fprintf(stderr, "pppoe: poxfd == -1\n"); 2335 cleanup_and_exit(1); 2336 /* 2337 close(poxfd); 2338 exit(1);*/ 2339 } 2340 2341 if (pppfd == -1) { 2342 fprintf(stderr, "pppoe: pppfd == -1\n"); 2343 cleanup_and_exit(1); 2344 /* 2345 close(pppfd); 2346 exit(1);*/ 2347 } 2348 2349 if ( 0 > pptp_pppox_connect(&poxfd, &pppfd)) { 2350 fprintf(stderr, "error connect to pppox\n"); 2351 cleanup_and_exit(1); 2352 2353 2354 /* 2355 exit(1);*/ 2356 } 2357 2358 if (ppp_ifunit == 0) 2359 fp = fopen(PPP_PPPOE_SESSION, "w+"); 2360 else 2361 fp = fopen(PPP_PPPOE2_SESSION, "w+"); 2362 2363 if (fp) { 2364 /* Save the PPPoE server MAC address and Session ID */ 2365 fprintf(fp, "%02x:%02x:%02x:%02x:%02x:%02x %d\n", 2366 (unsigned char)(dst_addr[0]), (unsigned char)(dst_addr[1]), 2367 (unsigned char)(dst_addr[2]), (unsigned char)(dst_addr[3]), 2368 (unsigned char)(dst_addr[4]), (unsigned char)(dst_addr[5]), 2369 (int)htons(session)); 2370 fclose(fp); 2371 } 2372#else 2373 2374 /* foxconn wklin modified start, 07/31/2007 */ 2375 if ( 0 > pptp_pppox_connect(&poxfd, &pppfd)) 2376 cleanup_and_exit(1); 2377 /* foxconn wklin modified end, 07/31/2007 */ 2378 /* Foxconn added end, Winster Chan, 06/26/2006 */ 2379 2380 /* Foxconn added start Winster Chan 12/05/2005 */ 2381 if (!(fp = fopen(PPP_PPPOE_SESSION, "w"))) { 2382 perror(PPP_PPPOE_SESSION); 2383 } 2384 else { 2385 /* Save the PPPoE server MAC address and Session ID */ 2386 fprintf(fp, "%02x:%02x:%02x:%02x:%02x:%02x %d\n", 2387 (unsigned char)(dst_addr[0]), (unsigned char)(dst_addr[1]), 2388 (unsigned char)(dst_addr[2]), (unsigned char)(dst_addr[3]), 2389 (unsigned char)(dst_addr[4]), (unsigned char)(dst_addr[5]), 2390 (int)htons(session)); 2391 fclose(fp); 2392 } 2393 /* Foxconn added end Winster Chan 12/05/2005 */ 2394#endif 2395 clean_child = 0; 2396 signal(SIGCHLD, sigchild); 2397 2398 while (1) { 2399 FD_ZERO(&allfdset); 2400 FD_SET(sess_sock, &allfdset); 2401 FD_SET(disc_sock, &allfdset); 2402 FD_SET(0, &allfdset); 2403 if (select((sess_sock>disc_sock?sess_sock:disc_sock) + 1, &allfdset, 2404 (fd_set *) NULL, (fd_set *) NULL, NULL) <= 0) 2405 continue; /* timeout or error */ 2406 2407 if (FD_ISSET(disc_sock, &allfdset)) { 2408#ifdef MULTIPLE_PPPOE 2409 if (read_packet_nowait(disc_sock, packet, &pkt_size) == disc_sock) { 2410 if (memcmp(packet->ethhdr.h_dest, src_addr, sizeof(src_addr))!=0){ 2411 /* fprintf(stderr, "pppoe: received a packet not for 2412 * me.\n");*/ 2413 continue; 2414 } 2415 if (packet->code == CODE_PADT && packet->session == session) { 2416 time(&tm); 2417 fprintf(stderr, "PPPOE%d: PADT received (%d) %s\n", ppp_ifunit, ntohs(session), ctime(&tm)); 2418 break; /* go terminate */ 2419 } 2420 } 2421#else 2422 if ((read_packet2(disc_sock, packet, &pkt_size) == disc_sock) && 2423 (memcmp(packet->ethhdr.h_source, dst_addr, sizeof(dst_addr))==0)){ 2424 if (packet->code == CODE_PADT) { 2425 time(&tm); 2426 fprintf(stderr, "PPPOE: PADT received (%d/%d), %s\n", 2427 ntohs(packet->session), ntohs(session),ctime(&tm)); 2428 } 2429 if (packet->code == CODE_PADT && packet->session == session) 2430 break; /* cleanup and exit */ 2431 } 2432#endif 2433 } 2434 2435 if (FD_ISSET(sess_sock, &allfdset)) { 2436 sess_handler(); 2437 } 2438 2439 if (FD_ISSET(0, &allfdset)) { 2440 pppd_handler(); 2441 } 2442 } 2443 cleanup_and_exit(0); /* foxconn wklin added, 08/10/2007 */ 2444 return 0; 2445} 2446 2447 2448