#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "redhatppp.h" #include "redhatppp.m" #include "../../paths.h" #include const char scripts_path[]="/etc/sysconfig/network-scripts/ifcfg-"; HELP_FILE help_ptp ("redhatppp","ptp"); const char subsys_dialout[]="dialout"; static LINUXCONF_SUBSYS subb (subsys_dialout,P_MSG_U(M_DIALOUT,"PPP/SLIP/PLIP")); static CONFIG_FILE f_pap_secrets (ETC_PPP_PAPSECRETS ,help_ptp ,CONFIGF_MANAGED ,"root","root",0600,subsys_dialout); static const char ppp_chat_path[]="/etc/sysconfig/network-scripts/chat-"; static const char dip_chat_path[]="/etc/sysconfig/network-scripts/dip-"; /* Parse a ifcfg-dev path and return the file name and eliminate all the non point to point stuff */ static const char *ppp_filtername (const char *path) { const char *ret = NULL; const char *fname = strrchr (path,'/'); if (fname != NULL){ fname += 7; if (strncmp(fname,"ppp",3) == 0 || strncmp(fname,"sl",2) == 0 || strncmp(fname,"plip",4) == 0){ ret = fname; } } return ret; } /* Extract the list of ifcfg files related to Point To Point devices */ int ppp_list(SSTRINGS &tb) { SSTRINGS tmptb; dir_getlist_p (scripts_path,tmptb); // Remove the ifcfg file which are not Point To Point devices for (int i=0; iget()); if (name != NULL){ tb.add (new SSTRING (name)); } } tb.sort(); return tb.getnb(); } static const char NAME[]="NAME"; static const char USEWVDIAL[]="USEWVDIAL"; static const char WVDIALSECT[]="WVDIALSECT"; static const char DEFROUTE[]="DEFROUTE"; static const char HARDFLOWCTL[]="HARDFLOWCTL"; static const char ONBOOT[]="ONBOOT"; static const char PERSIST[]="PERSIST"; static const char MRU[]="MRU"; static const char MTU[]="MTU"; static const char LINESPEED[]="LINESPEED"; static const char DISCONNECTTIMEOUT[]="DISCONNECTTIMEOUT"; static const char PPPOPTIONS[]="PPPOPTIONS"; static const char IPADDR[]="IPADDR"; static const char REMIP[]="REMIP"; static const char NETMASK[]="NETMASK"; static const char PAPNAME[]="PAPNAME"; static const char MODEMPORT[]="MODEMPORT"; static const char DEFABORT[]="DEFABORT"; static const char ESCAPECHARS[]="ESCAPECHARS"; static const char RETRYTIMEOUT[]="RETRYTIMEOUT"; static const char USERCTL[]="USERCTL"; static const char BOOTPROTO[]="BOOTPROTO"; static const char INITSTRING[]="INITSTRING"; static const char DEBUG[]="DEBUG"; static const char FIREWALL[]="PPP_FIREWALL"; static const char MODE[]="MODE"; static const char PEERDNS[]="PEERDNS"; static void ppp_getpath (const char *dev, char *path) { sprintf (path,"%s%s",scripts_path,dev); } #define PROTO_NONE 0 #define PROTO_BOOTP 1 #define PROTO_DHCP 2 #define TYPE_PPP 1 #define TYPE_SLIP 2 #define TYPE_PLIP 3 class RHPPP{ public: SSTRING name; char usewvdial; SSTRING wvdialsect; SSTRING device; char userctl; char peerdns; char onboot; char bootproto; SSTRING modemport; SSTRING linespeed; char persist; char defabort; char original_defabort; // We keep a copy of the flag // and ajust the special abort strings // only if the flag has changed during edit // This way, changed made manually are // preserved as long as possible char defroute; char hardflowctl; char escapechars; SSTRING pppoptions; SSTRING papname; SSTRING secret; SSTRING remip; SSTRING ipaddr; SSTRING netmask; SSTRING mru; SSTRING mtu; SSTRING disconnecttimeout; int retrytimeout; SSTRING modeminit; SSTRING modemdial; SSTRING phone; SSTRINGS chat; SSTRINGS chataborts; char debug; char firewall; int type; char mode; // slip or cslip char stupidmode; // for wvdial /*~PROTOBEG~ RHPPP */ public: RHPPP (const char *dev); RHPPP (void); private: void addspcaborts (void); void delspcaborts (void); public: int edit (void); int editnew (void); private: void init (void); public: int load (void); void setdevice (const char *dev); private: void setmodemfield (DIALOG&dia); void settitle (char title[100]); public: int write (void); /*~PROTOEND~ RHPPP */ }; PUBLIC RHPPP::RHPPP (const char *dev) { init(); setdevice (dev); load (); } PUBLIC void RHPPP::setdevice (const char *dev) { device.setfrom (dev); if (strncmp(dev,"ppp",3)==0){ type = TYPE_PPP; }else if (strncmp(dev,"sl",2)==0){ type = TYPE_SLIP; }else if (strncmp(dev,"plip",4)==0){ type = TYPE_PLIP; } } /* Check if a device file exist and does not conflict with /dev/mouse. We assume /dev/mouse is a symlink. */ static bool ppp_devok(const char *dev) { bool ret = false; if (file_exist (dev)){ char path[PATH_MAX]; int len = readlink ("/dev/mouse",path,sizeof(path)-1); if (len != -1){ path[len] = '\0'; if (path[0] != '/'){ if(strcmp(dev+5,path)!=0){ ret = true; } }else if (strcmp(path,dev)!=0){ ret = true; } }else{ ret = true; } } return ret; } static const char *tbpppdev[]={ "/dev/modem", "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", NULL }; PRIVATE void RHPPP::init() { type = 0; userctl = 0; peerdns = 1; onboot = 0; bootproto = 0; modemport.setfrom ("/dev/modem"); for (int i=0; tbpppdev[i] != NULL; i++){ const char *dev = tbpppdev[i]; if (ppp_devok(dev)){ modemport.setfrom (dev); break; } } linespeed.setfrom ("115200"); persist = 1; defabort = 1; original_defabort = 0; defroute = 1; hardflowctl = 1; escapechars = 0; retrytimeout = 5; modeminit.setfrom ("ATZ"); modemdial.setfrom ("ATDT"); mode = 0; stupidmode = 1; } PUBLIC RHPPP::RHPPP () { init(); } static const char *tbaborts[]={ "BUSY", "ERROR", "NO CARRIER", "NO DIALTONE", "Invalid Login", "Login incorrect", NULL }; /* Add the well known ABORT sequence in chataborts */ PRIVATE void RHPPP::addspcaborts() { for (int i=0; tbaborts[i] != NULL; i++){ chataborts.add (new SSTRING ("ABORT")); chataborts.add (new SSTRING (tbaborts[i])); } } /* Remove the well known ABORT sequence in chataborts */ PRIVATE void RHPPP::delspcaborts() { for (int i=0; tbaborts[i] != NULL; i++){ int lk = chataborts.lookup (tbaborts[i]); while (lk != -1 && (lk & 1) != 0 && chataborts.getitem(lk-1)->cmp("ABORT")==0){ lk--; chataborts.remove_del (lk); chataborts.remove_del (lk); lk = chataborts.lookup (tbaborts[i]); } } } static void ppp_unquote (char *s) { char tmp[1000]; strncpy (tmp,s,sizeof tmp); tmp[sizeof tmp - 1] = 0; char *src = tmp; if (src[0] == '\'') src++; int last = strlen(src)-1; if (last >= 0 && src[last] == '\'') src[last] = '\0'; strcpy (s,src); } static int ppp_delsecrets ( const char *remote) { int ret = 0; VIEWITEMS items; items.read (f_pap_secrets); int n = items.getnb(); bool found = false; for (int i=0; iline.get(); pt = str_copyword (word1,pt,100); pt = str_copyword (word2,pt,100); str_copyword (word3,pt,100); if (strcmp(word2,remote)==0){ found = true; items.remove_del(it); break; } } if (found) ret = items.write (f_pap_secrets,NULL); return ret; } static int ppp_updsecrets ( const char *name, const char *remote, const char *secret) { int ret = 0; VIEWITEMS items; items.read (f_pap_secrets); int n = items.getnb(); bool found = false; bool modified = false; for (int i=0; iline.get(); pt = str_copyword (word1,pt,100); pt = str_copyword (word2,pt,100); str_copyword (word3,pt,100); if (strcmp(word2,remote)==0){ found = true; if (strcmp(word1,name)!=0 || strcmp (word3,secret)!=0){ modified = true; char line[100]; snprintf (line,sizeof(line)-1,"%s %s %s" ,name,remote,secret); it->line.setfrom (line); } break; } } if (!found){ char line[100]; SSTRING comment; comment.setfrom ("# "); comment.append (MSG_U(I_ADDBYLNX,"Added by linuxconf")); snprintf (line,sizeof(line)-1,"%s %s %s",name,remote,secret); items.add (new VIEWITEM(comment.get(),VIEWITEM_COMMENT)); items.add (new VIEWITEM(line)); modified = true; } if (modified) ret = items.write (f_pap_secrets,NULL); return ret; } static void ppp_loadsecret ( const char *name, const char *remote, SSTRING &secret) { VIEWITEMS items; items.read (f_pap_secrets); int n = items.getnb(); for (int i=0; iline.get(); pt = str_copyword (word1,pt,100); pt = str_copyword (word2,pt,100); str_copyword (word3,pt,100); if (strcmp(word1,name)==0 && strcmp(word2,remote)==0){ secret.setfrom (word3); break; } } } PUBLIC int RHPPP::load () { const char *dev = device.get(); int ret = -1; char path[PATH_MAX]; ppp_getpath (dev,path); CONFIG_FILE f_ppp(path,help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0755); VIEWITEMS items; if (items.read (f_ppp)!=-1){ ret = 0; char tmp[1000]; name.setfrom (items.locateval (NAME,tmp)); usewvdial = items.locatebval (USEWVDIAL,1); wvdialsect.setfrom (items.locateval (WVDIALSECT,tmp)); if (!wvdialsect.is_empty()){ stupidmode = wvdial_getstupidmode(wvdialsect.get()) ? 1 : 0; } onboot = items.locatebval (ONBOOT); userctl = items.locatebval (USERCTL); peerdns = items.locatebval (PEERDNS); modemport.setfrom (items.locateval(MODEMPORT,tmp)); linespeed.setfrom (items.locateval(LINESPEED,tmp)); persist = items.locatebval (PERSIST); defabort = items.locatebval (DEFABORT); original_defabort = defabort; debug = items.locatebval (DEBUG); firewall = items.locatebval (FIREWALL); defroute = items.locatebval (DEFROUTE); hardflowctl = items.locatebval (HARDFLOWCTL); escapechars = items.locatebval (ESCAPECHARS); pppoptions.setfrom (items.locateval (PPPOPTIONS,tmp)); papname.setfrom (items.locateval (PAPNAME,tmp)); remip.setfrom (items.locateval (REMIP,tmp)); netmask.setfrom (items.locateval (NETMASK,tmp)); ipaddr.setfrom (items.locateval (IPADDR,tmp)); mru.setfrom (items.locateval (MRU,tmp)); mtu.setfrom (items.locateval (MTU,tmp)); disconnecttimeout.setfrom (items.locateval (DISCONNECTTIMEOUT,tmp)); retrytimeout = items.locatenval (RETRYTIMEOUT); const char *proto = items.locateval(BOOTPROTO,tmp); if (proto == NULL || strcmp(proto,"none")==0){ bootproto = PROTO_NONE; }else if (strcmp(proto,"bootp")==0){ bootproto = PROTO_BOOTP; }else if (strcmp(proto,"dhcp")==0){ bootproto = PROTO_DHCP; } const char *modestr = items.locateval(MODE,tmp); if (modestr == NULL || strcmp(modestr,"SLIP")==0){ mode = 0; }else if (strcmp(modestr,"CSLIP")==0){ mode = 1; } modeminit.setfrom (items.locateval (INITSTRING,tmp)); modemdial.setfrom(""); if (!papname.is_empty()) ppp_loadsecret (papname.get(),dev,secret); if (type == TYPE_PPP || type == TYPE_SLIP){ // Read the chat char pathchat[PATH_MAX]; sprintf (pathchat,"%s%s",ppp_chat_path,dev); FILE *fin = fopen (pathchat,"r"); if (fin != NULL){ char buf[1000]; int state = 0; while (fgets_strip (buf,sizeof(buf)-1,fin,'\0','\0',NULL)!=NULL){ if (buf[0] == '#') continue; char *pt = str_skip (buf); if (pt[0] == '\''){ char word1[1000],word2[1000]; pt = str_copyquote (word1,pt); pt = str_skip(pt); str_copyquote (word2,pt); ppp_unquote (word1); ppp_unquote (word2); if (state == 0){ if (modeminit.cmp(word2)==0){ state = 1; }else{ chataborts.add (new SSTRING(word1)); chataborts.add (new SSTRING(word2)); } }else if (state == 1){ // Now the dial command and the phone number pt = word2; while (*pt) pt++; if (pt > word2){ //look backwards for number pt--; while (isdigit(*pt) && pt > word2) pt--; if (!isdigit(*pt)) pt++; } phone.setfrom (pt); *pt = '\0'; modemdial.setfrom (word2); state = 2; }else if (state == 2){ state = 3; }else{ chat.add (new SSTRING (word1)); chat.add (new SSTRING (word2)); } } } fclose (fin); } } } return ret; } /* Check an IP address if not empty Return true if ok. */ static bool ppp_checkip (const SSTRING &ip, bool ishost) { bool ret = true; if (!ip.is_empty() && !ipnum_validip (ip.get(),ishost)){ ret = false; xconf_error (MSG_U(E_IVLDIP,"Invalid IP address or netmask")); } return ret; } static void ppp_connect (const char *dev) { if (perm_rootaccess(MSG_U(P_CONTROLPTP ,"Control point to point link"))){ netconf_system_if ("ifup",dev); } } static void ppp_disconnect (const char *dev) { if (perm_rootaccess(MSG_R(P_CONTROLPTP))){ netconf_system_if ("ifdown",dev); } } /* Check if the device is connected return 0 if not 1 if yes 2 if it is connecting right now */ static int ppp_isconnect(const char *dev) { int ret = 0; char path[PATH_MAX]; sprintf (path,"/var/run/ppp-%s.dev",dev); FILE *fin = fopen (path,"r"); if (fin != NULL){ char buf[100]; ret = 1; if (fgets_strip(buf,sizeof(buf)-1,fin,NULL)!=NULL && strcmp(buf,"DIALING")==0){ ret = 2; } fclose (fin); } return ret; } PRIVATE void RHPPP::settitle (char title[100]) { const char *prefix=""; if (type == TYPE_PPP){ prefix = MSG_U(T_PPPINTER,"PPP interface"); }else if (type == TYPE_SLIP){ prefix = MSG_U(T_SLIPINTER,"SLIP interface"); }else if (type == TYPE_PLIP){ prefix = MSG_U(T_PLIPINTER,"PLIP interface"); } snprintf (title,99,"%s %s",prefix,device.get()); } static void ppp_addifexist (FIELD_COMBO *comb, const char *dev) { if (ppp_devok(dev)){ comb->addopt (dev); } } PRIVATE void RHPPP::setmodemfield (DIALOG &dia) { FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_MODEMPORT,"Modem port") ,modemport); for (int i=0; tbpppdev[i] != NULL; i++){ ppp_addifexist (comb,tbpppdev[i]); } } /* Check if an optional number is within a range, return true of ok. */ static bool ppp_checkoptnum ( const SSTRING &num, int mini, int maxi, const char *errmsg) { bool ret = true; const char *pt = num.get(); if (pt[0] != '\0'){ int val = atoi(pt); while (isdigit(*pt)) pt++; if ((pt[0] != '\0' && !isdigit(*pt)) || val < mini || val > maxi){ xconf_error(errmsg); ret = false; } } return ret; } PUBLIC int RHPPP::edit () { DIALOG dia; dia.newf_str (MSG_U(F_CONFIGNAME,"Configuration name"),name); char title[100]=""; settitle(title); dia.newf_title (MSG_U(T_HARDWARE,"Hardware"),1,"",MSG_R(T_HARDWARE)); if (type == TYPE_PPP){ dia.newf_chk ("",hardflowctl,MSG_U(I_HARDFLOWCTL ,"Use hardware flow control and modem lines")); dia.newf_chk ("",escapechars,MSG_U(I_ESCAPECHARS ,"Escape control characters")); dia.newf_chk ("",defabort,MSG_U(I_DEFABORT ,"Abort connection on well-known errors")); } dia.newf_chk ("",userctl,MSG_U(I_USERCTL ,"Allow any user (de)activate the interface")); if (type == TYPE_PPP || type == TYPE_SLIP){ FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_LINESPEED,"Line speed"),linespeed); { static short int tb[]={ 3,6,12,24,48,96, 192,384,576,1152 }; for (unsigned i=0; iaddopt (msg); } } setmodemfield (dia); } if (type == TYPE_PPP){ dia.newf_str (MSG_U(F_PPPOPTIONS,"PPP options"),pppoptions); } if (type != TYPE_PLIP){ dia.newf_title (MSG_U(T_COMMS,"Communication"),1,"",MSG_R(T_COMMS)); dia.newf_str (MSG_U(F_MODEMINIT,"Modem init string"),modeminit); dia.newf_str (MSG_U(F_MODEMDIAL,"Modem dial command"),modemdial); dia.newf_str (MSG_U(F_PHONE,"Phone number"),phone); dia.newf_chk ("",usewvdial,MSG_U(I_USEWVDIAL,"Use wvdial")); if (type == TYPE_PPP){ if (wvdial_is_installed()){ dia.newf_chk (MSG_U(F_LINKSETUP,"Link setup"),stupidmode ,MSG_U(I_LINKSETUP,"PPP does all authentication")); } dia.newf_chk ("",debug,MSG_U(I_DEBUGCON,"Debug connection")); } dia.newf_title ("",MSG_U(T_CHAT,"Chat")); { int nbempty = 0; for (int i=0; iis_empty()) nbempty++; } for ( ; nbempty<6; nbempty+=2){ chat.add (new SSTRING); chat.add (new SSTRING); } for (int j=0; jget(); const char *send = chat.getitem(i+1)->get(); if (expect[0] != '\0' || send[0] != '\0'){ fprintf (fout,"'%s' '%s'\n",expect,send); } } } PUBLIC int RHPPP::write() { char path[PATH_MAX]; ppp_getpath (device.get(),path); CONFIG_FILE f_ppp(path,help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0755); VIEWITEMS items; items.read (f_ppp); if (wvdialsect.is_empty() && !name.is_empty()){ // Copy the name to wvdialsect, transform spaces into _ char buf[name.getlen()+1]; const char *src = name.get(); char *dst = buf; while (*src != '\0'){ char car = *src++; if (isspace(car)){ *dst = '_'; }else{ *dst = car; } dst++; } *dst = '\0'; wvdialsect.setfrom (buf); } items.update ("DEVICE",device); if (type == TYPE_SLIP){ items.update ("MODE",mode ? "CSLIP" : "SLIP"); } items.update (NAME,name); items.update (USEWVDIAL, usewvdial ? "yes" : "no"); items.update (WVDIALSECT, !usewvdial || modemport.is_empty() ? "" : wvdialsect.get()); items.updatebval (ONBOOT,onboot); items.updatebval (USERCTL,userctl); items.updatebval (PEERDNS,peerdns); items.update (MODEMPORT,modemport); items.update (LINESPEED,linespeed); items.updatebval (PERSIST,persist); items.updatebval (DEFABORT,defabort); items.updatebval (DEBUG,debug); items.updatebval (FIREWALL,firewall); items.update (INITSTRING,modeminit); items.updatebval (DEFROUTE,defroute); items.updatebval (HARDFLOWCTL,hardflowctl); items.updatebval (ESCAPECHARS,escapechars); items.update (PPPOPTIONS,pppoptions); items.update (PAPNAME,papname); items.update (REMIP,remip); items.update (NETMASK,netmask); items.update (IPADDR,ipaddr); items.update (MRU,mru); items.update (MTU,mtu); items.update (DISCONNECTTIMEOUT,disconnecttimeout); items.update (RETRYTIMEOUT,retrytimeout); static const char *tbproto[]={ "none","bootp","dhcp" }; items.update (BOOTPROTO,tbproto[bootproto]); int ret = items.write (f_ppp,NULL); if (ret != -1){ if (!(papname.is_empty() || secret.is_empty())){ ret = ppp_updsecrets (papname.get(),device.get(),secret.get()); } if (ret != -1 && (type == TYPE_PPP || type == TYPE_SLIP)){ char pathchat[PATH_MAX]; sprintf (pathchat,"%s%s",ppp_chat_path,device.get()); if (modemport.is_empty()) { wvdial_delete(wvdialsect.get()); ret = unlink (pathchat); } else { wvdial_update(wvdialsect.get(),papname.get(), secret.get(),modeminit.get(), phone.get(),modemport.get(), linespeed.get(), modemdial.get(), stupidmode); // Read the chat CONFIG_FILE f_chat(pathchat,help_nil ,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,"root","root",0700); FILE_CFG *fout = f_chat.fopen ("w"); if (fout != NULL){ //if (defabort != original_defabort){ // We cleanup first and add them later if needed. delspcaborts(); if (defabort) addspcaborts(); //} ppp_writechat (fout,chataborts); fprintf (fout,"'' '%s'\n",modeminit.get()); if (modemdial.getlen() || phone.getlen()) { fprintf (fout,"'OK' '%s%s'\n",modemdial.get(),phone.get()); fputs ("'CONNECT' ''\n",fout); } ppp_writechat (fout,chat); ret = fclose (fout); }else{ ret = -1; } } } } return ret; } int ppp_del (const char *dev, const char* wvdialsect) { char path[PATH_MAX]; ppp_getpath (dev,path); int ret = unlink (path); if (ret != -1){ char pathchat[PATH_MAX]; sprintf (pathchat,"%s%s",ppp_chat_path,dev); unlink (pathchat); sprintf (pathchat,"%s%s",dip_chat_path,dev); unlink (pathchat); ppp_delsecrets(dev); if (wvdialsect){ wvdial_delete(wvdialsect); } } return ret; } int ppp_add (SSTRINGS &tb) { int ret = -1; DIALOG dia; char type = 0; dia.newf_radio ("",type,0,MSG_U(R_PPP,"PPP")); dia.newf_radio ("",type,1,MSG_U(R_SLIP,"SLIP")); dia.newf_radio ("",type,2,MSG_U(R_PLIP,"PLIP")); int nof = 0; if (dia.edit (MSG_U(T_DEVTYPE,"Type of interface") ,"" ,help_ptp ,nof)==MENU_ACCEPT){ static char *tbprefix[] = {"ppp","sl","plip"}; for (int i=0; i<1000; i++){ char device[10]; sprintf (device,"%s%d",tbprefix[type],i); if (tb.lookup(device)==-1){ RHPPP conf; conf.setdevice (device); ret = conf.editnew(); break; } } } return ret; } void ppprh_edit () { if (perm_rootaccess(MSG_U(P_EDITDIALOUT,"edit dialout configurations"))){ SSTRINGS tb; DIALOG_LISTE *dia = NULL; int nof = 0; while (1){ if (dia == NULL){ dia = new DIALOG_LISTE; tb.remove_all(); int n = ppp_list(tb); dia->newf_head ("",MSG_U(T_CONFIGS,"Logical device\tConfiguration name")); for (int i=0; iget(); RHPPP ppp (device); dia->new_menuitem (device,ppp.name.get()); } } MENU_STATUS code = dia->editmenu (MSG_U(T_PPPSLIPCONF ,"PPP/Slip/Plip configurations") ,"" ,help_ptp ,nof ,MENUBUT_ADD); bool must_delete = false; if (code == MENU_QUIT || code == MENU_ESCAPE){ break; }else if (code == MENU_ADD){ if (ppp_add (tb)==0) must_delete = true; }else if (nof >=0 && nof < tb.getnb()){ if (perm_rootaccess(MSG_R(P_EDITDIALOUT))){ const char *dev = tb.getitem(nof)->get(); RHPPP ppp (dev); if (ppp.edit () == 1){ must_delete = true; } } } if (must_delete){ delete dia; dia = NULL; } } delete dia; } } static bool ppp_userctl(const char *dev) { RHPPP ppp(dev); return ppp.userctl; } /* Control panel allowing connection and disconnection of PPP dialout */ void ppprh_control () { int choice = 0; while (1){ DIALOG_LISTE dia; SSTRINGS tb; int nb = ppp_list(tb); dia.newf_head ("",MSG_U(T_CONFIGSTATUS,"Logical device\tConfiguration name\tStatus")); for (int i=0; iget(); RHPPP ppp (dev); char buf[100]; snprintf (buf,sizeof(buf)-1,"%s\t%s",ppp.name.get() ,tbmsg[ppp_isconnect (dev)]); dia.new_menuitem (dev,buf); } MENU_STATUS code = dia.editmenu( MSG_U(T_PPPCONCTRL,"PPP/SLIP/PLIP connection control") ,MSG_U(I_PPPCONCTRL,"You are allowed to activate/deactivate\n" "PPP, SLIP and PLIP link\n") ,help_ptp ,choice ,0); if (code == MENU_ESCAPE || code == MENU_QUIT){ break; }else if (choice >= 0 && choice < nb){ const char *dev = tb.getitem(choice)->get(); //PRIVILEGE *privi = ppp_lookuppriv (dev); if (ppp_userctl(dev) || perm_rootaccess(MSG_U(P_CTLDIALOUT,"control dialout"))){ int status = ppp_isconnect(dev); if (status == 0){ if (dialog_yesno(MSG_U(Q_DOCONN,"Activate link") ,MSG_U(I_DOCONN ,"Do you want to activate the network link ?") ,help_nil)==MENU_YES){ ppp_connect(dev); } }else if (status == 1){ if (dialog_yesno(MSG_U(Q_DODISCONN,"Terminate link") ,MSG_U(I_DODISCONN ,"Do you want to terminate the network link ?") ,help_nil)==MENU_YES){ ppp_disconnect(dev); for (int i=0; i<4; i++){ sleep(1); if (!ppp_isconnect(dev)){ break; } } } } } } } } class CONFIG_FILE_PTPLIST: public CONFIG_FILE{ /*~PROTOBEG~ CONFIG_FILE_PTPLIST */ public: CONFIG_FILE_PTPLIST (void); int archive (SSTREAM&ss)const; int extract (SSTREAM&ss); /*~PROTOEND~ CONFIG_FILE_PTPLIST */ }; PUBLIC CONFIG_FILE_PTPLIST::CONFIG_FILE_PTPLIST() : CONFIG_FILE ("/etc/sysconfig/ptpdev.list",help_nil,CONFIGF_VIRTUAL ,subsys_dialout) { } PUBLIC int CONFIG_FILE_PTPLIST::archive(SSTREAM &ss) const { configf_sendexist (ss,true); SSTRINGS tb; int n = ppp_list (tb); for (int i=0; iget(); ss.printf ("%s\n",dev); } return 0; } PUBLIC int CONFIG_FILE_PTPLIST::extract(SSTREAM &ss) { SSTRINGS tbold; ppp_list (tbold); SSTRINGS tb; char path[PATH_MAX]; while (ss.gets(path,sizeof(path)-1) != NULL){ strip_end (path); tb.add (new SSTRING (path)); } for (int i=0; iget(); char path[PATH_MAX]; ppp_getpath (dev,path); CONFIG_FILE conf (path,help_nil,CONFIGF_MANAGED|CONFIGF_OPTIONAL ,subsys_dialout); conf.extract(); } // Erase the config files which were not part of the archive for (int j=0; jget(); if (tb.lookup(dev)==-1){ net_prtlog (NETLOG_CMD,MSG_U(I_REMOVINGPTP,"Removing point to point configuration: %s\n") ,dev); // Leaves entries in wvdial.conf untouched ppp_del (dev,0); } } return 0; } static CONFIG_FILE_PTPLIST ptplist; static bool ppp_devexist (const char *devname) { bool ret = false; if (strncmp(devname,"redhatppp/",10)==0){ devname += 10; SSTRINGS lst; int n = ppp_list (lst); for (int i=0; icmp(devname)==0){ ret = true; break; } } } return ret; } static int ppp_getdevlist (SSTRINGS &devs, SSTRINGS &descs) { SSTRINGS lst; int n = ppp_list (lst); for (int i=0; iget(); s->setfromf ("redhatppp/%s",c); d->setfromf (MSG_U(I_PPPDEVDESC,"Dialout configuration %s"),c); devs.add (s); descs.add (d); } return n; } // taken from usernet static int ppp_logical_to_physical (const char *devname, SSTRING &kerneldev) { int ret = -1; /* way too much space for "/var/run/ppp-ppp??.pid" */ char map_file_name[100]; sprintf(map_file_name, "/var/run/ppp-%s.pid", devname); int f = 0; if ((f = open(map_file_name, O_RDONLY)) > 0) { /* enough space for lock-file contents */ char buffer[32]; int n = 0; if ((n = read(f, buffer, sizeof buffer)) > 0) { buffer[n] = 0; char* p = buffer; while (p < buffer + n) { if (*p == '\n') *p = 0; ++p; } p = buffer; while (p < buffer + n && (*p == 0 || isdigit(*p))) { /* skip line */ while (p < buffer + n && *p++) { } } if (*p) { kerneldev.setfrom (p); ret = 0; } } close(f); } return ret; } // taken from usernet's get_interface_status_by_name static int ppp_getdevinfo (const char *devname, SSTRINGS &kerneldevs) { int ret = -1; SSTRING kerneldev; if (strncmp(devname,"redhatppp/",10)==0 && ppp_logical_to_physical(devname+10, kerneldev)==0){ int sock = 0; int pfs[] = {AF_INET, AF_IPX, AF_AX25, AF_APPLETALK, 0}; int p = 0; struct ifreq ifr; while (!sock && pfs[p]) { sock = socket(pfs[p++], SOCK_DGRAM, 0); } if (sock) { memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, kerneldev.get()); if (ioctl(sock, SIOCGIFFLAGS, &ifr) >= 0 && ifr.ifr_flags & IFF_UP) { kerneldevs.add (new SSTRING(kerneldev)); ret = 0; } close(sock); } } return ret; } static bool ppp_hostexist (const char *hostname) { return ppp_devexist (hostname); } static int ppp_gethostlist (SSTRINGS &hosts, SSTRINGS &descs) { return ppp_getdevlist (hosts,descs); } static int ppp_gethostinfo (const char *host, SSTRINGS &ips) { int ret = -1; SSTRINGS devs; if (ppp_getdevinfo(host,devs)!=-1){ for (int i=0; iget(); // We need the IP number associated with the device IFCONFIG_INFO info; if (ifconfig_getinfo_nocheck(dev,info)!=-1){ ips.add (new SSTRING(info.ip_addr)); ret = 0; } } } return ret; } void *redhatppp_fwinfo_api_get() { FWINFO_API *api = new FWINFO_API; api->devexist = ppp_devexist; api->getdevlist = ppp_getdevlist; api->getdevinfo = ppp_getdevinfo; api->hostexist = ppp_hostexist; api->gethostlist = ppp_gethostlist; api->gethostinfo = ppp_gethostinfo; return api; } void redhatppp_fwinfo_api_release(void *api) { delete (FWINFO_API*)api; }