// File: /workspace/github_c_makefile_star2_O0/open-mesh-mirror[P]batmand/hna.c
// Function: hna_global_update
void hna_global_update(struct orig_node *orig_node, unsigned char *new_hna,
				int16_t new_hna_len, struct neigh_node *old_router)
{
	struct hna_element *e, *buff;
	struct hna_global_entry *hna_global_entry;
	int i, num_elements, old_hna_len;
	unsigned char *old_hna;

	/* orig node stopped announcing any networks */
	if ((orig_node->hna_buff) && ((new_hna == NULL) || (new_hna_len == 0))) {
		hna_global_del(orig_node);
		return;
	}

	/* orig node started to announce networks */
	if ((!orig_node->hna_buff) && ((new_hna != NULL) || (new_hna_len != 0))) {
		hna_global_add(orig_node, new_hna, new_hna_len);
		return;
	}

	/**
	 * next hop router changed - no need to change the global hna hash
	 * we just have to make sure that the best orig node is still in place
	 * NOTE: we may miss a changed HNA here which we will update with the next packet
	 */
	if (old_router != orig_node->router) {
		num_elements = orig_node->hna_buff_len / sizeof(struct hna_element);
		buff = (struct hna_element *)orig_node->hna_buff;

		for (i = 0; i < num_elements; i++) {
			e = &buff[i];

			if ((e->netmask < 1) || (e->netmask > 32))
				continue;

			hna_global_entry = ((struct hna_global_entry *)hash_find(hna_global_hash, e));

			if (!hna_global_entry)
				continue;

			/* if the given orig node is not in use no routes need to change */
			if (hna_global_entry->curr_orig_node != orig_node)
				continue;

			add_del_route(e->addr, e->netmask, orig_node->router->addr,
					orig_node->router->if_incoming->addr.sin_addr.s_addr,
					orig_node->router->if_incoming->if_index,
					orig_node->router->if_incoming->dev,
					BATMAN_RT_TABLE_NETWORKS, ROUTE_TYPE_UNICAST, ROUTE_ADD);

			add_del_route(e->addr, e->netmask, old_router->addr,
				old_router->if_incoming->addr.sin_addr.s_addr,
				old_router->if_incoming->if_index,
				old_router->if_incoming->dev,
				BATMAN_RT_TABLE_NETWORKS, ROUTE_TYPE_UNICAST, ROUTE_DEL);
		}

		return;
	}

	/**
	 * check if the buffers even changed. if its still the same, there is no need to
	 * update the routes. if the router changed, then we have to update all the routes
	 * NOTE: no NULL pointer checking here because memcmp() just returns if n == 0
	 */
	if ((orig_node->hna_buff_len == new_hna_len) && (memcmp(orig_node->hna_buff, new_hna, new_hna_len) == 0))
		return;	/* nothing to do */

	/* changed HNA */
	old_hna = orig_node->hna_buff;
	old_hna_len = orig_node->hna_buff_len;

	orig_node->hna_buff = debugMalloc(new_hna_len, 706);
	orig_node->hna_buff_len = new_hna_len;
	memcpy(orig_node->hna_buff, new_hna, new_hna_len);

	/* add new routes and keep old routes */
	num_elements = orig_node->hna_buff_len / sizeof(struct hna_element);
	buff = (struct hna_element *)orig_node->hna_buff;

	for (i = 0; i < num_elements; i++) {
		e = &buff[i];

		/**
		 * if the router is the same, and the announcement was already in the old
		 * buffer, we can keep the route.
		 */
		if (hna_buff_delete((struct hna_element *)old_hna, &old_hna_len, e) == 0) {
			/* not found / deleted, need to add this new route */
			if ((e->netmask > 0) && (e->netmask <= 32))
				_hna_global_add(orig_node, e);
		}
	}

	/* old routes which are not to be kept are deleted now. */
	num_elements = old_hna_len / sizeof(struct hna_element);
	buff = (struct hna_element *)old_hna;

	for (i = 0; i < num_elements; i++) {
		e = &buff[i];

		if ((e->netmask > 0) && (e->netmask <= 32))
			_hna_global_del(orig_node, e);
	}

	/* dispose old hna buffer now. */
	if (old_hna != NULL)
		debugFree(old_hna, 1704);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movw %dx, %ax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movw %ax, -0x12(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x38(%rax)
je 0x9964
cmpq $0x0, -0x10(%rbp)
je 0x9956
movswl -0x12(%rbp), %eax
cmpl $0x0, %eax
jne 0x9964
movq -0x8(%rbp), %rdi
callq 0x9cb0
jmp 0x9caa
movq -0x8(%rbp), %rax
cmpq $0x0, 0x38(%rax)
jne 0x9995
cmpq $0x0, -0x10(%rbp)
jne 0x997f
movswl -0x12(%rbp), %eax
cmpl $0x0, %eax
je 0x9995
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movswl -0x12(%rbp), %edx
callq 0x9470
jmp 0x9caa
movq -0x20(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
je 0x9b14
movq -0x8(%rbp), %rax
movswq 0x40(%rax), %rax
movl $0x5, %ecx
xorl %edx, %edx
divq %rcx
movl %eax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x30(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x40(%rbp), %eax
jge 0x9b0f
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x5, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x1, %eax
jl 0x9a09
movq -0x28(%rbp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x20, %eax
jle 0x9a0e
jmp 0x9b01
movq 0x11d03(%rip), %rdi     # 0x1b718
movq -0x28(%rbp), %rsi
callq 0x83f0
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x9a2e
jmp 0x9b01
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
cmpq -0x8(%rbp), %rax
je 0x9a41
jmp 0x9b01
movq -0x28(%rbp), %rax
movl (%rax), %edi
movq -0x28(%rbp), %rax
movb 0x4(%rax), %al
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
movl 0x8(%rcx), %edx
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq 0x30(%rcx), %rcx
movl 0x34(%rcx), %ecx
movq -0x8(%rbp), %rsi
movq 0x8(%rsi), %rsi
movq 0x30(%rsi), %rsi
movl 0x20(%rsi), %r8d
movq -0x8(%rbp), %rsi
movq 0x8(%rsi), %rsi
movq 0x30(%rsi), %rsi
movq 0x8(%rsi), %r9
xorl %esi, %esi
movzbl %al, %esi
movl $0x41, (%rsp)
movl $0x0, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
callq 0xa420
movq -0x28(%rbp), %rax
movl (%rax), %edi
movq -0x28(%rbp), %rax
movb 0x4(%rax), %al
movq -0x20(%rbp), %rcx
movl 0x8(%rcx), %edx
movq -0x20(%rbp), %rcx
movq 0x30(%rcx), %rcx
movl 0x34(%rcx), %ecx
movq -0x20(%rbp), %rsi
movq 0x30(%rsi), %rsi
movl 0x20(%rsi), %r8d
movq -0x20(%rbp), %rsi
movq 0x30(%rsi), %rsi
movq 0x8(%rsi), %r9
xorl %esi, %esi
movzbl %al, %esi
movl $0x41, (%rsp)
movl $0x0, 0x8(%rsp)
movl $0x1, 0x10(%rsp)
callq 0xa420
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x99d0
jmp 0x9caa
movq -0x8(%rbp), %rax
movswl 0x40(%rax), %eax
movswl -0x12(%rbp), %ecx
cmpl %ecx, %eax
jne 0x9b44
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x10(%rbp), %rsi
movswq -0x12(%rbp), %rdx
callq 0x2270
cmpl $0x0, %eax
jne 0x9b44
jmp 0x9caa
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movswl 0x40(%rax), %eax
movl %eax, -0x44(%rbp)
movswl -0x12(%rbp), %edi
movl $0x2c2, %esi            # imm = 0x2C2
callq 0x7220
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x38(%rax)
movw -0x12(%rbp), %cx
movq -0x8(%rbp), %rax
movw %cx, 0x40(%rax)
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x10(%rbp), %rsi
movswq -0x12(%rbp), %rdx
callq 0x22c0
movq -0x8(%rbp), %rax
movswq 0x40(%rax), %rax
movl $0x5, %ecx
xorl %edx, %edx
divq %rcx
movl %eax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x30(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x40(%rbp), %eax
jge 0x9c26
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x5, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x50(%rbp), %rdi
movq -0x28(%rbp), %rdx
leaq -0x44(%rbp), %rsi
callq 0x9d80
cmpl $0x0, %eax
jne 0x9c19
movq -0x28(%rbp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x0, %eax
jle 0x9c17
movq -0x28(%rbp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x20, %eax
jg 0x9c17
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x9610
jmp 0x9c19
jmp 0x9c1b
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x9bbf
movslq -0x44(%rbp), %rax
movl $0x5, %ecx
xorl %edx, %edx
divq %rcx
movl %eax, -0x40(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x40(%rbp), %eax
jge 0x9c95
movq -0x30(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x5, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x0, %eax
jle 0x9c88
movq -0x28(%rbp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x20, %eax
jg 0x9c88
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x9e50
jmp 0x9c8a
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x9c46
cmpq $0x0, -0x50(%rbp)
je 0x9caa
movq -0x50(%rbp), %rdi
movl $0x6a8, %esi            # imm = 0x6A8
callq 0x7720
addq $0x70, %rsp
popq %rbp
retq