#include #include #include #include #include #include #include #include #include /* Skip the white space in a string. Stop at the end or at the first non white space. */ static char *str_skip(const char *str) { while (isspace(*str)) str++; return (char*)str; } /* Get the list of all network device (except aliases). Return -1 if any errors. Return the number of entry in list. */ static bool pppparms_devexist (const char *device) { bool ret = false; FILE *fin = fopen ("/proc/net/dev","r"); if (fin != NULL){ char buf[600]; if (fgets(buf,sizeof(buf)-1,fin)!=NULL && fgets(buf,sizeof(buf)-1,fin)!=NULL){ while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ char *pt = strchr(buf,':'); if (pt != NULL){ if (strchr(pt+1,':')==NULL){ /* #Specification: netconf / proc/net/dev netconf assume that /proc/net/dev has the following format. 2 lines of heading followed by device info. Each line begin by the device name. A device name is ended by :, while an alias has a : in the middle and at the end. */ *pt = '\0'; char *start = str_skip (buf); if (strcmp(start,device)==0){ ret = true; break; } } } } } fclose (fin); } return ret; } static int ifconfig_ioctl( int fd, const char *ifname, int cmd, struct ifreq &ifr) { strcpy(ifr.ifr_name, ifname); return ioctl(fd, cmd,&ifr); } /* Format in text an IP number */ static void ipnum_ip2a(unsigned long ip, char *buf) { sprintf (buf,"%u.%u.%u.%u" ,(unsigned)(ip >> 24) ,(unsigned)((ip >> 16 ) & 0xff) ,(unsigned)((ip >> 8 ) & 0xff) ,(unsigned)(ip & 0xff)); } static void ifconfig_format (struct sockaddr &adr, char *buf) { struct sockaddr_in *sin = (struct sockaddr_in*)&adr; ipnum_ip2a (htonl(sin->sin_addr.s_addr),buf); } /* Fetch the inteface configuration from the kernel. Return -1 if any error. */ int ifconfig_getinfo ( const char *ifname, char ipaddr[20]) { int ret = -1; if (pppparms_devexist(ifname)){ int skfd = socket(AF_INET, SOCK_DGRAM, 0); if (skfd != -1){ struct ifreq ifr; if (ifconfig_ioctl(skfd, ifname, SIOCGIFFLAGS, ifr) >= 0){ if (ifconfig_ioctl(skfd,ifname,SIOCGIFADDR, ifr) >= 0){ ifconfig_format (ifr.ifr_addr,ipaddr); ret = 0; } } } } return ret; } static void usage() { fprintf (stderr, "pppparms pppdopt account default-account\n" "pppparms routing account\n"); } class PPPINFO{ public: int proxyarp; int firewall; int ppp233; char dns1[20]; char dns2[20]; char ourip[20]; char remoteip[20]; char copyaccount[20]; char postconcmd[200]; char postdisconcmd[200]; char delivermail[200]; int allocfromtty; int idletime; char options[200]; int maxtime; struct { int enable; int netnum; int localnum; int remotenum; int routingrip; int routingnlsp; char options[200]; }ipx; /*~PROTOBEG~ PPPINFO */ public: PPPINFO (void); void load (FILE *fin, const char *name); /*~PROTOEND~ PPPINFO */ }; PUBLIC PPPINFO::PPPINFO() { ppp233 = 0; proxyarp = 0; firewall = 0; dns1[0] = '\0'; dns2[0] = '\0'; ourip[0] = '\0'; remoteip[0] = '\0'; copyaccount[0] = '\0'; postconcmd[0] = '\0'; postdisconcmd[0] = '\0'; delivermail[0] = '\0'; allocfromtty = 0; idletime = 0; maxtime = 0; options[0] = '\0'; ipx.enable = 0; ipx.netnum = 0; ipx.localnum = 0; ipx.remotenum = 0; ipx.routingrip = 0; ipx.routingnlsp = 0; ipx.options[0] = '\0'; } #include "key.h" static void loadif ( const char *ptbuf, const char *key, int &val) { if (val == 0){ int len = strlen(key); if (strncmp(ptbuf,key,len)==0 && isspace (ptbuf[len])){ ptbuf += len; while (isspace (*ptbuf)) ptbuf++; val = atoi(ptbuf); } } } static void loadif ( const char *ptbuf, const char *key, char *val) { if (val[0] == '\0'){ int len = strlen(key); if (strncmp(ptbuf,key,len)==0 && isspace (ptbuf[len])){ ptbuf += len; while (isspace (*ptbuf)) ptbuf++; while (*ptbuf >= ' ') *val++ = *ptbuf++; *val = '\0'; } } } PUBLIC void PPPINFO::load ( FILE *fin, const char *name) { rewind (fin); char buf[1000]; int len = strlen (name); while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ if (strncmp(buf,name,len)==0 && buf[len] == '.'){ char *ptbuf = buf + len + 1; loadif (ptbuf,K_PPP233,ppp233); loadif (ptbuf,K_PROXYARP,proxyarp); loadif (ptbuf,K_FIREWALL,firewall); loadif (ptbuf,K_ALLOCFROMTTY,allocfromtty); loadif (ptbuf,K_IDLETIME,idletime); loadif (ptbuf,K_MAXTIME,maxtime); loadif (ptbuf,K_COPYACCOUNT,copyaccount); loadif (ptbuf,K_DNS1,dns1); loadif (ptbuf,K_DNS2,dns2); loadif (ptbuf,K_OURIP,ourip); loadif (ptbuf,K_REMOTEIP,remoteip); loadif (ptbuf,K_OPTIONS,options); loadif (ptbuf,K_POSTCONCMD,postconcmd); loadif (ptbuf,K_POSTDISCONCMD,postdisconcmd); loadif (ptbuf,K_DELIVERMAIL,delivermail); loadif (ptbuf,K_IPXENABLE,ipx.enable); loadif (ptbuf,K_IPXNETNUM,ipx.netnum); loadif (ptbuf,K_IPXLOCALNUM,ipx.localnum); loadif (ptbuf,K_IPXREMOTENUM,ipx.remotenum); loadif (ptbuf,K_IPXROUTINGRIP,ipx.routingrip); loadif (ptbuf,K_IPXROUTINGNLSP,ipx.routingnlsp); loadif (ptbuf,K_IPXOPTIONS,ipx.options); } } } /* Transforme to HEX, except if the value is 0 */ static const char*pppparms_tohex (int val, char buf[20]) { buf[0] = '\0'; if (val != 0){ sprintf (buf,"%x",val); } return buf; } static void pppparms_show (FILE *fin, const char *keyword, const char *user) { if (fin != NULL){ char key[100]; int len = snprintf (key,sizeof(key)-1,"%s.%s",user,keyword); char buf[1000]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ if (strncmp(buf,key,len)==0 && isspace(buf[len])){ char *pt = str_skip (buf+len); printf ("%s",pt); } } fclose (fin); } } int main (int argc, char *argv[]) { FILE * fin = fopen ("/etc/pppdialin.conf","r"); if (argc <= 1){ usage(); }else if (argc == 4 && strcmp(argv[1],"pppdopt")==0){ PPPINFO info; if (fin != NULL){ info.load (fin,argv[2]); if (info.copyaccount[0] != '\0'){ info.load (fin,info.copyaccount); }else{ info.load(fin,argv[3]); } info.load(fin,K_DEFPPP); fclose (fin); } if (info.ourip[0] == '\0'){ /* #Specification: our IP / default The pppparms utility is called at the start of the PPP session to grab the various parameters of the session, including the two IP numbers (local and remote). A default value may be defined for the local IP number. This is common practice to assign the same local number for all PPP session, even if there are multiple modems involved. If a default value is not specified, the IP number of the eth0 network device is used, if defined */ ifconfig_getinfo ("eth0",info.ourip); } printf ("PPP_233=%s\n",info.ppp233 ? "yes" : "no"); printf ("PPP_PROXYARP=%s\n",info.proxyarp ? "yes" : "no"); printf ("PPP_FIREWALL=%s\n",info.firewall ? "yes" : "no"); printf ("PPP_DNS1=%s\n",info.dns1); printf ("PPP_DNS2=%s\n",info.dns2); printf ("PPP_OURIP=%s\n",info.ourip); printf ("PPP_REMOTEIP=%s\n",info.remoteip); printf ("PPP_POSTCONCMD=\"%s\"\n",info.postconcmd); printf ("PPP_POSTDISCONCMD=\"%s\"\n",info.postdisconcmd); printf ("PPP_DELIVERMAIL=\"%s\"\n",info.delivermail); printf ("PPP_ALLOCFROMTTY=%s\n",info.allocfromtty ? "yes" : "no"); printf ("PPP_OPTIONS=\"%s\"\n",info.options); printf ("PPP_IDLETIME=%d\n",info.idletime); printf ("PPP_MAXTIME=%d\n",info.maxtime); printf ("PPP_IPXENABLE=%s\n",info.ipx.enable ? "yes" : "no"); printf ("PPP_IPXROUTINGRIP=%s\n",info.ipx.routingrip ? "yes" : "no"); printf ("PPP_IPXROUTINGNLSP=%s\n",info.ipx.routingnlsp ? "yes" : "no"); printf ("PPP_IPXOPTIONS=\"%s\"\n",info.ipx.options); char tmp[20]; printf ("PPP_IPXNETNUM=%s\n",pppparms_tohex (info.ipx.netnum,tmp)); printf ("PPP_IPXLOCALNUM=%s\n",pppparms_tohex (info.ipx.localnum,tmp)); printf ("PPP_IPXREMOTENUM=%s\n",pppparms_tohex (info.ipx.remotenum,tmp)); }else if (argc == 3 && strcmp(argv[1],"routing")==0){ pppparms_show (fin,K_ROUTE,argv[2]); }else{ fprintf (stderr,"error: Invalid usage\n"); usage(); } }