// File: /workspace/github_c_makefile_star2_O3/open-mesh-mirror[P]batmand/linux/tun.c
// Function: add_dev_tun
int8_t add_dev_tun( struct batman_if *batman_if, uint32_t tun_addr, char *tun_dev, size_t tun_dev_size, int32_t *fd, int32_t *ifi ) {

	int32_t tmp_fd, sock_opts;
	struct ifreq ifr_tun, ifr_if;
	struct sockaddr_in addr;

	/* set up tunnel device */
	memset( &ifr_tun, 0, sizeof(ifr_tun) );
	memset( &ifr_if, 0, sizeof(ifr_if) );

	ifr_tun.ifr_flags = IFF_TUN | IFF_NO_PI;
	strncpy( ifr_tun.ifr_name, "gate%d", IFNAMSIZ );

	if ( ( *fd = open( "/dev/net/tun", O_RDWR ) ) < 0 ) {

		debug_output( 0, "Error - can't create tun device (/dev/net/tun): %s\n", strerror(errno) );
		return -1;

	}

	if ( ( ioctl( *fd, TUNSETIFF, (void *)&ifr_tun ) ) < 0 ) {

		debug_output( 0, "Error - can't create tun device (TUNSETIFF): %s\n", strerror(errno) );
		close(*fd);
		return -1;

	}

	if ( ioctl( *fd, TUNSETPERSIST, 1 ) < 0 ) {

		debug_output( 0, "Error - can't create tun device (TUNSETPERSIST): %s\n", strerror(errno) );
		close(*fd);
		return -1;

	}


	tmp_fd = socket( AF_INET, SOCK_DGRAM, 0 );

	if ( tmp_fd < 0 ) {
		debug_output( 0, "Error - can't create tun device (udp socket): %s\n", strerror(errno) );
		del_dev_tun( *fd );
		return -1;
	}


	/* set ip of this end point of tunnel */
	memset( &addr, 0, sizeof(addr) );
	addr.sin_addr.s_addr = tun_addr;
	addr.sin_family = AF_INET;
	memcpy( &ifr_tun.ifr_addr, &addr, sizeof(struct sockaddr) );


	if ( ioctl( tmp_fd, SIOCSIFADDR, &ifr_tun) < 0 ) {

		debug_output( 0, "Error - can't create tun device (SIOCSIFADDR): %s\n", strerror(errno) );
		del_dev_tun( *fd );
		close( tmp_fd );
		return -1;

	}


	if ( ioctl( tmp_fd, SIOCGIFINDEX, &ifr_tun ) < 0 ) {

		debug_output( 0, "Error - can't create tun device (SIOCGIFINDEX): %s\n", strerror(errno) );
		del_dev_tun( *fd );
		close( tmp_fd );
		return -1;

	}

	*ifi = ifr_tun.ifr_ifindex;

	if ( ioctl( tmp_fd, SIOCGIFFLAGS, &ifr_tun) < 0 ) {

		debug_output( 0, "Error - can't create tun device (SIOCGIFFLAGS): %s\n", strerror(errno) );
		del_dev_tun( *fd );
		close( tmp_fd );
		return -1;

	}

	ifr_tun.ifr_flags |= IFF_UP;
	ifr_tun.ifr_flags |= IFF_RUNNING;

	if ( ioctl( tmp_fd, SIOCSIFFLAGS, &ifr_tun) < 0 ) {

		debug_output( 0, "Error - can't create tun device (SIOCSIFFLAGS): %s\n", strerror(errno) );
		del_dev_tun( *fd );
		close( tmp_fd );
		return -1;

	}

	/* get MTU from real interface */
	strncpy( ifr_if.ifr_name, batman_if->dev, IFNAMSIZ - 1 );

	if ( ioctl( tmp_fd, SIOCGIFMTU, &ifr_if ) < 0 ) {

		debug_output( 0, "Error - can't create tun device (SIOCGIFMTU): %s\n", strerror(errno) );
		del_dev_tun( *fd );
		close( tmp_fd );
		return -1;

	}

	/* set MTU of tun interface: real MTU - 29 */
	if ( ifr_if.ifr_mtu < 100 ) {

		debug_output( 0, "Warning - MTU smaller than 100 -> can't reduce MTU anymore\n" );

	} else {

		ifr_tun.ifr_mtu = ifr_if.ifr_mtu - 29;

		if ( ioctl( tmp_fd, SIOCSIFMTU, &ifr_tun ) < 0 ) {

			debug_output( 0, "Error - can't create tun device (SIOCSIFMTU): %s\n", strerror(errno) );
			del_dev_tun( *fd );
			close( tmp_fd );
			return -1;

		}

	}


	/* make tun socket non blocking */
	sock_opts = fcntl( *fd, F_GETFL, 0 );
	fcntl( *fd, F_SETFL, sock_opts | O_NONBLOCK );


	strncpy( tun_dev, ifr_tun.ifr_name, tun_dev_size - 1 );
	close( tmp_fd );

	return 1;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r9, %r13
movq %r8, %rbx
movq %rcx, %r14
movq %rdx, %rbp
movl %esi, %r15d
movq %rdi, %r12
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
movq %rax, 0x20(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x40(%rsp)
movq %rax, 0x50(%rsp)
movw $0x1001, 0x10(%rsp)     # imm = 0x1001
movups 0x86a3(%rip), %xmm0     # 0x1194a
movaps %xmm0, (%rsp)
leaq 0x82d8(%rip), %rdi      # 0x1158a
movl $0x2, %esi
xorl %eax, %eax
callq 0x23a0
movl %eax, (%rbx)
testl %eax, %eax
js 0x93f0
movq %rsp, %rdx
movl $0x400454ca, %esi       # imm = 0x400454CA
movl %eax, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x9414
movl (%rbx), %edi
movl $0x400454cb, %esi       # imm = 0x400454CB
movl $0x1, %edx
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x9429
movq %rbp, 0x28(%rsp)
movl $0x2, %edi
movl $0x2, %esi
xorl %edx, %edx
callq 0x24e0
testl %eax, %eax
js 0x944f
movl %eax, %ebp
movq %rsp, %rdx
movl $0x2, 0x10(%rdx)
movl %r15d, 0x14(%rdx)
movq $0x0, 0x18(%rdx)
movl $0x8916, %esi           # imm = 0x8916
movl %eax, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x947a
movq %rsp, %rdx
movl $0x8933, %esi           # imm = 0x8933
movl %ebp, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x9492
movq %rsp, %rdx
movl 0x10(%rdx), %eax
movl %eax, (%r13)
movl $0x8913, %esi           # imm = 0x8913
movl %ebp, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x94aa
movq %rsp, %rdx
orb $0x41, 0x10(%rdx)
movl $0x8914, %esi           # imm = 0x8914
movl %ebp, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x94c2
movq 0x8(%r12), %rsi
leaq 0x30(%rsp), %r12
movl $0xf, %edx
movq %r12, %rdi
callq 0x2090
movl $0x8921, %esi           # imm = 0x8921
movl %ebp, %edi
movq %r12, %rdx
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x94da
movl 0x40(%rsp), %eax
cmpl $0x63, %eax
jg 0x94ef
leaq 0x83f2(%rip), %rsi      # 0x117d4
xorl %edi, %edi
xorl %eax, %eax
callq 0xd88c
jmp 0x950a
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8204(%rip), %rsi      # 0x11607
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd88c
jmp 0x957a
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8214(%rip), %rsi      # 0x1163b
jmp 0x943c
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8230(%rip), %rsi      # 0x1166c
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd88c
movl (%rbx), %edi
jmp 0x9575
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x823f(%rip), %rsi      # 0x116a1
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd88c
movl (%rbx), %edi
callq 0x9218
jmp 0x957a
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8246(%rip), %rsi      # 0x116d3
jmp 0x9560
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8261(%rip), %rsi      # 0x11706
jmp 0x9560
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x827d(%rip), %rsi      # 0x1173a
jmp 0x9560
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8299(%rip), %rsi      # 0x1176e
jmp 0x9560
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x82b5(%rip), %rsi      # 0x117a2
jmp 0x9560
addl $-0x1d, %eax
movq %rsp, %rdx
movl %eax, 0x10(%rdx)
movl $0x8922, %esi           # imm = 0x8922
movl %ebp, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x954d
movl (%rbx), %edi
movl $0x3, %esi
xorl %edx, %edx
xorl %eax, %eax
callq 0x20e0
movl (%rbx), %edi
orl $0x800, %eax            # imm = 0x800
movl $0x4, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x20e0
decq %r14
movq %rsp, %rsi
movq 0x28(%rsp), %rdi
movq %r14, %rdx
callq 0x2090
movl %ebp, %edi
callq 0x21f0
movb $0x1, %al
jmp 0x957c
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x82b0(%rip), %rsi      # 0x11810
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd88c
movl (%rbx), %edi
callq 0x9218
movl %ebp, %edi
callq 0x21f0
movb $-0x1, %al
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq