// File: /workspace/github_c_makefile_star2_O1/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 0x8956(%rip), %xmm0     # 0x1189d
movaps %xmm0, (%rsp)
leaq 0x858b(%rip), %rdi      # 0x114dd
movl $0x2, %esi
xorl %eax, %eax
callq 0x23a0
movl %eax, (%rbx)
testl %eax, %eax
js 0x9090
movq %rsp, %rdx
movl $0x400454ca, %esi       # imm = 0x400454CA
movl %eax, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x90b4
movl (%rbx), %edi
movl $0x400454cb, %esi       # imm = 0x400454CB
movl $0x1, %edx
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x90c9
movq %rbp, 0x28(%rsp)
movl $0x2, %edi
movl $0x2, %esi
xorl %edx, %edx
callq 0x24e0
testl %eax, %eax
js 0x90ef
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 0x911a
movq %rsp, %rdx
movl $0x8933, %esi           # imm = 0x8933
movl %ebp, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x9132
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 0x914a
movq %rsp, %rdx
orb $0x41, 0x10(%rdx)
movl $0x8914, %esi           # imm = 0x8914
movl %ebp, %edi
xorl %eax, %eax
callq 0x21d0
testl %eax, %eax
js 0x9162
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 0x917a
movl 0x40(%rsp), %eax
cmpl $0x63, %eax
jg 0x918f
leaq 0x86a5(%rip), %rsi      # 0x11727
xorl %edi, %edi
xorl %eax, %eax
callq 0xd5b0
jmp 0x91aa
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x84b7(%rip), %rsi      # 0x1155a
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd5b0
jmp 0x921a
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x84c7(%rip), %rsi      # 0x1158e
jmp 0x90dc
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x84e3(%rip), %rsi      # 0x115bf
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd5b0
movl (%rbx), %edi
jmp 0x9215
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x84f2(%rip), %rsi      # 0x115f4
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd5b0
movl (%rbx), %edi
callq 0x8eb8
jmp 0x921a
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x84f9(%rip), %rsi      # 0x11626
jmp 0x9200
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8514(%rip), %rsi      # 0x11659
jmp 0x9200
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8530(%rip), %rsi      # 0x1168d
jmp 0x9200
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x854c(%rip), %rsi      # 0x116c1
jmp 0x9200
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8568(%rip), %rsi      # 0x116f5
jmp 0x9200
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 0x91ed
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 0x921c
callq 0x2070
movl (%rax), %edi
callq 0x2480
leaq 0x8563(%rip), %rsi      # 0x11763
xorl %edi, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0xd5b0
movl (%rbx), %edi
callq 0x8eb8
movl %ebp, %edi
callq 0x21f0
movb $-0x1, %al
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq