summaryrefslogtreecommitdiff
path: root/jni/src/pppoe_wrapper.c (plain)
blob: 8cf721fc3eed673bfa496bcd5423b0bf7789e024
1#include <stdio.h>
2#include <ctype.h>
3#include <stdlib.h>
4#include <string.h>
5#include <unistd.h>
6#include <signal.h>
7#include <errno.h>
8#include <fcntl.h>
9#include <syslog.h>
10#include <netdb.h>
11#include <utmp.h>
12#include <pwd.h>
13#include <setjmp.h>
14#include <sys/param.h>
15#include <sys/types.h>
16#include <sys/wait.h>
17#include <sys/time.h>
18#include <sys/resource.h>
19#include <sys/stat.h>
20#include <sys/socket.h>
21#include <netinet/in.h>
22#include <arpa/inet.h>
23#include <cutils/properties.h>
24#include <sys/un.h>
25
26#include <android/log.h>
27
28#include "pppoe_ctrl.h"
29
30#define LOCAL_TAG "PPPOE_WRAPPER"
31
32#define PPP_CMD_LEN_MAX 512
33
34static char ppp_cmd[PPP_CMD_LEN_MAX];
35
36
37static pid_t read_pid(const char *pidfile)
38{
39 FILE *fp;
40 pid_t pid;
41
42 if ((fp = fopen(pidfile, "r")) == NULL) {
43 __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,
44 "failed to open %s (%s)\n", pidfile, strerror(errno));
45 errno = ENOENT;
46 return 0;
47 }
48
49 if (fscanf(fp, "%d", &pid) != 1) {
50 __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,
51 "failed to read pid, make pid as 0\n");
52 pid = 0;
53 }
54 fclose(fp);
55
56 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,
57 "read_pid: %d\n", pid);
58
59 return pid;
60}
61
62static int ppp_stop()
63{
64 pid_t pid;
65 int ret;
66
67 pid = read_pid(PPPOE_PIDFILE);
68 if ( 0 == pid ) {
69 __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,
70 "failed to stop ppp for no pid got\n" );
71 return -1;
72 }
73
74 ret = kill(pid, 0);
75 if ( 0 != ret ) {
76 __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,
77 "process(#%d) died already???\n", pid );
78 return -1;
79 }
80
81 /*
82 The signals SIGKILL and SIGSTOP cannot
83 be caught, blocked, or ignored.
84 So send SIGUSR1 to notify pppoe to send PADT.
85 */
86 ret = kill(pid, SIGUSR1);
87 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,
88 "Send SIGUSR1 to pid(#%d), ret = %d\n", pid, ret );
89
90 /*
91 If no sleep before send SIGKILL, pppoe will just being killed
92 rather than sending PADT.
93 */
94 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,
95 "sleep before send SIGKILL to pid(#%d)\n", pid );
96
97 sleep(5);
98
99 ret = kill(pid, SIGKILL);
100 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,
101 "Send SIGKILL to pid(#%d), ret = %d\n", pid, ret );
102
103 unlink(PPPOE_PIDFILE);
104 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,
105 "removed %s\n", PPPOE_PIDFILE );
106
107 return 0;
108}
109
110
111int main(int argc, char * argv[])
112{
113 int socket_fd;
114 struct sockaddr_un name;
115 int i, len;
116 int ppp_cmd_len;
117
118 socket_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
119 if (socket_fd < 0) {
120 __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,
121 "failed to create socket(%s)\n", strerror(errno));
122 exit(-1);
123 }
124
125 memset(&name,0,sizeof(name));
126 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,
127 "create AF_UNIX socket:%d OK\n",socket_fd);
128
129 unlink("/dev/socket/pppd");
130 name.sun_family = AF_UNIX;
131 strncpy(name.sun_path, "/dev/socket/pppd", sizeof(name.sun_path) - 1);
132
133 if (bind(socket_fd, (struct sockaddr *)&name, sizeof(struct sockaddr_un)) < 0) {
134 __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,
135 "failed to bind socket(%s)\n", strerror(errno));
136 exit(-1);
137 }
138
139 {
140 struct timeval tv;
141 int res;
142 fd_set rfds;
143
144 for (;;) {
145 tv.tv_sec = 10;
146 tv.tv_usec = 0;
147 FD_ZERO(&rfds);
148 FD_SET(socket_fd, &rfds);
149 res = select(socket_fd + 1, &rfds, NULL, NULL, &tv);
150 if (FD_ISSET(socket_fd, &rfds)) {
151 res = recv(socket_fd, ppp_cmd, PPP_CMD_LEN_MAX-1, 0);
152 if (res < 0)
153 return res;
154 ppp_cmd[res] = '\0';
155 ppp_cmd_len = res;
156 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,
157 "recv cmd: [%s]\n",ppp_cmd);
158 if ( 0 == strcmp(ppp_cmd, "ppp-stop") ) {
159 ppp_stop();
160 }
161 else {
162 system(ppp_cmd);
163 }
164 }
165 }
166 }
167
168 __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG, "EXIT\n");
169 close(socket_fd);
170 return 0;
171}
172
173