21static void set_option_in_hello(NetSim_PACKET* packet,
26 ptrPIM_HELLO hello = get_PIM_MSG(packet);
29 hello->option = realloc(hello->option, (hello->optCount + 1) *
sizeof* hello->option);
33 hello->option = calloc(1,
sizeof* hello->option);
35 hello->option[hello->optCount] = calloc(1,
sizeof* hello->option[hello->optCount]);
36 hello->option[hello->optCount]->optionValue = opt;
37 hello->option[hello->optCount]->optionLength = len;
38 hello->option[hello->optCount]->optionType = type;
41 packet->pstruNetworkData->dOverhead += len + PIM_HELLO_OPTION_LEN;
42 packet->pstruNetworkData->dPacketSize += len + PIM_HELLO_OPTION_LEN;
45static void* get_option_from_hello(ptrPIM_HELLO hello, UINT16 type)
48 for (i = 0; i < hello->optCount; i++)
50 if (hello->option[i]->optionType == type)
51 return hello->option[i]->optionValue;
56static void add_dr_priority_option(NETSIM_ID d, NetSim_PACKET* packet)
58 ptrOPTION_DRPRIORITY pri = calloc(1,
sizeof* pri);
59 pri->DRPriority = GET_PIM_VAR(d)->DRPriority;
60 set_option_in_hello(packet,
61 PIM_OPTION_DRPRIORITY_TYPE,
62 PIM_OPTION_DRPRIORITY_LEN,
64 print_pim_sm_log(
"Adding DR Priority option. DR Priority = %d", pri->DRPriority);
67static void add_genid_option(NETSIM_ID d, NetSim_PACKET* packet)
69 ptrOPTION_GENERATIONID gen = calloc(1,
sizeof* gen);
70 gen->GenerationId = GET_PIM_VAR(d)->genId;
71 set_option_in_hello(packet,
72 PIM_OPTION_GENERATIONID_TYPE,
73 PIM_OPTION_GENERATIONID_LEN,
75 print_pim_sm_log(
"Adding Generation Id option. Generation Id = %d", gen->GenerationId);
78static void add_lanprunedelay_option(NETSIM_ID d, NetSim_PACKET* packet)
80 ptrOPTION_LANPRUNEDELAY lpd = calloc(1,
sizeof* lpd);
81 lpd->overrideInterval = GET_PIM_VAR(d)->overrideInterval;
82 lpd->propagationDelay = GET_PIM_VAR(d)->propagationDelay;
84 set_option_in_hello(packet,
85 PIM_OPTION_LANPRUNEDELAY_TYPE,
86 PIM_OPTION_LANPRUNEDELAY_LEN,
88 print_pim_sm_log(
"Adding Lan prune delay option.");
91static void add_addresslist_option(NETSIM_ID d, NetSim_PACKET* packet)
93 ptrOPTION_ADDRLIST addrList = calloc(1,
sizeof* addrList);
95 NETSIM_ID c = DEVICE(d)->nNumOfInterface;
99 addrList->SeconadayAddr = calloc(c,
sizeof* addrList->SeconadayAddr);
100 for (i = 0; i < c; i++)
102 addrList->SeconadayAddr[i] = encode_unicast_addr(DEVICE_NWADDRESS(d, i + 1));
103 len += ENCODED_UNICAST_ADDR_LEN;
106 len -= ENCODED_UNICAST_ADDR_LEN;
110 set_option_in_hello(packet,
111 PIM_OPTION_ADDRLIST_TYPE,
114 print_pim_sm_log(
"Adding secondary address list option.");
117static ptrPIM_HELLO alloc_pim_hello()
119 ptrPIM_HELLO hello = (ptrPIM_HELLO)calloc(1,
sizeof* hello);
120 set_pim_hdr(&hello->hdr, PIMMSG_Hello);
125static NetSim_PACKET* create_pim_hello(NETSIM_ID dev,
128 ptrPIM_HELLO hello = alloc_pim_hello();
130 NetSim_PACKET* packet = create_pim_packet(PIMMSG_Hello,
134 DEVICE_NWADDRESS(dev, 1),
137 ALL_PIM_ROUTERS_ADDRESS,
142void send_hello_msg(NETSIM_ID d,
double time)
144 ptrPIM_VAR var = GET_PIM_VAR(d);
145 NetSim_PACKET* packet = create_pim_hello(d, time);
147 add_dr_priority_option(d, packet);
149 add_genid_option(d, packet);
151 add_lanprunedelay_option(d, packet);
153 add_addresslist_option(d, packet);
155 send_pim_msg(d, time, packet);
156 print_pim_sm_log(
"Adding timer event %s at %0.3lf\n",
158 (time + var->helloPeriod) / 1000);
159 pim_add_timeout_event(d, time + var->helloPeriod, EVENT_PIM_SEND_HELLO, NULL);
162bool process_pim_hello_packet()
164 bool isNeighbor =
false;
165 NetSim_PACKET* packet = pstruEventDetails->pPacket;
166 NETSIM_ID d = pstruEventDetails->nDeviceId;
167 NETSIM_ID ifid = pstruEventDetails->nInterfaceId;
168 ptrPIM_HELLO hello = get_PIM_MSG(packet);
170 NETSIM_IPAddress src = packet->pstruNetworkData->szSourceIP;
171 ptrPIM_NEIGHBOR neigh = find_neighbor(d, src);
172 isNeighbor = neigh ? true :
false;
176 print_pim_sm_log(
"New neighbor %s is found on interface %d",
178 neigh = create_and_add_neighbor(d, ifid, src);
181 ptrOPTION_GENERATIONID gen = get_option_from_hello(hello, PIM_OPTION_GENERATIONID_TYPE);
183 neigh->gen_id = gen->GenerationId;
185 ptrOPTION_DRPRIORITY pri = get_option_from_hello(hello, PIM_OPTION_DRPRIORITY_TYPE);
188 neigh->dr_priority = pri->DRPriority;
189 neigh->dr_priority_present =
true;
193 ptrOPTION_HOLDTIME hold = get_option_from_hello(hello, PIM_OPTION_HOLDTIME_TYPE);
195 t = hold->holdTime*MILLISECOND;
197 t = GET_PIM_VAR(d)->helloPeriod*3.5;
198 if (!neigh->isTimeoutAdded)
200 print_pim_sm_log(
"Adding neighbor timeout event at %0.3lf",
201 (pstruEventDetails->dEventTime + t) / 1000);
202 pim_add_timeout_event(d,
203 pstruEventDetails->dEventTime + t,
204 EVENT_PIM_NEIGHBOR_TIMEOUT,
207 neigh->timeout = pstruEventDetails->dEventTime + t;
208 neigh->isTimeoutAdded =
true;
209 print_pim_sm_log(
"Neighbor details updated as DR_priority=%d, GenId=%d, Timeout=%0.3lf",
212 neigh->timeout / 1000);
216 ptrOPTION_LANPRUNEDELAY lpd = get_option_from_hello(hello, PIM_OPTION_LANPRUNEDELAY_TYPE);
219 neigh->lan_prune_delay_present =
true;
220 neigh->override_interval = lpd->overrideInterval;
221 neigh->propagation_delay = lpd->propagationDelay;
222 neigh->tracking_support = lpd->T;
226 neigh->lan_prune_delay_present =
false;
229 ptrOPTION_ADDRLIST addrlist = get_option_from_hello(hello, PIM_OPTION_ADDRLIST_TYPE);
232 neigh->secondary_address_count = addrlist->c;
236 free(neigh->secondary_address_list);
237 neigh->secondary_address_list = calloc(addrlist->c,
sizeof* neigh->secondary_address_list);
238 for (i = 0, k = 0; k < addrlist->c; i++,k++)
240 if (!IP_COMPARE(addrlist->SeconadayAddr[i]->unicastAddr, src))
245 neigh->secondary_address_list[k] = addrlist->SeconadayAddr[i]->unicastAddr;
250 neigh->secondary_address_count = 0;
251 free(neigh->secondary_address_list);
252 neigh->secondary_address_list = NULL;