1/* 2 * ppp scripts 3 * 4 * Copyright (C) 2009, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: ppp.c,v 1.19 2009/12/02 20:07:37 Exp $ 19 */ 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <unistd.h> 24#include <string.h> 25#include <sys/ioctl.h> 26#include <sys/socket.h> 27#include <netinet/in.h> 28#include <arpa/inet.h> 29#include <errno.h> 30#include <ctype.h> 31 32#include <bcmnvram.h> 33#include <shutils.h> 34#include <rc.h> 35 36#ifdef RTCONFIG_USB_MODEM 37#include <usb_info.h> 38#endif 39 40/* 41* parse ifname to retrieve unit # 42*/ 43int 44ppp_ifunit(char *ifname) 45{ 46 int unit; 47 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 48 49 for (unit = WAN_UNIT_FIRST; unit < WAN_UNIT_MAX; unit++) { 50 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 51 if (nvram_match(strcat_r(prefix, "pppoe_ifname", tmp), ifname)) 52 return unit; 53 } 54 55 return -1; 56} 57 58int 59ppp_linkunit(char *linkname) 60{ 61 if (strncmp(linkname, "wan", 3)) 62 return -1; 63 if (!isdigit(linkname[3])) 64 return -1; 65 return atoi(&linkname[3]); 66} 67 68/* 69 * Called when link comes up 70 */ 71int 72ipup_main(int argc, char **argv) 73{ 74 FILE *fp; 75 char *wan_ifname = safe_getenv("IFNAME"); 76 char *wan_linkname = safe_getenv("LINKNAME"); 77 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 78 char buf[256], *value; 79 int unit; 80 81 _dprintf("%s():: %s\n", __FUNCTION__, argv[0]); 82 83 /* Get unit from LINKNAME: ppp[UNIT] */ 84 if ((unit = ppp_linkunit(wan_linkname)) < 0) 85 return 0; 86 87 _dprintf("%s: unit=%d ifname=%s\n", __FUNCTION__, unit, wan_ifname); 88 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 89 90#ifdef DEBUG_RCTEST // Left for UI debug 91 int max_count = nvram_get_int("ppp_delay_sec"); 92 int count; 93 if(max_count > 0){ 94 for(count = 1; count <= max_count; ++count){ 95 _dprintf("%s: unit=%d ifname=%s sleep %d seconds...\n", __FUNCTION__, unit, wan_ifname, count); 96 sleep(1); 97 } 98 } 99#endif 100 101 /* Stop triggering demand connection */ 102 if (nvram_get_int(strcat_r(prefix, "pppoe_demand", tmp))) 103 nvram_set_int(strcat_r(prefix, "pppoe_demand", tmp), 1); 104 105#ifdef RTCONFIG_USB_MODEM 106 // wanX_ifname is used for device for USB Modem 107 if ((value = getenv("DEVICE")) && 108 (isSerialNode(value) || isACMNode(value))){ 109 nvram_set(strcat_r(prefix, "ifname", tmp), value); 110 nvram_set(strcat_r(prefix, "proto", tmp), "pppoe"); 111 } 112#endif 113 114 /* Touch connection file */ 115 if (!(fp = fopen(strcat_r("/tmp/ppp/link.", wan_ifname, tmp), "a"))) { 116 perror(tmp); 117 return errno; 118 } 119 fclose(fp); 120 121 if ((value = getenv("IPLOCAL"))) { 122 if (nvram_invmatch(strcat_r(prefix, "ipaddr", tmp), value)) 123 ifconfig(wan_ifname, IFUP, "0.0.0.0", NULL); 124 _ifconfig(wan_ifname, IFUP, value, "255.255.255.255", getenv("IPREMOTE"), 0); 125 nvram_set(strcat_r(prefix, "ipaddr", tmp), value); 126 nvram_set(strcat_r(prefix, "netmask", tmp), "255.255.255.255"); 127 } 128 129 if ((value = getenv("IPREMOTE"))) 130 nvram_set(strcat_r(prefix, "gateway", tmp), value); 131 132 strcpy(buf, ""); 133 if ((value = getenv("DNS1"))) 134 sprintf(buf, "%s", value); 135 if ((value = getenv("DNS2"))) 136 sprintf(buf + strlen(buf), "%s%s", strlen(buf) ? " " : "", value); 137 138 /* empty DNS means they either were not requested or peer refused to send them. 139 * for this case static DNS can be used, if they are configured */ 140 if (strlen(buf) == 0 && !nvram_get_int(strcat_r(prefix, "dnsenable_x", tmp))) { 141 value = nvram_safe_get(strcat_r(prefix, "dns1_x", tmp)); 142 if (*value && inet_addr_(value) != INADDR_ANY) 143 sprintf(buf, "%s", value); 144 value = nvram_safe_get(strcat_r(prefix, "dns2_x", tmp)); 145 if (*value && inet_addr_(value) != INADDR_ANY) 146 sprintf(buf + strlen(buf), "%s%s", *buf ? " " : "", value); 147 } 148 149 nvram_set(strcat_r(prefix, "dns", tmp), buf); 150 151 wan_up(wan_ifname); 152 153 _dprintf("%s:: done\n", __FUNCTION__); 154 return 0; 155} 156 157/* 158 * Called when link goes down 159 */ 160int 161ipdown_main(int argc, char **argv) 162{ 163 char *wan_ifname = safe_getenv("IFNAME"); 164 char *wan_linkname = safe_getenv("LINKNAME"); 165 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 166 int unit; 167 168 _dprintf("%s():: %s\n", __FUNCTION__, argv[0]); 169 170 /* Get unit from LINKNAME: ppp[UNIT] */ 171 if ((unit = ppp_linkunit(wan_linkname)) < 0) 172 return 0; 173 174 _dprintf("%s: unit=%d ifname=%s\n", __FUNCTION__, unit, wan_ifname); 175 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 176 177 wan_down(wan_ifname); 178 179 // override wan_state to get real reason 180 update_wan_state(prefix, WAN_STATE_STOPPED, pppstatus()); 181 182 unlink(strcat_r("/tmp/ppp/link.", wan_ifname, tmp)); 183 184 preset_wan_routes(wan_ifname); 185 186 _dprintf("%s:: done\n", __FUNCTION__); 187 return 0; 188} 189 190/* 191 * Called when interface comes up 192 */ 193int 194ippreup_main(int argc, char **argv) 195{ 196 char *wan_ifname = safe_getenv("IFNAME"); 197 char *wan_linkname = safe_getenv("LINKNAME"); 198 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 199 int unit; 200 201 _dprintf("%s():: %s\n", __FUNCTION__, argv[0]); 202 203 /* Get unit from LINKNAME: ppp[UNIT] */ 204 if ((unit = ppp_linkunit(wan_linkname)) < 0) 205 return 0; 206 207 _dprintf("%s: unit=%d ifname=%s\n", __FUNCTION__, unit, wan_ifname); 208 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 209 210 /* Set wanX_pppoe_ifname to real interface name */ 211 nvram_set(strcat_r(prefix, "pppoe_ifname", tmp), wan_ifname); 212 213 /* Start triggering demand connection */ 214 if (nvram_get_int(strcat_r(prefix, "pppoe_demand", tmp))) 215 nvram_set_int(strcat_r(prefix, "pppoe_demand", tmp), 2); 216 217 _dprintf("%s:: done\n", __FUNCTION__); 218 return 0; 219} 220 221#ifdef RTCONFIG_IPV6 222int ip6up_main(int argc, char **argv) 223{ 224 char *wan_ifname = safe_getenv("IFNAME"); 225 char *wan_linkname = safe_getenv("LINKNAME"); 226 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 227 int unit; 228 229 if (!wan_ifname || strlen(wan_ifname) <= 0) 230 return 0; 231 232 /* Get unit from LINKNAME: ppp[UNIT] */ 233 if ((unit = ppp_linkunit(wan_linkname)) < 0) 234 return 0; 235 236 _dprintf("%s: unit=%d ifname=%s\n", __FUNCTION__, unit, wan_ifname); 237 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 238 239 /* share the same interface with pppoe ipv4 connection */ 240 nvram_set(strcat_r(prefix, "pppoe_ifname", tmp), wan_ifname); 241 242 wan6_up(wan_ifname); 243 244 return 0; 245} 246 247int ip6down_main(int argc, char **argv) 248{ 249 char *wan_ifname = safe_getenv("IFNAME"); 250 251 wan6_down(wan_ifname); 252 253 return 0; 254} 255#endif // IPV6 256 257/* 258 * Called when link closing with auth fail 259 */ 260int 261authfail_main(int argc, char **argv) 262{ 263 char *wan_ifname = safe_getenv("IFNAME"); 264 char *wan_linkname = safe_getenv("LINKNAME"); 265 char tmp[100], prefix[] = "wanXXXXXXXXXX_"; 266 int unit; 267 268 _dprintf("%s():: %s\n", __FUNCTION__, argv[0]); 269 270 /* Get unit from LINKNAME: ppp[UNIT] */ 271 if ((unit = ppp_linkunit(wan_linkname)) < 0) 272 return 0; 273 274 _dprintf("%s: unit=%d ifname=%s\n", __FUNCTION__, unit, wan_ifname); 275 snprintf(prefix, sizeof(prefix), "wan%d_", unit); 276 277 /* Stop triggering demand connection */ 278 if (nvram_get_int(strcat_r(prefix, "pppoe_demand", tmp))) 279 nvram_set_int(strcat_r(prefix, "pppoe_demand", tmp), 1); 280 281 // override wan_state 282 update_wan_state(prefix, WAN_STATE_STOPPED, WAN_STOPPED_REASON_PPP_AUTH_FAIL); 283 284 _dprintf("%s:: done\n", __FUNCTION__); 285 return 0; 286} 287