Lazarus

Programming => Operating Systems => Linux => Topic started by: Hiko222 on April 20, 2018, 08:20:45 pm

Title: Linux TUN
Post by: Hiko222 on April 20, 2018, 08:20:45 pm
Hi, I can create a TUN((

Code: Pascal  [Select][+][-]
  1. const
  2.     IFF_TUN = $0001;
  3.     TUNSETIFF = $400454ca;
  4.     IFF_NO_PI = $1000;
  5.  
  6.   type
  7.     __caddr_t = byte;
  8.  
  9.     {$IFDEF CPU64}
  10.       Ifmap = record
  11.         mem_start : int64;
  12.         mem_end : int64;
  13.         base_addr : word;
  14.         irq : byte;
  15.         dma : byte;
  16.         port : byte;
  17.         spare : array[0..2] of byte;
  18.       end;
  19.     {$ELSE}
  20.       Ifmap = record
  21.         mem_start : dword;
  22.         mem_end : dword;
  23.         base_addr : word;
  24.         irq : byte;
  25.         dma : byte;
  26.         port : byte;
  27.         spare : array[0..2] of byte;
  28.       end;
  29.     {$ENDIF}
  30.  
  31.     Ifreq = record
  32.       ifr_ifrn : record
  33.         case longint of
  34.           0 : ( ifrn_name : array[0..15] of char );
  35.         end;
  36.       ifr_ifru : record
  37.         case longint of
  38.           0 : ( ifru_addr : sockaddr );
  39.           1 : ( ifru_dstaddr : sockaddr );
  40.           2 : ( ifru_broadaddr : sockaddr );
  41.           3 : ( ifru_netmask : sockaddr );
  42.           4 : ( ifru_hwaddr : sockaddr );
  43.           5 : ( ifru_flags : smallint );
  44.           6 : ( ifru_ifindex : longint );
  45.           7 : ( ifru_metric : longint );
  46.           8 : ( ifru_mtu : longint );
  47.           9 : ( ifru_map : ifmap );
  48.           10 : ( ifru_slave : array[0..15] of char );
  49.           11 : ( ifru_newname : array[0..15] of char );
  50.           12 : ( ifru_data : __caddr_t  );
  51.         end;
  52.       end;
  53.  
  54.   function createTunWithName(name, address, subnetmask : String; mtu : Integer) : Integer;
  55.   var
  56.     fileDescriptor : Integer;
  57.     ifr: Ifreq;
  58.   begin
  59.     fileDescriptor := fpOpen('/dev/net/tun', O_RDWR);
  60.  
  61.     if fileDescriptor < 0 then
  62.       exit(ERROR);
  63.  
  64.     ifr.ifr_ifru.ifru_flags := IFF_TUN or IFF_NO_PI;
  65.  
  66.     if length(name) > 0 then
  67.       ifr.ifr_ifrn.ifrn_name := name;
  68.  
  69.     if fpIOCtl(fileDescriptor, TUNSETIFF, @ifr) < 0 then
  70.       begin
  71.         fpClose(fileDescriptor);
  72.         exit(ERROR);
  73.       end;
  74.  

fpIOCtl returned -1, fpgeterrno returned 77. Please help!
Title: Re: Linux TUN
Post by: Leledumbo on April 22, 2018, 09:20:29 am
fpIOCtl returned -1, fpgeterrno returned 77. Please help!
77 is EBADFD, that means your fpopen return value is actually invalid. Did you run with sudo? Normal users shouldn't have privileges to open device.
Title: Re: Linux TUN
Post by: Hiko222 on April 22, 2018, 10:31:37 am
fpIOCtl returned -1, fpgeterrno returned 77. Please help!
77 is EBADFD, that means your fpopen return value is actually invalid. Did you run with sudo? Normal users shouldn't have privileges to open device.

I run code from the root. I wrote a library for c++, it creates tun normally.
Title: Re: Linux TUN
Post by: zeljko on April 22, 2018, 01:53:13 pm
Are you sure that your record ifmap is exact same as C struct ?
Title: Re: Linux TUN
Post by: Hiko222 on April 22, 2018, 10:42:58 pm
Are you sure that your record ifmap is exact same as C struct ?

yes

struct ifmap
{
    unsigned long   mem_start;
    unsigned long   mem_end;
    unsigned short  base_addr;
    unsigned char   irq;                 
    unsigned char   dma;
    unsigned char   port;
};
Title: Re: Linux TUN
Post by: Laksen on April 22, 2018, 10:49:58 pm
Have you verified that the structs are the right size compared to the C versions?

You might have to add a {$packrecords C} in there first
Title: Re: Linux TUN
Post by: Hiko222 on April 22, 2018, 11:04:39 pm
Have you verified that the structs are the right size compared to the C versions?

You might have to add a {$packrecords C} in there first

fpgeterrno returned 77((
Title: Re: Linux TUN
Post by: benohb on April 23, 2018, 01:53:12 am
what do you want to do . Maybe there is another way
shared some of your thoughts :D
Title: Re: Linux TUN
Post by: Hiko222 on April 23, 2018, 08:25:42 am
what do you want to do . Maybe there is another way
shared some of your thoughts :D

I want to create a Tun interface! But it does not work.
Title: Re: Linux TUN
Post by: Thaddy on April 23, 2018, 09:00:07 am
Make sure your records are all packed C, like:
Code: Pascal  [Select][+][-]
  1. {$IFDEF FPC}{$PACKRECORDS C}{$ENDIF}
  2.   type
  3.     ifmap = packed record  // declare ALL records as packed, also all child records.
  4.         mem_start : dword;
  5.         mem_end : dword;
  6.         base_addr : word;
  7.         irq : byte;
  8.         dma : byte;
  9.         port : byte;
  10.       end;
Here your original code works (as root). I only added all the packed and changed char to byte because a C char is actually a byte.
If you do not use packed, a record uses natural alignment. You *must* use packed afaik.
Title: Re: Linux TUN
Post by: benohb on April 24, 2018, 02:04:57 am
Make sure your records are all packed C, like:
Code: Pascal  [Select][+][-]
  1. {$IFDEF FPC}{$PACKRECORDS C}{$ENDIF}
  2.   type
  3.     ifmap = packed record  // declare ALL records as packed, also all child records.
  4.         mem_start : dword;
  5.         mem_end : dword;
  6.         base_addr : word;
  7.         irq : byte;
  8.         dma : byte;
  9.         port : byte;
  10.       end;
Here your original code works (as root). I only added all the packed and changed char to byte because a C char is actually a byte.
If you do not use packed, a record uses natural alignment. You *must* use packed afaik.



Does the code work in your computer ??
Title: Re: Linux TUN
Post by: Thaddy on April 24, 2018, 09:50:09 am
Only if there is an interface established (I use both OpenSSH and vtund). I forgot to tell the second const needs to be cint cast.
Title: Re: Linux TUN
Post by: Hiko222 on April 24, 2018, 05:03:33 pm
So everything is fine, I created an interface. I can read from it. But I can not write to it ...

Code: Pascal  [Select][+][-]
  1.   var
  2.     data : string[10] = '1234567890';
  3.   begin
  4.     writeln(fileDescriptor);
  5.     writeln(fpWrite(fileDescriptor, data[1], 1));
  6.     writeln(fpgeterrno);
  7.  

fileDescriptor = 5
fpWrite= -1
fpgeterrno = 22

I updated the main code in the first message!
с code write data fine!
Title: Re: Linux TUN
Post by: Hiko222 on April 25, 2018, 06:23:57 pm
the solution of the problem found here
https://github.com/songgao/water/issues/18

Thanks for the help!
Title: Re: Linux TUN
Post by: Hiko222 on April 26, 2018, 09:17:34 am
Why the use of IFF_NO_PI in c ++ goes fine and at FPC at write causes an error of 22 (EINVAL)?
TinyPortal © 2005-2018