blob: a1ef8447aa266846a2d09ac6bf5d837fccec6d18
1 | #include <stdlib.h> |
2 | #include <stdio.h> |
3 | #include <stdarg.h> |
4 | #include <string.h> |
5 | |
6 | #include <sys/types.h> |
7 | #include <errno.h> |
8 | |
9 | #include <unistd.h> |
10 | |
11 | #include <sys/socket.h> |
12 | #include <netinet/in.h> |
13 | |
14 | #include <sys/un.h> |
15 | #include <android/log.h> |
16 | #include "pppoe_ctrl.h" |
17 | |
18 | |
19 | #define LOCAL_TAG "PPPOE_CTRL" |
20 | |
21 | struct pppoe_ctrl * pppoe_ctrl_open(const char *ctrl_path) |
22 | { |
23 | struct pppoe_ctrl *ctrl; |
24 | static int counter = 0; |
25 | int ret; |
26 | size_t res; |
27 | int tries = 0; |
28 | |
29 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"%s(ctrl_path = %s)\n", __FUNCTION__, ctrl_path); |
30 | ctrl = malloc(sizeof(*ctrl)); |
31 | if (ctrl == NULL) |
32 | return NULL; |
33 | memset(ctrl, 0, sizeof(*ctrl)); |
34 | |
35 | ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0); |
36 | if (ctrl->s < 0) { |
37 | free(ctrl); |
38 | return NULL; |
39 | } |
40 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"%s(ctrl->s = %d)\n", __FUNCTION__, ctrl->s); |
41 | |
42 | ctrl->local.sun_family = AF_UNIX; |
43 | counter++; |
44 | try_again: |
45 | ret = snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path), |
46 | "/dev/socket/ppp_cli-%d", getpid()); |
47 | |
48 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"%s: ctrl->local.sun_path: %s\n", __FUNCTION__, ctrl->local.sun_path); |
49 | if (ret < 0 || (size_t) ret >= sizeof(ctrl->local.sun_path)) { |
50 | close(ctrl->s); |
51 | free(ctrl); |
52 | return NULL; |
53 | } |
54 | tries++; |
55 | if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, |
56 | sizeof(ctrl->local)) < 0) { |
57 | #if 0 |
58 | if (errno == EADDRINUSE && tries < 2) { |
59 | /* |
60 | * getpid() returns unique identifier for this instance |
61 | * of pppoe_ctrl, so the existing socket file must have |
62 | * been left by unclean termination of an earlier run. |
63 | * Remove the file and try again. |
64 | */ |
65 | unlink(ctrl->local.sun_path); |
66 | goto try_again; |
67 | } |
68 | |
69 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"%s: bind failed(%s)\n", __FUNCTION__, strerror(errno)); |
70 | close(ctrl->s); |
71 | free(ctrl); |
72 | return NULL; |
73 | #endif |
74 | } |
75 | |
76 | ctrl->dest.sun_family = AF_UNIX; |
77 | res = strlcpy(ctrl->dest.sun_path, ctrl_path, |
78 | sizeof(ctrl->dest.sun_path)); |
79 | if (res >= sizeof(ctrl->dest.sun_path)) { |
80 | close(ctrl->s); |
81 | free(ctrl); |
82 | return NULL; |
83 | } |
84 | |
85 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"%s: ctrl->dest.sun_path: %s\n", __FUNCTION__, ctrl->dest.sun_path); |
86 | if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, |
87 | sizeof(ctrl->dest)) < 0) { |
88 | close(ctrl->s); |
89 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"%s: connection failed\n", __FUNCTION__); |
90 | unlink(ctrl->local.sun_path); |
91 | free(ctrl); |
92 | return NULL; |
93 | } |
94 | |
95 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"connection to ppp_wrapper OK\n"); |
96 | return ctrl; |
97 | } |
98 | |
99 | |
100 | void pppoe_ctrl_close(struct pppoe_ctrl *ctrl) |
101 | { |
102 | if (ctrl == NULL) |
103 | return; |
104 | unlink(ctrl->local.sun_path); |
105 | if (ctrl->s >= 0) |
106 | close(ctrl->s); |
107 | free(ctrl); |
108 | } |
109 | |
110 | |
111 | |
112 | int pppoe_ctrl_request(struct pppoe_ctrl *ctrl, const char *cmd, size_t cmd_len) |
113 | { |
114 | if (send(ctrl->s, cmd, cmd_len, 0) < 0) { |
115 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"send command[%s] failed\n", cmd); |
116 | return -1; |
117 | } |
118 | |
119 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"send command[%s] OK\n", cmd); |
120 | return 0; |
121 | } |
122 | |
123 | |
124 | int pppoe_ctrl_get_fd(struct pppoe_ctrl *ctrl) |
125 | { |
126 | return ctrl->s; |
127 | } |
128 | |
129 | |
130 |