summaryrefslogtreecommitdiff
authorkejun.gao <kejun.gao@amlogic.com>2012-08-29 06:06:21 (GMT)
committer tao.dong <tao.dong@amlogic.com>2012-09-04 10:15:52 (GMT)
commit8ab8c604d0642c473d3a395b3421afa51694af9c (patch)
tree1ef28e51d5f4a8b89f2f647144e94fb477d3a6e3
parent10d94acac125f198f3b2542cdc625ed8b14497f1 (diff)
downloadpppoe-8ab8c604d0642c473d3a395b3421afa51694af9c.zip
pppoe-8ab8c604d0642c473d3a395b3421afa51694af9c.tar.gz
pppoe-8ab8c604d0642c473d3a395b3421afa51694af9c.tar.bz2
1. Save PADT when PDAS received.
2. Send saved PADT by command "pcli terminate". 3. In init.rc, add service: service close_pppoe /system/bin/pcli terminate class core oneshot on property:net.eth0.status=up start close_pppoe 4. In EthernetStateTraker.java, when ether wire is detected, change net.eth0.status as up.
Diffstat
-rwxr-xr-xAndroid.mk4
-rwxr-xr-xjni/src/common.c159
-rwxr-xr-xjni/src/discovery.c3
-rwxr-xr-xjni/src/pppoe.c2
-rwxr-xr-xjni/src/pppoe_cli.c11
5 files changed, 176 insertions, 3 deletions
diff --git a/Android.mk b/Android.mk
index 95cc205..3d4819a 100755
--- a/Android.mk
+++ b/Android.mk
@@ -48,7 +48,9 @@ include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= jni/src/pppoe_cli.c
+LOCAL_SRC_FILES:= jni/src/pppoe_cli.c \
+ jni/src/common.c
+
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := pcli
LOCAL_SHARED_LIBRARIES := libcutils libnetutils
diff --git a/jni/src/common.c b/jni/src/common.c
index b8c53fd..36f644a 100755
--- a/jni/src/common.c
+++ b/jni/src/common.c
@@ -45,6 +45,7 @@ static char const RCSID[] =
#include <sys/types.h>
#include <pwd.h>
+#include "../../ppp/pppd/pathnames.h"
/* Are we running SUID or SGID? */
int IsSetID = 0;
@@ -570,6 +571,164 @@ sendPADT(PPPoEConnection *conn, char const *msg)
syslog(LOG_INFO,"Sent PADT");
}
+
+int
+getRawSocket(char const *ifname)
+{
+ int ret;
+ int optval=1;
+ int fd;
+ struct ifreq ifr;
+ int domain, stype;
+
+ struct sockaddr_ll sa;
+
+ memset(&sa, 0, sizeof(sa));
+
+ domain = PF_PACKET;
+ stype = SOCK_RAW;
+
+ fd = socket(domain, stype, htons(ETH_PPPOE_DISCOVERY));
+ if (fd < 0) {
+ syslog(LOG_INFO,"failed to create raw socket");
+ return -1;
+ }
+
+ ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval));
+ if (ret < 0) {
+ syslog(LOG_INFO,"failed to setsockopt");
+ return -1;
+ }
+
+
+ /* Get interface index */
+ sa.sll_family = AF_PACKET;
+ sa.sll_protocol = htons(ETH_PPPOE_DISCOVERY);
+
+ strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ ret = ioctl(fd, SIOCGIFINDEX, &ifr);
+ if (ret < 0) {
+ syslog(LOG_INFO,"failed to ioctl");
+ return -1;
+ }
+ sa.sll_ifindex = ifr.ifr_ifindex;
+
+ /* We're only interested in packets on specified interface */
+ ret = bind(fd, (struct sockaddr *) &sa, sizeof(sa));
+ if (ret < 0) {
+ syslog(LOG_INFO,"failed to bind");
+ return -1;
+ }
+
+ return fd;
+}
+
+
+void
+sendSavedPADT(char *padt_file)
+{
+ FILE *file_fd = NULL;
+ char *packet;
+ long len;
+ int fd;
+
+ file_fd = fopen(padt_file, "r");
+ if (!file_fd) {
+ syslog(LOG_INFO,"failed to read padt");
+ return;
+ }
+
+ fseek(file_fd, 0, SEEK_END);
+ len = ftell(file_fd);
+ if (len < 0) {
+ goto free_file_fd;
+ }
+
+ packet = malloc(len);
+ if (!packet){
+ syslog(LOG_INFO, "sendSavedPADT: failed to malloc");
+ goto free_file_fd;
+ }
+
+ fseek(file_fd, 0, SEEK_SET);
+ fread(packet, 1, len, file_fd);
+
+ fd = getRawSocket("eth0");
+ if ( fd < 0){
+ syslog(LOG_INFO, "sendSavedPADT: failed to getRawSocket");
+ goto free_packet;
+
+ }
+ send( fd, packet, len, 0);
+ syslog(LOG_INFO, "Send SavedPADT(fd = %d) by eth0", fd);
+
+ close(fd);
+
+free_packet:
+ free(packet);
+
+free_file_fd:
+ fclose(file_fd);
+ }
+
+
+void
+savePADT(PPPoEConnection *conn, char const *msg)
+{
+ FILE *padt_file_bin = NULL;
+ PPPoEPacket packet;
+ unsigned char *cursor = packet.payload;
+
+ UINT16_t plen = 0;
+
+ memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN);
+ memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN);
+
+ packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery);
+ packet.ver = 1;
+ packet.type = 1;
+ packet.code = CODE_PADT;
+ packet.session = conn->session;
+
+ /* Reset Session to zero so there is no possibility of
+ recursive calls to this function by any signal handler */
+ //conn->session = 0;
+
+ /* If we're using Host-Uniq, copy it over */
+ if (conn->useHostUniq) {
+ PPPoETag hostUniq;
+ pid_t pid = getpid();
+ hostUniq.type = htons(TAG_HOST_UNIQ);
+ hostUniq.length = htons(sizeof(pid));
+ memcpy(hostUniq.payload, &pid, sizeof(pid));
+ memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
+ cursor += sizeof(pid) + TAG_HDR_SIZE;
+ plen += sizeof(pid) + TAG_HDR_SIZE;
+ }
+
+ /* Copy error message */
+ if (msg) {
+ PPPoETag err;
+ size_t elen = strlen(msg);
+ err.type = htons(TAG_GENERIC_ERROR);
+ err.length = htons(elen);
+ strcpy((char *) err.payload, msg);
+ memcpy(cursor, &err, elen + TAG_HDR_SIZE);
+ cursor += elen + TAG_HDR_SIZE;
+ plen += elen + TAG_HDR_SIZE;
+ }
+
+ packet.length = htons(plen);
+
+ padt_file_bin = fopen(_ROOT_PATH "/etc/ppp/padt_bin", "w");
+ if (!padt_file_bin) {
+ syslog(LOG_INFO,"failed to save padt_bin");
+ }
+ fwrite(&packet, (int) (plen + HDR_SIZE), 1, padt_file_bin);
+ fflush(padt_file_bin);
+ fclose(padt_file_bin);
+}
+
/***********************************************************************
*%FUNCTION: sendPADTf
*%ARGUMENTS:
diff --git a/jni/src/discovery.c b/jni/src/discovery.c
index c92ceef..63884bc 100755
--- a/jni/src/discovery.c
+++ b/jni/src/discovery.c
@@ -652,6 +652,7 @@ waitForPADS(PPPoEConnection *conn, int timeout)
* Performs the PPPoE discovery phase
***********************************************************************/
static struct timeval current_time;
+void savePADT(PPPoEConnection *conn, char const *msg);
static int g_padi_sent = 0;
void
@@ -730,6 +731,8 @@ discovery(PPPoEConnection *conn)
timeout *= 2;
} while (conn->discoveryState == STATE_SENT_PADR);
+ savePADT(conn, "RP-PPPoE: Received gaokj to disconnect");
+
/* We're done. */
conn->discoveryState = STATE_SESSION;
return;
diff --git a/jni/src/pppoe.c b/jni/src/pppoe.c
index 5809f92..6ad8293 100755
--- a/jni/src/pppoe.c
+++ b/jni/src/pppoe.c
@@ -645,7 +645,7 @@ main(int argc, char *argv[])
} else {
conn.discoverySocket =
openInterface(conn.ifName, Eth_PPPOE_Discovery, conn.myEth);
- syslog( LOG_INFO, "discovery\n");
+ syslog( LOG_INFO, "begin discovery conn.myEth =%p\n", conn.myEth);
discovery(&conn);
}
if (optSkipSession) {
diff --git a/jni/src/pppoe_cli.c b/jni/src/pppoe_cli.c
index 9c23af5..e453416 100755
--- a/jni/src/pppoe_cli.c
+++ b/jni/src/pppoe_cli.c
@@ -35,10 +35,19 @@ int main(int argc, char *argv[])
struct netwrapper_ctrl * ctrl;
if (argc < 2 || (0 != strcmp( "connect", argv[1]) &&
- 0 != strcmp( "disconnect", argv[1]) )) {
+ 0 != strcmp( "disconnect", argv[1] ) &&
+ 0 != strcmp( "terminate", argv[1] ))) {
usage();
return -2;
}
+
+ if (0 == strcmp( "terminate", argv[1] )) {
+ for ( i = 0; i < 3; i++ ) {
+ sendSavedPADT(_ROOT_PATH "/etc/ppp/padt_bin");
+ sleep(1);
+ }
+ return 0;
+ }
ctrl = netwrapper_ctrl_open(_ROOT_PATH "/etc/ppp/pppcli", PPPOE_WRAPPER_SERVER_PATH);
if (ctrl == NULL) {