Logo Search packages:      
Sourcecode: dctc version File versions  Download package

network.c

/* DCTC - a Direct Connect text clone for Linux
 * Copyright (C) 2001 Eric Prevoteau
 *
 * network.c: Copyright (C) Eric Prevoteau <www@a2pb.gotdns.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
/*
$Id: network.c,v 1.11 2003/12/28 08:12:38 uid68112 Exp $
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <net/if.h>
#include <net/route.h>
#include <netdb.h>
#include <ctype.h>
#include <errno.h>
#include <glib.h>

#include "network.h"
static struct sockaddr_in INET_ZERO = { AF_INET };

/****************************************************************/
/* the following parameters are used to handle SOCKS proxy (v4) */
/****************************************************************/
char *socks_ip=NULL;                                  /* hostname or IP of the socks proxy */
unsigned short socks_port=1080;           /* port number of the socks proxy */
char *socks_name=NULL;                          /* userID to use on the socks proxy (or NULL if none required) */
char *socks_pass=NULL;                          /* password to use on the socks proxy (or NULL if none required) */
                                                                        /* only valid when socks_name!=NULL AND SOCKSv5 enabled */
int use_socks_v5=FALSE;                         /* prefer SOCKSv5 instead of v4 */

char *web_proxy_address=NULL;             /* address (IP or name) and port of a web proxy to use which supports the command CONNECT */

/* --------------------------------------------------------------------------------------------- */
static char six2pr[64] = {
    'A','B','C','D','E','F','G','H','I','J','K','L','M',
    'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
    'a','b','c','d','e','f','g','h','i','j','k','l','m',
    'n','o','p','q','r','s','t','u','v','w','x','y','z',
    '0','1','2','3','4','5','6','7','8','9','+','/'
};

/*********************************************************************************************/
/* simple function to encode the login:passwd string for proxy requiring an authentification */
/*********************************************************************************************/
int uu_auth(unsigned char *bufin, unsigned int nbytes, char *bufcoded)
{
#define ENC(c) six2pr[c]

   register char *outptr = bufcoded;
   unsigned int i;
   for (i=0; i<nbytes; i += 3) {
      *(outptr++) = ENC(*bufin >> 2);           /* c1 */
      *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2*/
      *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03));/*c3*/
      *(outptr++) = ENC(bufin[2] & 077);        /* c4 */

      bufin += 3;
   }

   if(i == nbytes+1) {
      /* There were only 2 bytes in that last group */
      outptr[-1] = '=';
   } else if(i == nbytes+2) {
      /* There was only 1 byte in that last group */
      outptr[-1] = '=';
      outptr[-2] = '=';
   }
   *outptr = '\0';
   return(outptr - bufcoded);
}

/* --------------------------------------------------------------------------------------------- */


/****************************************************************************************/
/* perform the socket connection. If socks_ip is NULL, a direct connection is performed */
/* if socks_ip!=NULL, the function tries to establish a connection thru a SOCKS proxy   */
/* using the given information.                                                         */
/****************************************************************************************/
/* WARNING: if the given socks is in non-blocking mode, the connection will fail */
/*********************************************************************************/
static int do_connect_opt_socks(int desc,struct sockaddr_in nom)
{
      int ret=-1;
      GByteArray *cmd=NULL;

      if(socks_ip==NULL)
      {     /* SOCKS proxy disabled, web proxy or normal mode can be enabled */
            if(web_proxy_address==NULL)
            {     /* normal straight connection mode */
                  ret=connect(desc,(void*)&nom,sizeof(nom));
            }
            else
            {     /* web proxy mode */
                  char buf[512];
                  char *t;
                  struct sockaddr_in web_cnx;
                  unsigned int port;
                  struct hostent *web_host;

                  strcpy(buf,web_proxy_address);
                  t=strchr(buf,':');
                  if(t==NULL)
                        port=8080;
                  else
                  {
                        *t++='\0';
                        port=strtoul(t,NULL,10);
                  }

                  printf("connecting thru web proxy.\n");

                  if((web_host=gethostbyname(buf))==NULL)
                        goto eofunc;

                  memcpy(&web_cnx.sin_addr,web_host->h_addr,web_host->h_length);
                  web_cnx.sin_family=AF_INET;
                  web_cnx.sin_port=htons(port);

                  ret=connect(desc,(void*)&web_cnx,sizeof(web_cnx));
                  if(ret==-1)
                  {
                        perror("web connect");
                        goto eofunc;
                  }

                  {
                        GString *str;

                        str=g_string_new("");

                        g_string_sprintf(str,"CONNECT %s HTTP/1.1\nHost: %s\n",web_proxy_address,web_proxy_address);
                        /* proxy needs authentification ? */
                        if((socks_name!=NULL)&&(socks_pass!=NULL))
                        {
                              /* Yes */
                              int l1, l2;
                              char plain_pass[256];

                              l1=strlen(socks_name);
                              l2=strlen(socks_pass);
                              if((l1+l2+2)>sizeof(plain_pass))
                                    fprintf(stderr,"ERROR: proxy login + password size exceeded buffer size, both are ignored\n");
                              else
                              {
                                    char encoded_lp[512];

                                    /* build the string "login:passwd" */
                                    memcpy(plain_pass,socks_name,l1);
                                    plain_pass[l1]=':';
                                    memcpy(plain_pass+l1+1,socks_pass,l2);
                                    plain_pass[l1+1+l2]='\0';

                                    uu_auth(plain_pass,strlen(plain_pass),encoded_lp);

                                    g_string_sprintfa(str,"Authorization: Basic %s\n",encoded_lp);
                              }
                        }
                        g_string_append_c(str,'\n');        /* end HTTP query */


                        if(send(desc,str->str,str->len,MSG_NOSIGNAL|MSG_DONTWAIT)!=str->len)
                        {
                              perror("web send CONNECT");
                              g_string_free(str,TRUE);
                              ret=-1;
                              goto eofunc;
                        }
                        g_string_free(str,TRUE);
                  }
      
                  /* check if we receive a 200 code */
                  if(recv(desc,buf,4,MSG_WAITALL|MSG_NOSIGNAL)!=4)
                  {
                        ret=-1;
                        goto eofunc;
                  }

                  if(buf[0]!='2')
                  {
                        printf("connect thru web proxy returns %c%c%c.\n",buf[0],buf[1],buf[2]);
                        ret=-1;
                        goto eofunc;
                  }

                  /* now, we will discard any bytes until a '\n\n' was received */
                  {
                        gboolean connected=FALSE;
                        gboolean has_nl=FALSE;

                        while(!connected)
                        {
                              char c;
                              if(recv(desc,&c,1,MSG_WAITALL|MSG_NOSIGNAL)!=1)
                              {
                                    perror("web receive fails");
                                    ret=-1;
                                    goto eofunc;
                              }

                              if(c=='\r')             /* ignore \r in the header */
                                    continue;
                              if(c!='\n')
                              {
                                    has_nl=FALSE;
                              }
                              else
                              {
                                    if(!has_nl)
                                          has_nl=TRUE;
                                    else
                                          connected=TRUE;
                              }
                        }
                  }
                  ret=0;
                  printf("web proxy connected\n");
            }
      }
      else
      {     /* SOCKS proxy enabled */
            if(use_socks_v5==FALSE)
            {     /* SOCKS proxy v4 */
                  struct sockaddr_in socks_cnx;
                  struct hostent *socks_host;
                  unsigned char val[9];
            
                  printf("connecting thru SOCKSv4.\n");

                  if((socks_host=gethostbyname(socks_ip))==NULL)
                        goto eofunc;
                  memcpy(&socks_cnx.sin_addr,socks_host->h_addr,socks_host->h_length);
                  socks_cnx.sin_family=AF_INET;
                  socks_cnx.sin_port=htons(socks_port);
      
                  ret=connect(desc,(void*)&socks_cnx,sizeof(socks_cnx));
                  if(ret==-1)
                  {
                        perror("socks connect");
                        goto eofunc;
                  }

                  cmd=g_byte_array_new();
                  val[0]=4;         /* socks version 4 */
                  val[1]=1;         /* CONNECT */
                  val[2]=ntohs(nom.sin_port)>>8;
                  val[3]=ntohs(nom.sin_port)&255;
                  val[4]=ntohl(nom.sin_addr.s_addr)>>24;
                  val[5]=ntohl(nom.sin_addr.s_addr)>>16;
                  val[6]=ntohl(nom.sin_addr.s_addr)>>8;
                  val[7]=ntohl(nom.sin_addr.s_addr);
                  cmd=g_byte_array_append(cmd,val,8);
                  if(socks_name!=NULL)
                  {
                        cmd=g_byte_array_append(cmd,socks_name,strlen(socks_name));
                  }
                  val[0]='\0';
                  cmd=g_byte_array_append(cmd,val,1);
      
                  if(send(desc,cmd->data,cmd->len,MSG_NOSIGNAL|MSG_DONTWAIT)!=cmd->len)
                  {
                        perror("socks send CONNECT");
                        ret=-1;
                        goto eofunc;
                  }
      
                  if(recv(desc,val,8,MSG_WAITALL|MSG_NOSIGNAL)!=8)
                  {
                        perror("socks receive CONNECT result");
                        ret=-1;
                        goto eofunc;
                  }
      
                  if(val[0]!=0)           /*  reply code version 0 ? */
                  {
                        fprintf(stderr,"socks CONNECT result: unknown reply code version (%d)",(int)(val[0]));
                        ret=-1;
                        goto eofunc;
                  }
      
                  if(val[1]!=90)
                  {
                        fprintf(stderr,"socks CONNECT result: access denied or failed (%d)",(int)(val[1]));
                        ret=-1;
                        goto eofunc;
                  }
                  ret=0;
#if 0
                  printf("SOCKSv4 connected\n");
#endif
            }
            else
            {     /* SOCKS proxy v5 */
                  struct sockaddr_in socks_cnx;
                  struct hostent *socks_host;
                  unsigned char val[512];
            
                  printf("connecting thru SOCKSv4.\n");

                  if((socks_host=gethostbyname(socks_ip))==NULL)
                        goto eofunc;
                  memcpy(&socks_cnx.sin_addr,socks_host->h_addr,socks_host->h_length);
                  socks_cnx.sin_family=AF_INET;
                  socks_cnx.sin_port=htons(socks_port);
      
                  ret=connect(desc,(void*)&socks_cnx,sizeof(socks_cnx));
                  if(ret==-1)
                  {
                        perror("socks connect");
                        goto eofunc;
                  }

                  /* perform initial negociation */
                  cmd=g_byte_array_new();
                  val[0]=5;         /* socks version 5 */
                  val[1]=2;         /* we support 2 methods */
                  val[2]=0;         /* method 0: no login required */
                  val[3]=2;         /* method 2: connection with login/password */
                  cmd=g_byte_array_append(cmd,val,4);
                  if(send(desc,cmd->data,cmd->len,MSG_NOSIGNAL|MSG_DONTWAIT)!=cmd->len)
                  {
                        perror("socks initial negociation");
                        ret=-1;
                        goto eofunc;
                  }
      
                  if(recv(desc,val,2,MSG_WAITALL|MSG_NOSIGNAL)!=2)
                  {
                        perror("socks receive initial negociation result");
                        ret=-1;
                        goto eofunc;
                  }

                  if(val[0]!=5)
                  {
                        fprintf(stderr,"socks initial negociation result: unknown reply code version (%d)",(int)(val[0]));
                        ret=-1;
                        goto eofunc;
                  }
      
                  switch(val[1])
                  {
                        case 0:                 /* no login required */
                                          break;

                        case 2:                 /* connection with login/password */
                                          /* create a string: 0x05, login len, login, password len, password */
                                          cmd=g_byte_array_set_size(cmd,0);         /* clear the temp buffer */
                                          val[0]=5;
                                          cmd=g_byte_array_append(cmd,val,1);
                                          if(socks_name!=NULL)
                                          {
                                                val[1]=strlen(socks_name);
                                                cmd=g_byte_array_append(cmd,val+1,1);     /* no login */
                                                cmd=g_byte_array_append(cmd,socks_name,strlen(socks_name));

                                                if(socks_pass!=NULL)
                                                {
                                                      val[2]=strlen(socks_pass);
                                                      cmd=g_byte_array_append(cmd,val+2,1);     /* no login */
                                                      cmd=g_byte_array_append(cmd,socks_pass,strlen(socks_pass));
                                                }
                                                else
                                                {
                                                      val[2]=0;
                                                      cmd=g_byte_array_append(cmd,val+2,1);     /* no password */
                                                }
                                          }
                                          else
                                          {
                                                val[1]=0;
                                                cmd=g_byte_array_append(cmd,val+1,1);     /* no login */
                                                val[2]=0;
                                                cmd=g_byte_array_append(cmd,val+2,1);     /* no password */
                                          }

                                          if(send(desc,cmd->data,cmd->len,MSG_NOSIGNAL|MSG_DONTWAIT)!=cmd->len)
                                          {
                                                perror("socks send login/password");
                                                ret=-1;
                                                goto eofunc;
                                          }

                                          if(recv(desc,val,2,MSG_WAITALL|MSG_NOSIGNAL)!=2)
                                          {
                                                perror("socks login/password stage");
                                                ret=-1;
                                                goto eofunc;
                                          }

                                          if(val[0]!=5)
                                          {
                                                fprintf(stderr,"socks login/password stage: unknown reply code version (%d)",(int)(val[0]));
                                                ret=-1;
                                                goto eofunc;
                                          }

                                          if(val[1]!=0)
                                          {
                                                fprintf(stderr,"socks login/password stage result: unknown return code (%d)",(int)(val[1]));
                                                ret=-1;
                                                goto eofunc;
                                          }
                                          break;

                        default:
                                          fprintf(stderr,"socks initial negociation result: unknown authentification method (%d)",(int)(val[1]));
                                          ret=-1;
                                          goto eofunc;
                  }

                  /* authentification done, time to establish connection */
                  cmd=g_byte_array_set_size(cmd,0);         /* clear the temp buffer */
                  val[0]=5;         /* socks version 5 */
                  val[1]=1;         /* CONNECT */
                  val[2]=0;         /* reserved */
                  val[3]=1;         /* IPv4 address */
                  val[4]=ntohl(nom.sin_addr.s_addr)>>24;
                  val[5]=ntohl(nom.sin_addr.s_addr)>>16;
                  val[6]=ntohl(nom.sin_addr.s_addr)>>8;
                  val[7]=ntohl(nom.sin_addr.s_addr);
                  val[8]=ntohs(nom.sin_port)>>8;
                  val[9]=ntohs(nom.sin_port)&255;
                  cmd=g_byte_array_append(cmd,val,10);
      
                  if(send(desc,cmd->data,cmd->len,MSG_NOSIGNAL|MSG_DONTWAIT)!=cmd->len)
                  {
                        perror("socks send CONNECT");
                        ret=-1;
                        goto eofunc;
                  }
      
                  if(recv(desc,val,10,MSG_WAITALL|MSG_NOSIGNAL)!=10)
                  {
                        perror("socks receive CONNECT result");
                        ret=-1;
                        goto eofunc;
                  }

                  if(val[0]!=5)
                  {
                        fprintf(stderr,"socks CONNECT: unknown reply code version (%d)",(int)(val[0]));
                        ret=-1;
                        goto eofunc;
                  }

                  if(val[1]!=0)
                  {
                        fprintf(stderr,"socks CONNECT result: unknown return code (%d)",(int)(val[1]));
                        ret=-1;
                        goto eofunc;
                  }
            
                  ret=0;
#if 1
                  printf("SOCKSv5 connected\n");
#endif
            }
      }
      eofunc:
      if(cmd!=NULL)
            g_byte_array_free(cmd,TRUE);
            
      return ret;
}

/*************************************************/
/* open a TCP connection with the requested port */
/*************************************************/
/* en entree: port= port demande     */
/* en sortie: numero de socket ou -1 */
/*************************************/
int _x_tcp (int port)
{
      int f, len;
      struct sockaddr_in me ;
      struct sockaddr_in s_in;
      int zz=1;
  
      me = s_in = INET_ZERO;
  
      me.sin_port = htons((unsigned short) port);
      me.sin_family = AF_INET;
  
      if((f=socket(AF_INET,SOCK_STREAM,0)) == -1) return(-1);
  
      if(setsockopt(f,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz)) < 0 ||
            bind(f,(struct sockaddr *) &me,(len = sizeof(me))) < 0)
      {
            perror("setsock or bind");
            close(f);
            return(-1);
      }

      return(f);
}

/*************************************************/
/* open a UDP connection with the requested port */
/************************************************************/
/* input: port= wanted port number (0=find an unused one)   */
/*        if port!=0 and port_upper_range > port and <65536 */
/*        the function tries to bind on a free port in the  */
/*        range [port:port_upper_range].                    */
/*        if port_upper_range==0, only "port" is used       */
/* output: socket descriptor or -1                          */
/*        if port!=0 and port_upper_range=0, a returned     */
/*        value of -1 probably means the port is busy.      */
/*        if port_upper_range!=0, a returned value of -1    */
/*        probably means all ports on the given range are   */
/*        busy.                                             */
/************************************************************/
int _x_udp (int port, int port_upper_range)
{
      int f, len, zz;
      struct sockaddr_in me ;
      struct sockaddr_in s_in;

      if((f=socket(AF_INET,SOCK_DGRAM,0)) == -1) return(-1);

      zz=1;

      if(setsockopt(f,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz)) < 0)
      {
            perror("_x_udp");
            close(f);
            return(-1);
      }

      /* try to bind on the wanted port number */
      retry_bind:
      me = s_in = INET_ZERO;
      me.sin_port = htons((unsigned short) port);
      me.sin_family = AF_INET;
      if(bind(f,(struct sockaddr *) &me,(len = sizeof(me))) < 0 )
      {
            if(port_upper_range!=0)
            {
                  port++;
                  if(port<=port_upper_range)
                        goto retry_bind;
            }
            perror("_x_udp");
            close(f);
            return(-1);
      }

      if(getsockname(f,(struct sockaddr *)&s_in,&len) < 0)
      {
            perror("_x_udp");
            close(f);
            return(-1);
      }
      return(f);
}      

/***************************************/
/* conversion nom d'hote -> adresse ip */
/***************************************/
/* en sortie: -1= fail, 0=ok */
/*****************************/
int str_to_inaddr (const char *str, struct in_addr *iap)
{
#ifdef DONT_HAVE_INET_ATON
      *(int *)iap = inet_addr(str);
      if (*(int *)iap == -1)
#else
      if (!inet_aton(str, iap))
#endif
      {
            struct hostent *he;

            if ((he = gethostbyname(str)))
            {
                  if ((unsigned)he->h_length > sizeof *iap)
                        he->h_length = sizeof *iap;

                  memcpy(iap, he->h_addr, he->h_length);
            }
            else
            {
                  return -1;
            }
      }

      return 0;
}

/*****************************************************/
/* routine fixant le flag non bloquant sur un socket */
/*****************************************************/
void set_non_bloquant_sock(int socket_fd)
{
      long retval;

      retval=fcntl(socket_fd,F_GETFL);
      retval|= O_NONBLOCK;

      fcntl(socket_fd,F_SETFL,retval);
}


/*************************************************/
/* routine fixant le flag bloquant sur un socket */
/*************************************************/
void set_bloquant_sock(int socket_fd)
{
      long retval;

      retval=fcntl(socket_fd,F_GETFL);
      retval&= ~O_NONBLOCK;

      fcntl(socket_fd,F_SETFL,retval);
}

/*************************************************/
/* routine to set TOS on socket                  */
/*************************************************/
void set_tos_sock(int socket_fd, int tos)
{
      if(tos)
            if(setsockopt(socket_fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))
                  perror("Unable to set TOS:");
}

/****************************************************/
/* create a socket and connect it to the given host */
/***************************************************************/
/* input: non_block=1 (socket is created with O_NONBLOCK flag) */
/*********************************************************************************************/
/* output: sock_fd or -1,-2 or -3                                                            */
/*         if non_block==1, returned sock_fd must be tested (ready_to_write) before using it */
/*********************************************************************************************/
/* -1=unknown host           */
/* -2=socket creation failed */
/* -3=unable to contact host */
/***********************************************************************************/
/* WARNING: if non_block==1 and a SOCKS proxy is used, the connection will fail... */
/***********************************************************************************/
int create_and_open_sock_on(char *hostname,unsigned short port, int non_block)
{
      struct sockaddr_in addr;
      int s;
      int code;

      addr.sin_family=AF_INET;
      addr.sin_port=htons(port);
      if(str_to_inaddr(hostname,&(addr.sin_addr)))
            return -1;

      if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
      {
            perror("socket:");
            return -2;
      }

      if(non_block)
            set_non_bloquant_sock(s);

      /* perform the connect call which may use a proxy (web or SOCKS) */
      code=do_connect_opt_socks(s,addr);

      if(non_block==0)
      {
            if(code==-1)
            {
                  perror("connect");
                  close(s);
                  return -3;
            }
      }
      else
      {
            /* socket doesn't block, -1 is allowed if errno==EINPROGRESS */
            if((code==-1)&&(errno!=EINPROGRESS))
            {
                  perror("connect");
                  close(s);
                  return -3;
            }
      }

      return s;
}

/********************************************/
/* check if the given value is an IP or not */
/********************************************/
/* output: TRUE=it is an IP, FALSE= no */
/***************************************/
static gboolean is_an_ip(const char *value_to_check)
{
      int a,b,c,d;

      if(value_to_check==NULL)
            return FALSE;

      if(sscanf(value_to_check,"%d.%d.%d.%d",&a,&b,&c,&d)!=4)
            return FALSE;           /* not enough value assigned */

      if(
            (a>=0)&&(a<=255)&&
            (b>=0)&&(b<=255)&&
            (c>=0)&&(c<=255)&&
            (d>=0)&&(d<=255))
      {
            return TRUE;
      }

      return FALSE;
}

/******************************/
/* return the default host IP */
/************************************************************************/
/* the default host IP is the IP of the interface used as default route */
/************************************************************************/
/* The parameter can be NULL and in this case, the default host IP is */
/* used, it can also be an IP (IPv4) or an interface to have an IP    */
/**********************************************************************/
GString *get_default_host_ip(const char *ip_or_if, gboolean dynamic_flag)
{
      FILE *f;
      char buf[512];
      gboolean it_is_an_ip;

      /* the following script does this: */
      /* 1) extract the interface used by the default route: netstat -rn | grep ^0.0.0.0 | awk '{print $8;} */
      /* 2) obtain the IP of this interface: netstat xxx | fgrep inet | cut -d : -f 2 | awk '{print $1;}' */
      const char *cmd=
#ifndef ROUTE_HAS_GET_DEFAULT
            "/sbin/ifconfig `netstat -rn | awk '/^0.0.0.0/{print$NF}'` | fgrep inet | cut -d : -f 2 | awk '{print $1;}'";
#else
            "/sbin/route -n get default | awk '/local/{print$NF}'";
#endif

      it_is_an_ip=is_an_ip(ip_or_if);

      /* if the parameter is an IP, we just return it but only in static mode */
      if((it_is_an_ip==TRUE)&&(dynamic_flag==0))
      {
            return g_string_new(ip_or_if);
      }

      if((ip_or_if==NULL)||(strlen(ip_or_if)==0)||(it_is_an_ip==TRUE))
      {
            /* 3 possibles cases: no interface provided, empty string provided or IP provided */
            strcpy(buf,cmd);
      }
      else
      {
            sprintf(buf,"/sbin/ifconfig '%s' | fgrep inet | cut -d : -f 2 | awk '{print $1;}'",ip_or_if);
      }

      f=popen(buf,"r");
      if(f==NULL)
      {
            fprintf(stderr,"Unable to create a shell to obtain default IP.\n");
            return NULL;
      }

      if(fgets(buf,sizeof(buf),f)==NULL)
      {
            pclose(f);
            fprintf(stderr,"No default interface found.\n");
            return NULL;
      }

      pclose(f);

      if(strlen(buf)!=0)
      {
            char *t;

            t=buf;
            while( (*t) && ((*t=='.') || (isdigit(*t))) )
                  t++;

            *t='\0';
            return g_string_new(buf);
      }
      else
            return NULL;
}


Generated by  Doxygen 1.6.0   Back to index