1/* 2** BPALogin - lightweight portable BIDS2 login client 3** Copyright (c) 2001-3 Shane Hyde, and others. 4** 5** This program is free software; you can redistribute it and/or modify 6** it under the terms of the GNU General Public License as published by 7** the Free Software Foundation; either version 2 of the License, or 8** (at your option) any later version. 9** 10** This program is distributed in the hope that it will be useful, 11** but WITHOUT ANY WARRANTY; without even the implied warranty of 12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13** GNU General Public License for more details. 14** 15** You should have received a copy of the GNU General Public License 16** along with this program; if not, write to the Free Software 17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18** 19*/ 20 21#include "bpalogin.h" 22#include "bcmnvram.h" 23 24/* 25** Main processing loop. Logs in, handles heartbeats, and logs out on request 26** 27** Returns - 0 - We are no longer connected, and should not retry. 28** 1 - We are no longer connnected and should retry. 29*/ 30int mainloop(struct session * s) 31{ 32 int err; 33 struct sockaddr_in listenaddr; 34 struct hostent * he; 35 int addrsize; 36 37 int rawSock = 0; 38 struct ifreq ifr; 39 40 if(!parse_parms(s,NULL)) 41 { 42 s->debug(1,"[ bpaclient ] : parameter read error" ); 43 //usage(); 44 exit(1); 45 } 46 47 s->debug(1,"parameter parsing:\n"); 48 s->debug(1,"username = %s\n",s->username); 49 s->debug(1,"password = %s\n",s->password); 50 s->debug(1,"server = %s\n",s->authserver); 51 s->debug(1,"minHB = %d\n",s->minheartbeat); 52 s->debug(1,"maxHB = %d\n",s->maxheartbeat); 53 s->debug(1,"localport= %d\n",s->localport); 54 55 if(!strcmp(s->username,"")) 56 { 57 critical("Username has not been set"); 58 exit(1); 59 } 60 61 if(!strcmp(s->password,"")) 62 { 63 critical("Password has not been set"); 64 exit(1); 65 } 66 67 /* 68 ** sleep until wanside get IP 69 */ 70 if((rawSock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))<0) 71 s->debug(1,"[ bpaclient ]: rawSock open error\n"); 72 73 memset(&ifr,0,sizeof(struct ifreq)); 74 75 /* Foxconn modified start, zacker, 10/22/2008, @qos_v8 */ 76#if defined(U12H083) 77 strcpy(ifr.ifr_name,"eth0.2"); 78#elif ( defined(U12H092) || defined(U12H155) ) 79 strcpy(ifr.ifr_name,"eth0"); 80#elif defined(U12H072) || defined(U12H114) || (defined U12H139) || defined(U12H127) 81 strcpy(ifr.ifr_name, nvram_safe_get("wan_ifname")); 82#else 83 strcpy(ifr.ifr_name,"eth1"); 84#endif 85 /* Foxconn modified end, zacker, 10/22/2008, @qos_v8 */ 86 87 do 88 { 89 sleep(POLL_CYCLE); 90 91 if (ioctl(rawSock, SIOCGIFADDR, &ifr)<0) 92 { 93 s->debug(2,"ioctl error!!\n"); 94 s->debug(2,"errno = %d\n",errno); 95 } 96 97 s->debug(2,"ipaddress of %s : %s\n",ifr.ifr_name,inet_ntoa(((struct sockaddr_in*)(&ifr.ifr_addr))->sin_addr)); 98 } 99 while(!strcmp(inet_ntoa(((struct sockaddr_in*)(&ifr.ifr_addr))->sin_addr),"0.0.0.0")); 100 101 close(rawSock); 102 103 s->lastheartbeat = 0; 104 s->sequence = 0; 105 s->listensock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 106 s->debug(2,"listen socket = %d \n",s->listensock);//steve add for dbg 107 s->localaddr.sin_family = AF_INET; 108 s->localaddr.sin_port = htons(s->localport); 109 110 if(strcmp(s->localaddress,"")) 111 { 112 s->debug(2,"Using local address %s\n",s->localaddress); 113 he = gethostbyname(s->localaddress); 114 115 if(he) 116 { 117 s->localaddr.sin_addr.s_addr = *((int*)(he->h_addr_list[0])); 118 } 119 else 120 { 121 s->localaddr.sin_addr.s_addr = inet_addr(s->localaddress); 122 } 123 } 124 else 125 { 126 s->localaddr.sin_addr.s_addr = INADDR_ANY; 127 } 128 129 addrsize = sizeof(struct sockaddr_in); 130 err = bind(s->listensock,(struct sockaddr *)&s->localaddr,sizeof(s->localaddr)); 131 err = getsockname(s->listensock,(struct sockaddr *)&listenaddr,&addrsize); 132 133 s->sessionid = time(NULL); 134 135 s->listenport = ntohs(listenaddr.sin_port); 136 strcpy(s->osname,"whocares"); 137 strcpy(s->osrelease,"notme"); 138 139 he = gethostbyname(s->authserver); 140 141 if(he) 142 { 143 s->authhost.sin_addr.s_addr = *((int*)(he->h_addr_list[0])); 144 } 145 else 146 { 147 s->authhost.sin_addr.s_addr = inet_addr(s->authserver); 148 } 149 150 s->authhost.sin_port = htons(s->authport); 151 s->authhost.sin_family = AF_INET; 152 153 s->debug(1,"Auth host = %s:%d\n",s->authserver,s->authport); 154 s->debug(1,"Listening on port %d\n",s->listenport); 155 156 if(login(s)) 157 { 158 s->onconnected(s->listenport); 159 if(!handle_heartbeats(s)) 160 { 161 /* 162 ** heartbeat return 0: 163 ** case 1 : login fail-->to sleep for LGIN_CYCLE sec 164 ** case 2 : restart pkt is recv --> no implement: should reset state and do login 165 */ 166 167 int i; 168 s->ondisconnected(1); 169 s->noncritical("Sleeping for %d second\n",LGIN_CYCLE); 170 171 for(i=0; i<LGIN_CYCLE; i++) 172 { 173 if(s->shutdown) 174 return 0; 175 else 176 sleep(1); 177 } 178 } 179 else 180 { 181 closesocket(s->listensock); 182 return 0; 183 } 184 closesocket(s->listensock); 185 } 186 else 187 { 188 int i; 189 /* Foxconn added start, zacker, 07/18/2008 */ 190 if (s->state == STATE_AWAIT_NEG_RESP) 191 logout(0, s); 192 /* Foxconn added end, zacker, 07/18/2008 */ 193 194 s->noncritical("Sleeping for %d second\n",LGIN_CYCLE); 195 196 for(i=0; i<LGIN_CYCLE; i++) 197 { 198 if(s->shutdown) 199 return 0; 200 else 201 sleep(1); 202 } 203 closesocket(s->listensock); 204 } 205 return 1; 206} 207 208