Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-10

TUN/TAP

7 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jorge Aldo G. de F. Junior

Can anyone help me decypher the following code :

int tun_alloc(char *dev)
  {
      struct ifreq ifr;
      int fd, err;
      if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
         return tun_alloc_old(dev);
      memset(&ifr, 0, sizeof(ifr));
      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
       *        IFF_TAP   - TAP device
       *
       *        IFF_NO_PI - Do not provide packet information
       */
      ifr.ifr_flags = IFF_TUN;
      if( *dev )
         strncpy(ifr.ifr_name, dev, IFNAMSIZ);
      if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
         close(fd);
         return err;
      }
      strcpy(dev, ifr.ifr_name);
      return fd;
  }

This is an example code found in TUN/TAP documentation. I need to do some network diagnosing programs and i plan to use Freepascal to do the job.

Opening the TUN/TAP (/dev/net/tun) without the ioctl call is not doing the job, but i dont know how to do this with pascal equivalent code...

Thanks in advance and sorry for any inconvenience...

Reply by email

Jorge Aldo G. de F. Junior
to Luca Olivetti

i already knew about fpioctl, but the ioctl example uses some macros to get the correct code, but i dont understand how

theres a python equivalent code that works, but i cant decypher this :

(Python code)

TUNSETIFF = 0x400454ca
IFF_TUN = 0x0001
IFF_TAP = 0x0002

TUNMODE = IFF_TUN

f = os.open("/dev/net/tun", os.O_RDWR)
ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "toto%d", TUNMODE)) ifname = ifs[:16].strip("\x00")

becomes (Pascal Code);
TUNSETIFF := $400454ca;
IFF_TUN := $0001; // TUN is a pseudo-ip device
IFF_TAP := $0002; // TAP is a pseudo-ethernet device
F := TFileStream.Create('/dev/net/tun', fmOpenReadWrite);
IFS := fpioctl(F.Handle, TUNSETIFF, ???);
IFNAME := ????

This makes the handle behave as a virtual network interface (allowing packet injection/reception from userland) and returns the correct interface name so as to allow passing it to scripts, ifconfig etc...

Reply by email

Henry Vermaak
to Jorge Aldo G. de F. Junior: Can anyone help me decypher the following code : int tun_alloc(char *dev) { struct ifreq…

2009/10/3 Jorge Aldo G. de F. Junior :

Show quoted text 5 lines
Can anyone help me decypher the following code : int tun_alloc(char *dev) { struct ifreq ifr;

First, you need to get a pascal definition of struct ifreq, so look in /usr/include/linux/if.h and translate it to pascal (or try and use h2pas).

int fd, err; if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) return tun_alloc_old(dev);

You will have to use fpopen here.

memset(&ifr, 0, sizeof(ifr));

Use fillchar.

Show quoted text 7 lines
/* Flags: IFF_TUN - TUN device (no Ethernet headers) * IFF_TAP - TAP device * * IFF_NO_PI - Do not provide packet information */

These flags are defined int /sys/include/linux/if_tun.h.

ifr.ifr_flags = IFF_TUN; if( *dev ) strncpy(ifr.ifr_name, dev, IFNAMSIZ);

ifr_name is defined to be ifr_ifrn.ifrn_name in if.h.

if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){

lol. TUNSETIFF (_IOW('T', 202, int)) is generated by the various macros in /usr/include/asm-generic/ioctl.h. Work it out, or write a c program to give you the number. Then use fpioctl.

The rest should be straight forward.

Henry

Reply by email

Jorge Aldo G. de F. Junior
to Henry Vermaak

ifreq becomes

Const

TUNSETIFF = $400454ca
IFF_TUN = $0001
IFF_TAP = $0002

type
     ifreq = record
          ifr_ifrn : record
              case longint of
                 0 : ( ifrn_name : array[0..15] of char );
              end;
          ifr_ifru : record
              case longint of
                 0 : ( ifru_addr : sockaddr );
                 1 : ( ifru_dstaddr : sockaddr );
                 2 : ( ifru_broadaddr : sockaddr );
                 3 : ( ifru_netmask : sockaddr );
                 4 : ( ifru_hwaddr : sockaddr );
                 5 : ( ifru_flags : smallint );
                 6 : ( ifru_ivalue : longint );
                 7 : ( ifru_mtu : longint );
                 8 : ( ifru_map : ifmap );
                 9 : ( ifru_slave : array[0..15] of char );
                 10 : ( ifru_newname : array[0..15] of char );
                 11 : ( ifru_data : __caddr_t );
              end;
       end;

now i need to translate sockaddr, ifmap, __caddr_t etc

but thanks !

2009/10/5 Henry Vermaak

Show quoted text 54 lines
2009/10/3 Jorge Aldo G. de F. Junior : > Can anyone help me decypher the following code : > > int tun_alloc(char *dev) > { > struct ifreq ifr; First, you need to get a pascal definition of struct ifreq, so look in /usr/include/linux/if.h and translate it to pascal (or try and use h2pas). > int fd, err; > > if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) > return tun_alloc_old(dev); You will have to use fpopen here. > > > memset(&ifr, 0, sizeof(ifr)); Use fillchar. > > /* Flags: IFF_TUN - TUN device (no Ethernet headers) > * IFF_TAP - TAP device > * > * IFF_NO_PI - Do not provide packet information > > */ These flags are defined int /sys/include/linux/if_tun.h. > ifr.ifr_flags = IFF_TUN; > if( *dev ) > strncpy(ifr.ifr_name, dev, IFNAMSIZ); ifr_name is defined to be ifr_ifrn.ifrn_name in if.h. > > if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ lol. TUNSETIFF (_IOW('T', 202, int)) is generated by the various macros in /usr/include/asm-generic/ioctl.h. Work it out, or write a c program to give you the number. Then use fpioctl. The rest should be straight forward. Henry _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Jürgen Hestermann
to Jorge Aldo G. de F. Junior
Show quoted text 23 lines
Jorge Aldo G. de F. Junior schrieb: type ifreq = record ifr_ifrn : record case longint of 0 : ( ifrn_name : array[0..15] of char ); end; ifr_ifru : record case longint of 0 : ( ifru_addr : sockaddr ); 1 : ( ifru_dstaddr : sockaddr ); 2 : ( ifru_broadaddr : sockaddr ); 3 : ( ifru_netmask : sockaddr ); 4 : ( ifru_hwaddr : sockaddr ); 5 : ( ifru_flags : smallint ); 6 : ( ifru_ivalue : longint ); 7 : ( ifru_mtu : longint ); 8 : ( ifru_map : ifmap ); 9 : ( ifru_slave : array[0..15] of char ); 10 : ( ifru_newname : array[0..15] of char ); 11 : ( ifru_data : __caddr_t ); end; end;

What is the reason of the first case statement in the record? There is only one variant so you can omit it.

Reply by email

Jorge Aldo G. de F. Junior
to Jürgen Hestermann

thats h2pas result of compilling this structure into pascal. But thanks for the tip.

2009/10/7 Jürgen Hestermann

Show quoted text 34 lines
> Jorge Aldo G. de F. Junior schrieb: > type ifreq = record > ifr_ifrn : record > case longint of > 0 : ( ifrn_name : array[0..15] of char ); > end; > ifr_ifru : record > case longint of > 0 : ( ifru_addr : sockaddr ); > 1 : ( ifru_dstaddr : sockaddr ); > 2 : ( ifru_broadaddr : sockaddr ); > 3 : ( ifru_netmask : sockaddr ); > 4 : ( ifru_hwaddr : sockaddr ); > 5 : ( ifru_flags : smallint ); > 6 : ( ifru_ivalue : longint ); > 7 : ( ifru_mtu : longint ); > 8 : ( ifru_map : ifmap ); > 9 : ( ifru_slave : array[0..15] of char ); > 10 : ( ifru_newname : array[0..15] of char ); > 11 : ( ifru_data : __caddr_t ); > end; > end; > > What is the reason of the first case statement in the record? There is only one variant so you can omit it. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email