18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*********************************************************************** 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* common.c 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Implementation of user-space PPPoE redirector for Linux. 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Common functions used by PPPoE client and server 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Copyright (C) 2000 by Roaring Penguin Software Inc. 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* This program may be distributed according to the terms of the GNU 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* General Public License, version 2 or (at your option) any later version. 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char const RCSID[] = 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project"$Id: common.c,v 1.2 2004/01/13 04:03:58 paulus Exp $"; 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppoe.h" 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_SYSLOG_H 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <syslog.h> 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h> 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <errno.h> 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h> 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_UNISTD_H 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <unistd.h> 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: parsePacket 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* packet -- the PPPoE discovery packet to parse 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* func -- function called for each tag in the packet 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* extra -- an opaque data pointer supplied to parsing function 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 0 if everything went well; -1 if there was an error 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Parses a PPPoE discovery packet, calling "func" for each tag in the packet. 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* "func" is passed the additional argument "extra". 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectparsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra) 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t len = ntohs(packet->length); 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *curTag; 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t tagType, tagLen; 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (packet->ver != 1) { 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE version (%d)", (int) packet->ver); 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (packet->type != 1) { 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE type (%d)", (int) packet->type); 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Do some sanity checks on packet */ 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */ 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE packet length (%u)", len); 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Step through the tags */ 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project curTag = packet->payload; 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while(curTag - packet->payload < len) { 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Alignment is not guaranteed, so do this by hand... */ 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tagType = (((UINT16_t) curTag[0]) << 8) + 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (UINT16_t) curTag[1]; 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tagLen = (((UINT16_t) curTag[2]) << 8) + 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (UINT16_t) curTag[3]; 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (tagType == TAG_END_OF_LIST) { 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE tag length (%u)", tagLen); 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra); 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project curTag = curTag + TAG_HDR_SIZE + tagLen; 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: findTag 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* packet -- the PPPoE discovery packet to parse 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* type -- the type of the tag to look for 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* tag -- will be filled in with tag contents 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* A pointer to the tag if one of the specified type is found; NULL 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* otherwise. 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Looks for a specific tag type. 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunsigned char * 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectfindTag(PPPoEPacket *packet, UINT16_t type, PPPoETag *tag) 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t len = ntohs(packet->length); 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *curTag; 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t tagType, tagLen; 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (packet->ver != 1) { 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE version (%d)", (int) packet->ver); 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return NULL; 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (packet->type != 1) { 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE type (%d)", (int) packet->type); 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return NULL; 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Do some sanity checks on packet */ 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */ 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE packet length (%u)", len); 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return NULL; 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Step through the tags */ 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project curTag = packet->payload; 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while(curTag - packet->payload < len) { 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Alignment is not guaranteed, so do this by hand... */ 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tagType = (((UINT16_t) curTag[0]) << 8) + 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (UINT16_t) curTag[1]; 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tagLen = (((UINT16_t) curTag[2]) << 8) + 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (UINT16_t) curTag[3]; 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (tagType == TAG_END_OF_LIST) { 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return NULL; 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid PPPoE tag length (%u)", tagLen); 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return NULL; 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (tagType == type) { 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(tag, curTag, tagLen + TAG_HDR_SIZE); 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return curTag; 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project curTag = curTag + TAG_HDR_SIZE + tagLen; 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return NULL; 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: printErr 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* str -- error message 1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Nothing 1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Prints a message to stderr and syslog. 1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectprintErr(char const *str) 1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fprintf(stderr, "pppoe: %s\n", str); 1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "%s", str); 1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: strDup 1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* str -- string to copy 1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* A malloc'd copy of str. Exits if malloc fails. 1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar * 1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectstrDup(char const *str) 1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *copy = malloc(strlen(str)+1); 1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!copy) { 1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("strdup failed"); 1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcpy(copy, str); 1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return copy; 1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef PPPOE_STANDALONE 1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: computeTCPChecksum 1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* ipHdr -- pointer to IP header 1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* tcpHdr -- pointer to TCP header 1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* The computed TCP checksum 1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectUINT16_t 1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectcomputeTCPChecksum(unsigned char *ipHdr, unsigned char *tcpHdr) 1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT32_t sum = 0; 1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t count = ipHdr[2] * 256 + ipHdr[3]; 1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *addr = tcpHdr; 1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char pseudoHeader[12]; 1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Count number of bytes in TCP header and data */ 1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project count -= (ipHdr[0] & 0x0F) * 4; 2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(pseudoHeader, ipHdr+12, 8); 2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pseudoHeader[8] = 0; 2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pseudoHeader[9] = ipHdr[9]; 2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pseudoHeader[10] = (count >> 8) & 0xFF; 2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pseudoHeader[11] = (count & 0xFF); 2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Checksum the pseudo-header */ 2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += * (UINT16_t *) pseudoHeader; 2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += * ((UINT16_t *) (pseudoHeader+2)); 2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += * ((UINT16_t *) (pseudoHeader+4)); 2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += * ((UINT16_t *) (pseudoHeader+6)); 2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += * ((UINT16_t *) (pseudoHeader+8)); 2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += * ((UINT16_t *) (pseudoHeader+10)); 2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Checksum the TCP header and data */ 2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (count > 1) { 2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += * (UINT16_t *) addr; 2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project addr += 2; 2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project count -= 2; 2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (count > 0) { 2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum += *addr; 2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while(sum >> 16) { 2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sum = (sum & 0xffff) + (sum >> 16); 2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (UINT16_t) (~sum & 0xFFFF); 2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: clampMSS 2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* packet -- PPPoE session packet 2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* dir -- either "incoming" or "outgoing" 2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* clampMss -- clamp value 2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Nothing 2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Clamps MSS option if TCP SYN flag is set. 2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectclampMSS(PPPoEPacket *packet, char const *dir, int clampMss) 2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *tcpHdr; 2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *ipHdr; 2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *opt; 2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *endHdr; 2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *mssopt = NULL; 2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t csum; 2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int len, minlen; 2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* check PPP protocol type */ 2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (packet->payload[0] & 0x01) { 2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 8 bit protocol type */ 2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Is it IPv4? */ 2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (packet->payload[0] != 0x21) { 2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Nope, ignore it */ 2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ipHdr = packet->payload + 1; 2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project minlen = 41; 2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 16 bit protocol type */ 2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Is it IPv4? */ 2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (packet->payload[0] != 0x00 || 2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project packet->payload[1] != 0x21) { 2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Nope, ignore it */ 2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ipHdr = packet->payload + 2; 2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project minlen = 42; 2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Is it too short? */ 2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project len = (int) ntohs(packet->length); 2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (len < minlen) { 2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 20 byte IP header; 20 byte TCP header; at least 1 or 2 byte PPP protocol */ 2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Verify once more that it's IPv4 */ 2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((ipHdr[0] & 0xF0) != 0x40) { 2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Is it a fragment that's not at the beginning of the packet? */ 2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((ipHdr[6] & 0x1F) || ipHdr[7]) { 2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Yup, don't touch! */ 2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Is it TCP? */ 2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ipHdr[9] != 0x06) { 2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Get start of TCP header */ 3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tcpHdr = ipHdr + (ipHdr[0] & 0x0F) * 4; 3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Is SYN set? */ 3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!(tcpHdr[13] & 0x02)) { 3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Compute and verify TCP checksum -- do not touch a packet with a bad 3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project checksum */ 3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project csum = computeTCPChecksum(ipHdr, tcpHdr); 3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (csum) { 3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Bad TCP checksum %x", (unsigned int) csum); 3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Upper layers will drop it */ 3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Look for existing MSS option */ 3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project endHdr = tcpHdr + ((tcpHdr[12] & 0xF0) >> 2); 3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project opt = tcpHdr + 20; 3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (opt < endHdr) { 3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!*opt) break; /* End of options */ 3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch(*opt) { 3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case 1: 3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project opt++; 3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case 2: 3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (opt[1] != 4) { 3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Something fishy about MSS option length. */ 3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, 3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Bogus length for MSS option (%u) from %u.%u.%u.%u", 3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) opt[1], 3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[12], 3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[13], 3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[14], 3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[15]); 3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project mssopt = opt; 3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default: 3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (opt[1] < 2) { 3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Someone's trying to attack us? */ 3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, 3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Bogus TCP option length (%u) from %u.%u.%u.%u", 3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) opt[1], 3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[12], 3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[13], 3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[14], 3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (unsigned int) ipHdr[15]); 3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project opt += (opt[1]); 3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Found existing MSS option? */ 3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (mssopt) break; 3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* If MSS exists and it's low enough, do nothing */ 3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (mssopt) { 3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned mss = mssopt[2] * 256 + mssopt[3]; 3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (mss <= clampMss) { 3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project mssopt[2] = (((unsigned) clampMss) >> 8) & 0xFF; 3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project mssopt[3] = ((unsigned) clampMss) & 0xFF; 3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* No MSS option. Don't add one; we'll have to use 536. */ 3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Recompute TCP checksum */ 3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tcpHdr[16] = 0; 3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tcpHdr[17] = 0; 3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project csum = computeTCPChecksum(ipHdr, tcpHdr); 3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (* (UINT16_t *) (tcpHdr+16)) = csum; 3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* PPPOE_STANDALONE */ 3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*********************************************************************** 3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: sendPADT 3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* conn -- PPPoE connection 3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* msg -- if non-NULL, extra error message to include in PADT packet. 3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Nothing 3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Sends a PADT packet 3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectsendPADT(PPPoEConnection *conn, char const *msg) 3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project PPPoEPacket packet; 3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *cursor = packet.payload; 4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t plen = 0; 4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Do nothing if no session established yet */ 4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!conn->session) return; 4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Do nothing if no discovery socket */ 4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (conn->discoverySocket < 0) return; 4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); 4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); 4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); 4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project packet.ver = 1; 4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project packet.type = 1; 4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project packet.code = CODE_PADT; 4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project packet.session = conn->session; 4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Reset Session to zero so there is no possibility of 4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project recursive calls to this function by any signal handler */ 4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project conn->session = 0; 4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* If we're using Host-Uniq, copy it over */ 4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (conn->useHostUniq) { 4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project PPPoETag hostUniq; 4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project pid_t pid = getpid(); 4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hostUniq.type = htons(TAG_HOST_UNIQ); 4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hostUniq.length = htons(sizeof(pid)); 4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(hostUniq.payload, &pid, sizeof(pid)); 4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); 4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cursor += sizeof(pid) + TAG_HDR_SIZE; 4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project plen += sizeof(pid) + TAG_HDR_SIZE; 4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Copy error message */ 4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (msg) { 4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project PPPoETag err; 4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project size_t elen = strlen(msg); 4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project err.type = htons(TAG_GENERIC_ERROR); 4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project err.length = htons(elen); 4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcpy(err.payload, msg); 4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(cursor, &err, elen + TAG_HDR_SIZE); 4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cursor += elen + TAG_HDR_SIZE; 4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project plen += elen + TAG_HDR_SIZE; 4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Copy cookie and relay-ID if needed */ 4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (conn->cookie.type) { 4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CHECK_ROOM(cursor, packet.payload, 4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ntohs(conn->cookie.length) + TAG_HDR_SIZE); 4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); 4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; 4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; 4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (conn->relayId.type) { 4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CHECK_ROOM(cursor, packet.payload, 4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ntohs(conn->relayId.length) + TAG_HDR_SIZE); 4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); 4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; 4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; 4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project packet.length = htons(plen); 4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); 4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (conn->debugFile) { 4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dumpPacket(conn->debugFile, &packet, "SENT"); 4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fprintf(conn->debugFile, "\n"); 4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fflush(conn->debugFile); 4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_INFO,"Sent PADT"); 4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: parseLogErrs 4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* type -- tag type 4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* len -- tag length 4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* data -- tag data 4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* extra -- extra user data 4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Nothing 4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Picks error tags out of a packet and logs them. 4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectparseLogErrs(UINT16_t type, UINT16_t len, unsigned char *data, 4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project void *extra) 4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch(type) { 4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case TAG_SERVICE_NAME_ERROR: 4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "PADT: Service-Name-Error: %.*s", (int) len, data); 4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fprintf(stderr, "PADT: Service-Name-Error: %.*s\n", (int) len, data); 4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case TAG_AC_SYSTEM_ERROR: 4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "PADT: System-Error: %.*s", (int) len, data); 4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fprintf(stderr, "PADT: System-Error: %.*s\n", (int) len, data); 4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case TAG_GENERIC_ERROR: 4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "PADT: Generic-Error: %.*s", (int) len, data); 5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fprintf(stderr, "PADT: Generic-Error: %.*s\n", (int) len, data); 5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 505