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 | |
34 | static char ppp_cmd[PPP_CMD_LEN_MAX]; |
35 | |
36 | |
37 | static 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 | |
62 | static 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 | |
111 | int 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 |