📄 parse.c
字号:
#include "stdhead.h"#include "lib.h"#include "parse.h"char *config_buff = 0, *curr_ptr = 0, *token = 0;// Read the entire configuration file into config_buffvoid read_config_file (char *file_name){ int fd, n, size = 0; if ((fd = open (file_name, O_RDONLY)) == -1) { printf ("Error opening file %s.\n", file_name); exit (0); } config_buff = (char *) realloc (config_buff, 1); size = 1; while (read (fd, &config_buff[size - 1], 1) > 0) { size++; config_buff = (char *) realloc (config_buff, size); } config_buff[size - 1] = '\0'; close (fd);} // skip all whitespacevoid skip_whitespace (void){ while ((*curr_ptr == ' ') || (*curr_ptr == '\t') || (*curr_ptr == '\r') || (*curr_ptr == '\n')) curr_ptr++;}// move across substring return success/failureint move_across_substring (char *substring){ curr_ptr = strstr (curr_ptr, substring); if (curr_ptr) curr_ptr += strlen (substring); else return 0; return 1;}// Move across the substring. If not found exitint Move_across_substring (char *substring){ curr_ptr = strstr (curr_ptr, substring); if (curr_ptr) curr_ptr += strlen (substring); else { printf ("Configuration file not correct.\n"); exit (1); } return 1;}// Read the next tokenvoid read_token (void){ char *p; int n = 0; if (token) token = (char *) realloc (token, 0); while ((*curr_ptr != ' ') && (*curr_ptr != '\t') && (*curr_ptr != '\r') && (*curr_ptr != '\n')) { n++; token = (char *) realloc (token, n); p = token + (n - 1); *p = *curr_ptr; curr_ptr++; } n++; token = (char *) realloc (token, n); p = token + (n - 1); *p = '\0';}// Find if substring s1 occurs before s2int find_if_s1_before_s2 (char *s1, char *s2){ char *search_s1 = 0, *search_s2 = 0; search_s1 = strstr (curr_ptr, s1); search_s2 = strstr (curr_ptr, s2); if (!search_s1 && !search_s2) return 0; else if ((search_s2 && (search_s2 > search_s1)) || !search_s2) { curr_ptr = search_s1; curr_ptr += strlen (s1); return 1; } else return 0;}// Return an array of link list of possible range and user nodestruct config_head ** parse_and_assign (char *file_name, int *subnet_count, int relay_agent_flag){ extern struct DUID *server_duid; struct DUID1 *server_duid1; struct DUID2 *server_duid2; struct DUID3 *server_duid3; char *bkup_curr_ptr = 0, *start = 0; struct config_range *range_node, *prev_range_ptr = 0; struct config_user *user_node, *prev_user_ptr = 0; int node_count = 0, i, count = 0; struct config_head **head; u_int8_t temp[2]; *(subnet_count) = 0; if (relay_agent_flag) // Multiple subnets configuration return; // One server subnet only if (file_name) read_config_file (file_name); else read_config_file (DEFAULT_CONFIG_FILE); // assign current pointer to configuration buffer curr_ptr = config_buff; Move_across_substring ("duid_type"); skip_whitespace(); read_token(); server_duid = (struct DUID *) malloc (sizeof (struct DUID)); server_duid -> u_duid_type.duid_type = atoi (token); server_duid -> opt = 0; Move_across_substring ("{"); switch (server_duid -> u_duid_type.duid_type) { case 1 : start = curr_ptr; server_duid1 = (struct DUID1 *) malloc (sizeof (struct DUID1)); server_duid -> duid_type = server_duid1; Move_across_substring ("time"); skip_whitespace(); read_token(); server_duid1 -> u_time.time = atoi (token); curr_ptr = start; Move_across_substring ("hardware_type"); skip_whitespace(); read_token(); server_duid1 -> u_haddr_type.haddr_type = atoi (token); curr_ptr = start; Move_across_substring ("hardware_len"); skip_whitespace(); read_token(); server_duid1 -> haddr_len = atoi (token); curr_ptr = start; Move_across_substring ("hardware_addr"); skip_whitespace(); read_token(); server_duid1 -> link_layer_address = (u_int8_t *) malloc (sizeof (u_int8_t) * server_duid1 -> haddr_len); for (i = 0; i < 3 * server_duid1 -> haddr_len - 1; i += 3) { temp[0] = convert_character_to_hex (token[i]); temp[1] = convert_character_to_hex (token[i + 1]); server_duid1 -> link_layer_address[count++] = (temp[0] << 4) | temp[1]; } break; case 2 : start = curr_ptr; server_duid2 = (struct DUID2 *) malloc (sizeof (struct DUID2)); server_duid -> duid_type = server_duid2; curr_ptr = start; Move_across_substring ("ident_len"); skip_whitespace(); read_token(); server_duid2 -> u_identifier_length.identifier_length = atoi (token); curr_ptr = start; Move_across_substring ("identifier"); skip_whitespace(); read_token(); server_duid2 -> identifier = (u_int8_t *) malloc (sizeof (u_int8_t) * server_duid2 -> u_identifier_length.identifier_length); for (i = 0; i < server_duid2 -> u_identifier_length.identifier_length; i++) server_duid2 -> identifier[i] = token[i]; curr_ptr = start; Move_across_substring ("domain_name"); skip_whitespace(); read_token(); server_duid2 -> domain_name_len = sizeof (token); server_duid2 -> domain_name = (char *) malloc (sizeof (char) * server_duid2 -> domain_name_len); for (i = 0; i < server_duid2 -> domain_name_len; i++) server_duid2 -> domain_name[i] = token[i]; break; case 3 : start = curr_ptr; server_duid3 = (struct DUID3 *) malloc (sizeof (struct DUID3)); server_duid -> duid_type = server_duid3; Move_across_substring ("hardware_type"); skip_whitespace(); read_token(); server_duid3 -> u_haddr_type.haddr_type = atoi (token); curr_ptr = start; Move_across_substring ("hardware_len"); skip_whitespace(); read_token(); server_duid3 -> haddr_len = atoi (token); curr_ptr = start; Move_across_substring ("hardware_addr"); skip_whitespace(); read_token(); server_duid3 -> link_layer_address = (u_int8_t *) malloc (sizeof (u_int8_t) * server_duid3 -> haddr_len); for (i = 0; i < 3 * server_duid3 -> haddr_len - 1; i += 3) { temp[0] = convert_character_to_hex (token[i]); temp[1] = convert_character_to_hex (token[i + 1]); server_duid3 -> link_layer_address[count++] = (temp[0] << 4) | temp[1]; } break; default : printf ("Unrecognized DUID type\n"); exit (1); } Move_across_substring ("}"); head = (struct config_head **) malloc (sizeof (struct config_head *)); head[(*subnet_count)++] = (struct config_head *) malloc (sizeof (struct config_head)); Move_across_substring ("subnet"); Move_across_substring ("t1"); skip_whitespace(); read_token(); head[*(subnet_count) - 1] -> t1 = atoi (token); Move_across_substring ("t2"); skip_whitespace(); read_token(); head[*(subnet_count) - 1] -> t2 = atoi (token); // Build all user nodes bkup_curr_ptr = curr_ptr; while (find_if_s1_before_s2 ("user", "subnet"))//if user is before subnet. { user_node = (struct config_user *) malloc (sizeof (struct config_user)); if (!node_count) { head[*(subnet_count) - 1]->first_node_type = USER_NODE; head[*(subnet_count) - 1]->next = user_node; } else { prev_user_ptr->next = user_node; prev_user_ptr->next_node_type = USER_NODE; } node_count++; prev_user_ptr = user_node; move_across_substring ("{"); start = curr_ptr; move_across_substring ("link_local_address"); skip_whitespace(); read_token(); user_node -> link_local_addr = (struct in6_addr *) malloc (sizeof (struct in6_addr)); inet_pton (AF_INET6, token, user_node -> link_local_addr); curr_ptr = start; move_across_substring ("IPv6_address"); skip_whitespace(); read_token(); user_node -> ipv6_addr = (struct in6_addr *) malloc (sizeof (struct in6_addr)); inet_pton (AF_INET6, token, user_node -> ipv6_addr); curr_ptr = start; move_across_substring ("preferred_lifetime"); skip_whitespace(); read_token(); user_node -> pref_life = atoi (token); curr_ptr = start; move_across_substring ("valid_lifetime"); skip_whitespace(); read_token(); user_node -> valid_life = atoi (token); curr_ptr = start; move_across_substring ("max_renew_count"); skip_whitespace(); read_token(); user_node -> max_renew_count = atoi (token); curr_ptr = start; move_across_substring ("preference_val"); skip_whitespace(); read_token(); user_node -> pref_val = atoi (token); move_across_substring ("}"); } // Build all range nodes curr_ptr = bkup_curr_ptr; while (find_if_s1_before_s2 ("range", "subnet")) { range_node = (struct config_range *) malloc (sizeof (struct config_range)); if (!node_count) { head[*(subnet_count) - 1]->first_node_type = RANGE_NODE; head[*(subnet_count) - 1]->next = range_node; } else { if (prev_user_ptr) { prev_user_ptr->next = range_node; prev_user_ptr->next_node_type = RANGE_NODE; prev_user_ptr = 0; } else { prev_range_ptr->next = range_node; prev_range_ptr->next_node_type = RANGE_NODE; } } node_count++; prev_range_ptr = range_node; skip_whitespace(); read_token(); range_node -> st_addr = (struct in6_addr *) malloc (sizeof (struct in6_addr)); inet_pton (AF_INET6, token, range_node -> st_addr); skip_whitespace(); read_token(); range_node -> end_addr = (struct in6_addr *) malloc (sizeof (struct in6_addr)); inet_pton (AF_INET6, token, range_node -> end_addr); move_across_substring ("{"); start = curr_ptr; move_across_substring ("preferred_lifetime"); skip_whitespace(); read_token(); range_node -> pref_life = atoi (token); curr_ptr = start; move_across_substring ("valid_lifetime"); skip_whitespace(); read_token(); range_node -> valid_life = atoi (token); curr_ptr = start; move_across_substring ("max_renew_count"); skip_whitespace(); read_token(); range_node -> max_renew_count = atoi (token); curr_ptr = start; move_across_substring ("preference_val"); skip_whitespace(); read_token(); range_node -> pref_val = atoi (token); move_across_substring ("}"); } Move_across_substring ("}"); if (prev_user_ptr) { prev_user_ptr -> next_node_type = NO_NODE; prev_user_ptr -> next = 0; } else if (prev_range_ptr) { prev_range_ptr -> next_node_type = NO_NODE; prev_range_ptr -> next = 0; } else { head[*(subnet_count) - 1] -> first_node_type = NO_NODE; head[*(subnet_count) - 1] -> next = 0; } return head;}// Print the contents of the linked list.void print_config_list_contents (struct config_head *head){ struct config_range *range_node = 0; struct config_user *user_node = 0; char name[64]; printf ("Subnet options\n"); printf ("T1 = %d\n", head -> t1); printf ("T2 = %d\n", head -> t2); if (head -> first_node_type == RANGE_NODE) range_node = (struct config_range *) head -> next; else if (head -> first_node_type == USER_NODE) user_node = (struct config_user *) head -> next; else if (head -> first_node_type == NO_NODE) return; while (user_node) { printf ("\nLink local address of user = %s\n", inet_ntop (AF_INET6, (char *) user_node -> link_local_addr, name, 64)); printf ("IPv6 address of user = %s\n", inet_ntop (AF_INET6, (char *) user_node -> ipv6_addr, name, 64)); printf ("Preferred lifetime = %d\n", user_node -> pref_life); printf ("Valid lifetime = %d\n", user_node -> valid_life); printf ("Maximum renewal count = %d\n", user_node -> max_renew_count); printf ("Preference value = %d\n", user_node -> pref_val); if (user_node -> next_node_type == RANGE_NODE) { range_node = (struct config_range *) user_node -> next; break; } else if (user_node -> next_node_type == USER_NODE) user_node = (struct config_user *) user_node -> next; else if (user_node -> next_node_type == NO_NODE) return; } while (range_node) { printf ("\nStarting address of range = %s\n", inet_ntop (AF_INET6, (char *) range_node -> st_addr, name, 64)); printf ("Ending address of range = %s\n", inet_ntop (AF_INET6, (char *) range_node -> end_addr, name, 64)); printf ("Preferred lifetime = %d\n", range_node -> pref_life); printf ("Valid lifetime = %d\n", range_node -> valid_life); printf ("Maximum renewal count = %d\n", range_node -> max_renew_count); printf ("Preference value = %d\n", range_node -> pref_val); if (range_node -> next_node_type == RANGE_NODE) range_node = (struct config_range *) range_node -> next; else if (range_node -> next_node_type == NO_NODE) return; }}void print_server_duid (void){ extern struct DUID *server_duid; struct DUID1 *d1; struct DUID2 *d2; struct DUID3 *d3; int i; printf ("\nServer DUID\n"); printf ("DUID type = %d\n", server_duid -> u_duid_type.duid_type); switch (server_duid -> u_duid_type.duid_type) { case 1 : d1 = server_duid -> duid_type; printf ("Time = %d\n", d1 -> u_time.time); printf ("Hardware type = %d\nHardware address = ", d1 -> u_haddr_type.haddr_type); for (i = 0; i < 6; i++) { printf ("%x", d1 -> link_layer_address[i]); if (i != 5) printf (":"); } break; case 2 : d2 = server_duid -> duid_type; printf ("Identifier length = %d\nIdentifier = ", d2 -> u_identifier_length.identifier_length); for (i = 0; i < d2 -> u_identifier_length.identifier_length; i++) printf ("%d", d2 -> identifier[i]); printf ("\nDomain name = "); for (i = 0; i < d2 -> domain_name_len; i++) printf ("%c", d2 -> domain_name[i]); break; case 3 : d3 = server_duid -> duid_type; printf ("Hardware type = %d\nHardware address = ", d3 -> u_haddr_type.haddr_type); for (i = 0; i < 6; i++) { printf ("%x", d3 -> link_layer_address[i]); if (i != 5) printf (":"); } break; } printf ("\n\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -