📄 dsr_pkt_support.ex.c
字号:
/* dsr_pkt_support.ex.c *//* C support file for creation and deletion of DSR packets *//****************************************//* Copyright (c) 1987-2005 *//* by OPNET Technologies, Inc. *//* (A Delaware Corporation) *//* 7255 Woodmont Av., Suite 250 *//* Bethesda, MD 20814, U.S.A. *//* All Rights Reserved. *//****************************************//***** Includes *****/#include <opnet.h>#include <dsr.h>#include <dsr_pkt_support.h>#include <dsr_ptypes.h>#include <ip_addr_v4.h>/* Macro definition for string handling. */#define DSR_PKPRINT_STRING_INSERT(str, contents, list) \ { \ str = (char*) op_prg_mem_alloc ((strlen (contents) + 1) * sizeof (char)); \ strcpy (str, contents); \ op_prg_list_insert (list, str, OPC_LISTPOS_TAIL); \ }/* File Globals */static int fd_options_index = OPC_FIELD_INDEX_INVALID;/**** Prototypes ****/static List* dsr_pkt_support_tlv_options_mem_copy (List* tlv_options_lptr);static DsrT_Packet_Option* dsr_pkt_support_route_request_mem_copy (DsrT_Packet_Option*);static DsrT_Packet_Option* dsr_pkt_support_route_reply_mem_copy (DsrT_Packet_Option*);static DsrT_Packet_Option* dsr_pkt_support_route_error_mem_copy (DsrT_Packet_Option*);static DsrT_Packet_Option* dsr_pkt_support_ack_request_mem_copy (DsrT_Packet_Option*);static DsrT_Packet_Option* dsr_pkt_support_acknowledgement_mem_copy (DsrT_Packet_Option*);static DsrT_Packet_Option* dsr_pkt_support_source_route_mem_copy (DsrT_Packet_Option*);static void dsr_pkt_support_tlv_options_mem_free (List* tlv_options_lptr);static void dsr_pkt_support_route_request_mem_free (DsrT_Packet_Option*);static void dsr_pkt_support_route_reply_mem_free (DsrT_Packet_Option*);static void dsr_pkt_support_route_error_mem_free (DsrT_Packet_Option*);static void dsr_pkt_support_ack_request_mem_free (DsrT_Packet_Option*);static void dsr_pkt_support_acknowledgement_mem_free (DsrT_Packet_Option*);static void dsr_pkt_support_source_route_mem_free (DsrT_Packet_Option*);static DsrT_Packet_Option* dsr_pkt_support_option_mem_alloc (void);static DsrT_Route_Request_Option* dsr_pkt_support_route_request_mem_alloc (void);static DsrT_Route_Reply_Option* dsr_pkt_support_route_reply_mem_alloc (void);static DsrT_Route_Error_Option* dsr_pkt_support_route_error_mem_alloc (void);static DsrT_Acknowledgement_Request* dsr_pkt_support_ack_request_mem_alloc (void);static DsrT_Acknowledgement* dsr_pkt_support_acknowledgement_mem_alloc (void);static DsrT_Source_Route_Option* dsr_pkt_support_source_route_mem_alloc (void);/*****************************************************//************* PACKET CREATION FUNCTIONS *************//*****************************************************/Packet*dsr_pkt_support_pkt_create (int next_header) { Packet* dsr_pkptr = OPC_NIL; List* tlv_options_lptr = OPC_NIL; /** Create the DSR packet with the list of **/ /** options that are passed in. A single **/ /** packet can have multiple options **/ FIN (dsr_pkt_support_pkt_create (<args>)); /* Create the DSR packet */ dsr_pkptr = op_pk_create_fmt ("dsr"); /* Create a list to store the options */ tlv_options_lptr = op_prg_list_create (); /* Set the options in the packet */ op_pk_nfd_set (dsr_pkptr, "Options", tlv_options_lptr, dsr_pkt_support_tlv_options_mem_copy, dsr_pkt_support_tlv_options_mem_free, 0); /* Set the next header in the packet */ /* The next header field of the DSR */ /* packet is set to the protocol field */ /* of the IP datagram */ op_pk_nfd_set (dsr_pkptr, "Next Header", next_header); FRET (dsr_pkptr); }Packet*dsr_pkt_support_pkt_create_with_options (int next_header, List* tlv_options_lptr) { Packet* dsr_pkptr = OPC_NIL; DsrT_Packet_Option* dsr_tlv_ptr = OPC_NIL; int total_length = 0; int num_options, count; /** Create the DSR packet with the list of **/ /** options that are passed in. A single **/ /** packet can have multiple options **/ FIN (dsr_pkt_support_pkt_create_with_options (<args>)); /* Create the DSR packet */ dsr_pkptr = op_pk_create_fmt ("dsr"); /* Get the field index for the options field */ if (fd_options_index == OPC_FIELD_INDEX_INVALID) fd_options_index = op_pk_nfd_name_to_index (dsr_pkptr, "Options"); /* Determine the number of options in the list */ num_options = op_prg_list_size (tlv_options_lptr); for (count = 0; count < num_options; count++) { /* Access each TLV in the list */ /* to determine its size */ dsr_tlv_ptr = (DsrT_Packet_Option*) op_prg_list_access (tlv_options_lptr, count); /* Get the total size of all the options */ total_length += dsr_tlv_ptr->option_length; } /* Set the options in the packet */ op_pk_fd_set (dsr_pkptr, fd_options_index, OPC_FIELD_TYPE_STRUCT, tlv_options_lptr, total_length, dsr_pkt_support_tlv_options_mem_copy, dsr_pkt_support_tlv_options_mem_free, sizeof (List)); /* Set the next header in the packet */ /* The next header field of the DSR */ /* packet is set to the protocol field */ /* of the IP datagram */ op_pk_nfd_set (dsr_pkptr, "Next Header", next_header); FRET (dsr_pkptr); }voiddsr_pkt_support_option_add (Packet* dsr_pkptr, DsrT_Packet_Option* dsr_tlv_ptr) { int total_length = 0; OpT_Packet_Size field_size = 0; List* tlv_options_lptr = OPC_NIL; int num_options, count; DsrT_Packet_Option* exist_dsr_tlv_ptr = OPC_NIL; Boolean option_inserted = OPC_FALSE; /** Add an option to the DSR packet **/ FIN (dsr_pkt_support_option_add (<args>)); /* Get the field index for the options field */ if (fd_options_index == OPC_FIELD_INDEX_INVALID) fd_options_index = op_pk_nfd_name_to_index (dsr_pkptr, "Options"); /* Determine the size of the field, before we strip it */ /* from the packet. */ field_size = (int) op_pk_fd_size (dsr_pkptr, fd_options_index); /* Get the list of options */ op_pk_fd_get (dsr_pkptr, fd_options_index, &tlv_options_lptr); /* Determine the number of options in the list */ num_options = op_prg_list_size (tlv_options_lptr); /* Determine the total length of the options field */ /* with the new option added */ total_length = field_size + dsr_tlv_ptr->option_length; /* Insert the new option into the list */ /* Always insert all options before the */ /* source route option */ for (count = 0; count < num_options; count++) { /* Access each TLV in the list */ exist_dsr_tlv_ptr = (DsrT_Packet_Option*) op_prg_list_access (tlv_options_lptr, count); if (exist_dsr_tlv_ptr->option_type == DSRC_SOURCE_ROUTE) { /* Insert before the source route option */ op_prg_list_insert (tlv_options_lptr, dsr_tlv_ptr, count); option_inserted = OPC_TRUE; break; } } if (option_inserted == OPC_FALSE) { /* There is no source route in the packet */ /* Insert the option at the end of the list */ op_prg_list_insert (tlv_options_lptr, dsr_tlv_ptr, OPC_LISTPOS_TAIL); } /* Set the options in the packet */ op_pk_fd_set (dsr_pkptr, fd_options_index, OPC_FIELD_TYPE_STRUCT, tlv_options_lptr, total_length, dsr_pkt_support_tlv_options_mem_copy, dsr_pkt_support_tlv_options_mem_free, sizeof (List)); FOUT; }voiddsr_pkt_support_option_remove (Packet* dsr_pkptr, int option_type) { int num_options, count; int total_length = 0; DsrT_Packet_Option* dsr_tlv_ptr = OPC_NIL; List* tlv_options_lptr = OPC_NIL; List* temp_lptr = OPC_NIL; /** Removes a specific option from the DSR **/ /** packet and sets its size accordingly **/ /** There should only be one option of that **/ /** type in the DSR packet header **/ FIN (dsr_pkt_support_option_remove (<args>)); /* Get the field index for the options field */ if (fd_options_index == OPC_FIELD_INDEX_INVALID) fd_options_index = op_pk_nfd_name_to_index (dsr_pkptr, "Options"); /* Get the list of options */ op_pk_nfd_get (dsr_pkptr, "Options", &tlv_options_lptr); /* Determine the number of options in the list */ num_options = op_prg_list_size (tlv_options_lptr); for (count = 0; count < num_options; count++) { /* Access each TLV in the list */ dsr_tlv_ptr = (DsrT_Packet_Option*) op_prg_list_access (tlv_options_lptr, count); if (dsr_tlv_ptr->option_type == option_type) { /* Remove the matching option from the */ /* list of options in the packet */ dsr_tlv_ptr = (DsrT_Packet_Option*) op_prg_list_remove (tlv_options_lptr, count); /* Free the memory */ temp_lptr = op_prg_list_create (); op_prg_list_insert (temp_lptr, dsr_tlv_ptr, OPC_LISTPOS_TAIL); dsr_pkt_support_tlv_options_mem_free (temp_lptr); break; } } /* Reset the size of the packet based on the options remaining */ num_options = op_prg_list_size (tlv_options_lptr); for (count = 0; count < num_options; count++) { /* Access each TLV in the list */ /* to determine its size */ dsr_tlv_ptr = (DsrT_Packet_Option*) op_prg_list_access (tlv_options_lptr, count); /* Get the total size of all the options */ total_length += dsr_tlv_ptr->option_length; } /* Set the options in the packet */ op_pk_fd_set (dsr_pkptr, fd_options_index, OPC_FIELD_TYPE_STRUCT, tlv_options_lptr, total_length, dsr_pkt_support_tlv_options_mem_copy, dsr_pkt_support_tlv_options_mem_free, sizeof (List)); FOUT; }/*****************************************************//************* PACKET SUPPORT FUNCTIONS **************//*****************************************************/voiddsr_pkt_support_route_request_hop_insert (Packet* ip_pkptr, InetT_Address node_address) { List* tlv_options_lptr = OPC_NIL; Packet* dsr_pkptr = OPC_NIL; DsrT_Packet_Option* dsr_tlv_ptr = OPC_NIL; DsrT_Route_Request_Option* route_request_ptr = OPC_NIL; int num_hops, count, num_options; int total_length = 0; int address_length; InetT_Address* copy_address_ptr = OPC_NIL; OpT_Packet_Size dsr_pkt_size; /** Inserts the hop address into the list of hops **/ /** traversed by this route request **/ FIN (dsr_pkt_support_route_request_hop_insert (<args>)); /* Get the DSR packet from the IP datagram */ op_pk_nfd_get (ip_pkptr, "data", &dsr_pkptr); /* Get the list of options */ op_pk_nfd_get (dsr_pkptr, "Options", &tlv_options_lptr); /* Get the number of options */ num_options = op_prg_list_size (tlv_options_lptr); for (count = 0; count < num_options; count++) { dsr_tlv_ptr = (DsrT_Packet_Option*) op_prg_list_access (tlv_options_lptr, count); if (dsr_tlv_ptr->option_type == DSRC_ROUTE_REQUEST) break; } /* Get a handle to route request structure */ route_request_ptr = (DsrT_Route_Request_Option*) dsr_tlv_ptr->dsr_option_ptr; /* Set the node address in the hop list */ copy_address_ptr = inet_address_create_dynamic (node_address); op_prg_list_insert (route_request_ptr->route_lptr, copy_address_ptr, OPC_LISTPOS_TAIL); /* Determine the size of the options field */ address_length = (inet_address_family_get (copy_address_ptr) == InetC_Addr_Family_v4 ? IP_V4_ADDRESS_LENGTH : IP_V6_ADDRESS_LENGTH); num_hops = op_prg_list_size (route_request_ptr->route_lptr); dsr_tlv_ptr->option_length = DSR_HEADER_OPTIONS + (num_hops + 1) * address_length; /* Calculate the length of the options field */ for (count = 0; count < num_options; count++) { dsr_tlv_ptr = (DsrT_Packet_Option*) op_prg_list_access (tlv_options_lptr, count); total_length += dsr_tlv_ptr->option_length; } /* Set the options in the packet */ op_pk_fd_set (dsr_pkptr, fd_options_index, OPC_FIELD_TYPE_STRUCT, tlv_options_lptr, total_length, dsr_pkt_support_tlv_options_mem_copy, dsr_pkt_support_tlv_options_mem_free, sizeof (List)); /* Get new dsr packet size */ dsr_pkt_size = op_pk_total_size_get (dsr_pkptr); /* Set the DSR packet in the IP datagram */ op_pk_nfd_set (ip_pkptr, "data", dsr_pkptr); /* Set the bulk size of the IP packet to model */ /* the space occupied by the encapsulated data. */ op_pk_bulk_size_set (ip_pkptr, dsr_pkt_size); FOUT; }InetT_Addressdsr_pkt_support_source_route_hop_obtain (DsrT_Source_Route_Option* source_route_ptr, DsrT_Hop_Type hop_type, InetT_Address src_addr, InetT_Address dest_addr) { InetT_Address* next_hop_address_ptr; int num_hops; int access_number; /** Obtains the current or next hop in the **/ /** source route and decrements the segments **/ /** left in the source route option of the TLV **/ /** if the next hop is accessed **/ FIN (dsr_pkt_support_source_route_hop_obtain (<args>)); /* Total number of hops not including the source */ /* and destination node (only intermediate nodes) */ num_hops = op_prg_list_size (source_route_ptr->route_lptr); if (hop_type == DsrC_Previous_Hop) { /* Get the previous hop node from which */ /* this node received the packet */ access_number = num_hops - source_route_ptr->segments_left - 1; } else if (hop_type == DsrC_Current_Hop) { /* Get the current node interface address */ access_number = num_hops - source_route_ptr->segments_left; } else if (hop_type == DsrC_Next_Hop) { /* Decrement the segments left to visit */ /* if we are accessing the next hop */ source_route_ptr->segments_left--; access_number = num_hops - source_route_ptr->segments_left; } if (access_number < 0) { /* Return the source address */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -