2 * EIGRP General Sending and Receiving of EIGRP Packets.
3 * Copyright (C) 2013-2014
11 * This file is part of GNU Zebra.
13 * GNU Zebra is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2, or (at your option) any
18 * GNU Zebra is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; see the file COPYING; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
38 #include "sockunion.h"
46 #include "eigrpd/eigrp_structs.h"
47 #include "eigrpd/eigrpd.h"
48 #include "eigrpd/eigrp_interface.h"
49 #include "eigrpd/eigrp_neighbor.h"
50 #include "eigrpd/eigrp_packet.h"
51 #include "eigrpd/eigrp_zebra.h"
52 #include "eigrpd/eigrp_vty.h"
53 #include "eigrpd/eigrp_dump.h"
54 #include "eigrpd/eigrp_network.h"
55 #include "eigrpd/eigrp_topology.h"
56 #include "eigrpd/eigrp_fsm.h"
57 #include "eigrpd/eigrp_memory.h"
59 /* Packet Type String. */
60 const struct message eigrp_packet_type_str
[] =
62 { EIGRP_OPC_UPDATE
, "Update"},
63 { EIGRP_OPC_REQUEST
, "Request"},
64 { EIGRP_OPC_QUERY
, "Query"},
65 { EIGRP_OPC_REPLY
, "Reply"},
66 { EIGRP_OPC_HELLO
, "Hello"},
67 { EIGRP_OPC_IPXSAP
, "IPX-SAP"},
68 { EIGRP_OPC_PROBE
, "Probe"},
69 { EIGRP_OPC_ACK
, "Ack"},
70 { EIGRP_OPC_SIAQUERY
, "SIAQuery"},
71 { EIGRP_OPC_SIAREPLY
, "SIAReply"},
74 const size_t eigrp_packet_type_str_max
= sizeof(eigrp_packet_type_str
) /
75 sizeof(eigrp_packet_type_str
[0]);
77 static unsigned char zeropad
[16] = {0};
79 /* Forward function reference*/
80 static struct stream
* eigrp_recv_packet (int, struct interface
**, struct stream
*);
81 static int eigrp_verify_header (struct stream
*, struct eigrp_interface
*, struct ip
*,
82 struct eigrp_header
*);
83 static int eigrp_check_network_mask (struct eigrp_interface
*, struct in_addr
);
85 static int eigrp_retrans_count_exceeded(struct eigrp_packet
*ep
, struct eigrp_neighbor
*nbr
)
91 eigrp_make_md5_digest (struct eigrp_interface
*ei
, struct stream
*s
, u_char flags
)
93 struct key
*key
= NULL
;
94 struct keychain
*keychain
;
96 unsigned char digest
[EIGRP_AUTH_TYPE_MD5_LEN
];
99 size_t backup_get
, backup_end
;
100 struct TLV_MD5_Authentication_Type
*auth_TLV
;
103 backup_end
= s
->endp
;
104 backup_get
= s
->getp
;
106 auth_TLV
= eigrp_authTLV_MD5_new();
108 stream_set_getp(s
,EIGRP_HEADER_LEN
);
109 stream_get(auth_TLV
,s
,EIGRP_AUTH_MD5_TLV_SIZE
);
110 stream_set_getp(s
, backup_get
);
112 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
114 key
= key_lookup_for_send(keychain
);
117 eigrp_authTLV_MD5_free(auth_TLV
);
118 return EIGRP_AUTH_TYPE_NONE
;
121 memset(&ctx
, 0, sizeof(ctx
));
124 /* Generate a digest. Each situation needs different handling */
125 if(flags
& EIGRP_AUTH_BASIC_HELLO_FLAG
)
127 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
128 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
129 if(strlen(key
->string
) < 16)
130 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
132 else if(flags
& EIGRP_AUTH_UPDATE_INIT_FLAG
)
134 MD5Update(&ctx
, ibuf
, EIGRP_MD5_UPDATE_INIT_COMPUTE
);
136 else if(flags
& EIGRP_AUTH_UPDATE_FLAG
)
138 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
139 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
140 if(strlen(key
->string
) < 16)
141 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
142 if(backup_end
> (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
))
144 MD5Update(&ctx
, ibuf
+ (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
),
145 backup_end
- 20 - (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
));
149 MD5Final(digest
, &ctx
);
151 /* Append md5 digest to the end of the stream. */
152 memcpy(auth_TLV
->digest
,digest
,EIGRP_AUTH_TYPE_MD5_LEN
);
154 stream_set_endp(s
,EIGRP_HEADER_LEN
);
155 stream_put(s
,auth_TLV
,EIGRP_AUTH_MD5_TLV_SIZE
);
156 stream_set_endp(s
, backup_end
);
158 eigrp_authTLV_MD5_free(auth_TLV
);
159 return EIGRP_AUTH_TYPE_MD5_LEN
;
163 eigrp_check_md5_digest (struct stream
*s
,
164 struct TLV_MD5_Authentication_Type
*authTLV
,struct eigrp_neighbor
*nbr
, u_char flags
)
167 unsigned char digest
[EIGRP_AUTH_TYPE_MD5_LEN
];
168 struct key
*key
= NULL
;
169 struct keychain
*keychain
;
172 struct TLV_MD5_Authentication_Type
*auth_TLV
;
173 struct eigrp_header
*eigrph
;
175 if (nbr
&& ntohl(nbr
->crypt_seqnum
) > ntohl(authTLV
->key_sequence
))
177 zlog_warn ("interface %s: eigrp_check_md5 bad sequence %d (expect %d)",
179 ntohl(authTLV
->key_sequence
),
180 ntohl(nbr
->crypt_seqnum
));
184 eigrph
= (struct eigrp_header
*) s
->data
;
185 eigrph
->checksum
= 0;
187 auth_TLV
=(struct TLV_MD5_Authentication_Type
*) (s
->data
+ EIGRP_HEADER_LEN
);
188 memset(auth_TLV
->digest
, 0, sizeof(auth_TLV
->digest
));
191 backup_end
= s
->endp
;
193 keychain
= keychain_lookup(IF_DEF_PARAMS (nbr
->ei
->ifp
)->auth_keychain
);
195 key
= key_lookup_for_send(keychain
);
197 memset(&ctx
, 0, sizeof(ctx
));
200 /* Generate a digest. Each situation needs different handling */
201 if(flags
& EIGRP_AUTH_BASIC_HELLO_FLAG
)
203 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
204 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
205 if(strlen(key
->string
) < 16)
206 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
208 else if(flags
& EIGRP_AUTH_UPDATE_INIT_FLAG
)
210 MD5Update(&ctx
, ibuf
, EIGRP_MD5_UPDATE_INIT_COMPUTE
);
212 else if(flags
& EIGRP_AUTH_UPDATE_FLAG
)
214 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
215 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
216 if(strlen(key
->string
) < 16)
217 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
218 if(backup_end
> (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
))
220 MD5Update(&ctx
, ibuf
+ (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
),
221 backup_end
- 20 - (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
));
225 MD5Final(digest
, &ctx
);
227 /* compare the two */
228 if (memcmp (authTLV
->digest
, digest
, EIGRP_AUTH_TYPE_MD5_LEN
) == 0)
230 zlog_debug("VSETKO OK");
234 zlog_warn ("interface %s: eigrp_check_md5 checksum mismatch",
239 /* save neighbor's crypt_seqnum */
240 nbr
->crypt_seqnum
= authTLV
->key_sequence
;
246 eigrp_make_sha256_digest (struct eigrp_interface
*ei
, struct stream
*s
, u_char flags
)
248 struct key
*key
= NULL
;
249 struct keychain
*keychain
;
252 unsigned char digest
[EIGRP_AUTH_TYPE_SHA256_LEN
];
253 unsigned char buffer
[1 + PLAINTEXT_LENGTH
+ 45 + 1] = { 0 };
256 size_t backup_get
, backup_end
;
257 struct TLV_SHA256_Authentication_Type
*auth_TLV
;
260 backup_end
= s
->endp
;
261 backup_get
= s
->getp
;
263 auth_TLV
= eigrp_authTLV_SHA256_new ();
265 stream_set_getp(s
,EIGRP_HEADER_LEN
);
266 stream_get(auth_TLV
,s
,EIGRP_AUTH_SHA256_TLV_SIZE
);
267 stream_set_getp(s
, backup_get
);
269 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
271 key
= key_lookup_for_send(keychain
);
273 // saved_len[index] = strnzcpyn(saved_key[index], key,
274 // PLAINTEXT_LENGTH + 1);
276 source_ip
= calloc(16, sizeof(char));
277 inet_ntop(AF_INET
, &ei
->address
->u
.prefix4
, source_ip
, 16);
279 memset(&ctx
, 0, sizeof(ctx
));
281 memcpy(buffer
+ 1, key
, strlen (key
->string
));
282 memcpy(buffer
+ 1 + strlen(key
->string
), source_ip
, strlen(source_ip
));
283 HMAC__SHA256_Init(&ctx
, buffer
, 1 + strlen (key
->string
) + strlen(source_ip
));
284 HMAC__SHA256_Update(&ctx
, ibuf
, strlen(ibuf
));
285 HMAC__SHA256_Final(digest
, &ctx
);
288 /* Put hmac-sha256 digest to it's place */
289 memcpy(auth_TLV
->digest
,digest
,EIGRP_AUTH_TYPE_SHA256_LEN
);
291 stream_set_endp(s
,EIGRP_HEADER_LEN
);
292 stream_put(s
,auth_TLV
,EIGRP_AUTH_SHA256_TLV_SIZE
);
293 stream_set_endp(s
, backup_end
);
295 eigrp_authTLV_SHA256_free(auth_TLV
);
298 return EIGRP_AUTH_TYPE_SHA256_LEN
;
302 eigrp_check_sha256_digest (struct stream
*s
,
303 struct TLV_SHA256_Authentication_Type
*authTLV
,
304 struct eigrp_neighbor
*nbr
, u_char flags
)
312 * This routing dumps the contents of the IP packet either received or
316 eigrp_packet_dump (struct stream
*s
)
323 eigrp_write (struct thread
*thread
)
325 struct eigrp
*eigrp
= THREAD_ARG(thread
);
326 struct eigrp_header
*eigrph
;
327 struct eigrp_interface
*ei
;
328 struct eigrp_packet
*ep
;
329 struct sockaddr_in sa_dst
;
333 u_int16_t opcode
= 0;
337 struct listnode
*node
;
338 #ifdef WANT_EIGRP_WRITE_FRAGMENT
339 static u_int16_t ipid
= 0;
340 #endif /* WANT_EIGRP_WRITE_FRAGMENT */
341 #define EIGRP_WRITE_IPHL_SHIFT 2
343 eigrp
->t_write
= NULL
;
345 node
= listhead(eigrp
->oi_write_q
);
347 ei
= listgetdata(node
);
350 #ifdef WANT_EIGRP_WRITE_FRAGMENT
351 /* seed ipid static with low order bits of time */
353 ipid
= (time(NULL
) & 0xffff);
354 #endif /* WANT_EIGRP_WRITE_FRAGMENT */
356 /* Get one packet from queue. */
357 ep
= eigrp_fifo_head(ei
->obuf
);
359 assert(ep
->length
>= EIGRP_HEADER_LEN
);
361 if (ep
->dst
.s_addr
== htonl(EIGRP_MULTICAST_ADDRESS
))
362 eigrp_if_ipmulticast(eigrp
, ei
->address
, ei
->ifp
->ifindex
);
364 memset(&iph
, 0, sizeof(struct ip
));
365 memset(&sa_dst
, 0, sizeof(sa_dst
));
367 sa_dst
.sin_family
= AF_INET
;
368 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
369 sa_dst
.sin_len
= sizeof(sa_dst
);
370 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
371 sa_dst
.sin_addr
= ep
->dst
;
372 sa_dst
.sin_port
= htons(0);
374 /* Set DONTROUTE flag if dst is unicast. */
375 if (!IN_MULTICAST(htonl(ep
->dst
.s_addr
)))
376 flags
= MSG_DONTROUTE
;
378 iph
.ip_hl
= sizeof(struct ip
) >> EIGRP_WRITE_IPHL_SHIFT
;
379 /* it'd be very strange for header to not be 4byte-word aligned but.. */
380 if (sizeof(struct ip
) > (unsigned int)(iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
))
381 iph
.ip_hl
++; /* we presume sizeof struct ip cant overflow ip_hl.. */
383 iph
.ip_v
= IPVERSION
;
384 iph
.ip_tos
= IPTOS_PREC_INTERNETCONTROL
;
385 iph
.ip_len
= (iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
) + ep
->length
;
387 #if defined (__DragonFly__)
389 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
391 iph
.ip_len
= htons(iph
.ip_len
);
395 iph
.ip_ttl
= EIGRP_IP_TTL
;
396 iph
.ip_p
= IPPROTO_EIGRPIGP
;
398 iph
.ip_src
.s_addr
= ei
->address
->u
.prefix4
.s_addr
;
399 iph
.ip_dst
.s_addr
= ep
->dst
.s_addr
;
401 memset(&msg
, 0, sizeof(msg
));
402 msg
.msg_name
= (caddr_t
) &sa_dst
;
403 msg
.msg_namelen
= sizeof(sa_dst
);
407 iov
[0].iov_base
= (char*)&iph
;
408 iov
[0].iov_len
= iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
;
409 iov
[1].iov_base
= STREAM_PNT(ep
->s
);
410 iov
[1].iov_len
= ep
->length
;
412 /* send final fragment (could be first) */
413 sockopt_iphdrincl_swab_htosys(&iph
);
414 ret
= sendmsg(eigrp
->fd
, &msg
, flags
);
415 sockopt_iphdrincl_swab_systoh(&iph
);
417 if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND
))
419 eigrph
= (struct eigrp_header
*) STREAM_DATA(ep
->s
);
420 opcode
= eigrph
->opcode
;
421 zlog_debug("Sending [%s] to [%s] via [%s] ret [%d].",
422 LOOKUP(eigrp_packet_type_str
, opcode
), inet_ntoa(ep
->dst
),
427 zlog_warn("*** sendmsg in eigrp_write failed to %s, "
428 "id %d, off %d, len %d, interface %s, mtu %u: %s",
429 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
, iph
.ip_len
, ei
->ifp
->name
,
430 ei
->ifp
->mtu
, safe_strerror(errno
));
432 /* Show debug sending packet. */
433 if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND
) && (IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL
)))
435 zlog_debug("-----------------------------------------------------");
436 eigrp_ip_header_dump(&iph
);
437 stream_set_getp(ep
->s
, 0);
438 eigrp_packet_dump(ep
->s
);
439 zlog_debug("-----------------------------------------------------");
442 /* Now delete packet from queue. */
443 eigrp_packet_delete(ei
);
445 if (eigrp_fifo_head(ei
->obuf
) == NULL
)
448 list_delete_node(eigrp
->oi_write_q
, node
);
451 /* If packets still remain in queue, call write thread. */
452 if (!list_isempty(eigrp
->oi_write_q
)) {
453 eigrp
->t_write
= NULL
;
454 thread_add_write(master
, eigrp_write
, eigrp
, eigrp
->fd
, &eigrp
->t_write
);
460 /* Starting point of packet process function. */
462 eigrp_read (struct thread
*thread
)
467 struct eigrp_interface
*ei
;
469 struct eigrp_header
*eigrph
;
470 struct interface
*ifp
;
471 struct eigrp_neighbor
*nbr
;
473 u_int16_t opcode
= 0;
474 u_int16_t length
= 0;
476 /* first of all get interface pointer. */
477 eigrp
= THREAD_ARG(thread
);
479 /* prepare for next packet. */
480 eigrp
->t_read
= NULL
;
481 thread_add_read(master
, eigrp_read
, eigrp
, eigrp
->fd
, &eigrp
->t_read
);
483 stream_reset(eigrp
->ibuf
);
484 if (!(ibuf
= eigrp_recv_packet(eigrp
->fd
, &ifp
, eigrp
->ibuf
)))
486 /* This raw packet is known to be at least as big as its IP header. */
490 /* Note that there should not be alignment problems with this assignment
491 because this is at the beginning of the stream data buffer. */
492 iph
= (struct ip
*)STREAM_DATA(ibuf
);
494 //Substract IPv4 header size from EIGRP Packet itself
496 length
= (iph
->ip_len
) - 20U;
499 /* IP Header dump. */
500 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
) && IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL
))
501 eigrp_ip_header_dump(iph
);
503 /* Note that sockopt_iphdrincl_swab_systoh was called in eigrp_recv_packet. */
507 /* Handle cases where the platform does not support retrieving the ifindex,
508 and also platforms (such as Solaris 8) that claim to support ifindex
509 retrieval but do not. */
510 c
= if_lookup_address((void *)&iph
->ip_src
, AF_INET
, VRF_DEFAULT
);
518 /* associate packet with eigrp interface */
519 ei
= eigrp_if_lookup_recv_if(eigrp
, iph
->ip_src
, ifp
);
521 /* eigrp_verify_header() relies on a valid "ei" and thus can be called only
522 after the checks below are passed. These checks in turn access the
523 fields of unverified "eigrph" structure for their own purposes and
524 must remain very accurate in doing this.
529 /* Self-originated packet should be discarded silently. */
530 if (eigrp_if_lookup_by_local_addr(eigrp
, NULL
, iph
->ip_src
) ||
531 (IPV4_ADDR_SAME(&iph
->ip_src
.s_addr
, &ei
->address
->u
.prefix4
)))
533 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
534 zlog_debug("eigrp_read[%s]: Dropping self-originated packet",
535 inet_ntoa(iph
->ip_src
));
539 /* Advance from IP header to EIGRP header (iph->ip_hl has been verified
540 by eigrp_recv_packet() to be correct). */
542 stream_forward_getp(ibuf
, (iph
->ip_hl
* 4));
543 eigrph
= (struct eigrp_header
*) STREAM_PNT(ibuf
);
545 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
) && IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL
))
546 eigrp_header_dump(eigrph
);
548 // if (MSG_OK != eigrp_packet_examin(eigrph, stream_get_endp(ibuf) - stream_get_getp(ibuf)))
551 /* Now it is safe to access all fields of EIGRP packet header. */
552 /* associate packet with eigrp interface */
553 ei
= eigrp_if_lookup_recv_if(eigrp
, iph
->ip_src
, ifp
);
555 /* eigrp_verify_header() relies on a valid "ei" and thus can be called only
556 after the checks below are passed. These checks in turn access the
557 fields of unverified "eigrph" structure for their own purposes and
558 must remain very accurate in doing this.
563 /* If incoming interface is passive one, ignore it. */
564 if (ei
&& EIGRP_IF_PASSIVE_STATUS(ei
) == EIGRP_IF_PASSIVE
)
566 char buf
[3][INET_ADDRSTRLEN
];
568 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
569 zlog_debug("ignoring packet from router %s sent to %s, "
570 "received on a passive interface, %s",
571 inet_ntop(AF_INET
, &eigrph
->vrid
, buf
[0], sizeof(buf
[0])),
572 inet_ntop(AF_INET
, &iph
->ip_dst
, buf
[1], sizeof(buf
[1])),
573 inet_ntop(AF_INET
, &ei
->address
->u
.prefix4
,
574 buf
[2], sizeof(buf
[2])));
576 if (iph
->ip_dst
.s_addr
== htonl(EIGRP_MULTICAST_ADDRESS
))
578 /* Try to fix multicast membership.
579 * Some OS:es may have problems in this area,
580 * make sure it is removed.
582 EI_MEMBER_JOINED(ei
, MEMBER_ALLROUTERS
);
583 eigrp_if_set_multicast(ei
);
588 /* else it must be a local eigrp interface, check it was received on
591 else if (ei
->ifp
!= ifp
)
593 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
594 zlog_warn("Packet from [%s] received on wrong link %s",
595 inet_ntoa(iph
->ip_src
), ifp
->name
);
599 /* Verify more EIGRP header fields. */
600 ret
= eigrp_verify_header(ibuf
, ei
, iph
, eigrph
);
603 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
604 zlog_debug("eigrp_read[%s]: Header check failed, dropping.",
605 inet_ntoa(iph
->ip_src
));
609 /* calcualte the eigrp packet length, and move the pounter to the
610 start of the eigrp TLVs */
611 opcode
= eigrph
->opcode
;
613 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
614 zlog_debug("Received [%s] length [%u] via [%s] src [%s] dst [%s]",
615 LOOKUP(eigrp_packet_type_str
, opcode
), length
,
616 IF_NAME(ei
), inet_ntoa(iph
->ip_src
), inet_ntoa(iph
->ip_dst
));
618 /* Read rest of the packet and call each sort of packet routine. */
619 stream_forward_getp(ibuf
, EIGRP_HEADER_LEN
);
621 /* New testing block of code for handling Acks */
622 if (ntohl(eigrph
->ack
) != 0)
624 nbr
= eigrp_nbr_get(ei
, eigrph
, iph
);
626 /* neighbor must be valid, eigrp_nbr_get creates if none existed */
629 struct eigrp_packet
*ep
;
631 ep
= eigrp_fifo_tail(nbr
->retrans_queue
);
634 if (ntohl(eigrph
->ack
) == ep
->sequence_number
)
636 if((nbr
->state
== EIGRP_NEIGHBOR_PENDING
) &&
637 (ntohl(eigrph
->ack
) == nbr
->init_sequence_number
))
639 eigrp_nbr_state_set(nbr
, EIGRP_NEIGHBOR_UP
);
640 zlog_info("Neighbor adjacency became full");
641 nbr
->init_sequence_number
= 0;
642 nbr
->recv_sequence_number
= ntohl(eigrph
->sequence
);
643 eigrp_update_send_EOT(nbr
);
645 ep
= eigrp_fifo_pop_tail(nbr
->retrans_queue
);
646 eigrp_packet_free(ep
);
647 if (nbr
->retrans_queue
->count
> 0)
649 eigrp_send_packet_reliably(nbr
);
653 ep
= eigrp_fifo_tail(nbr
->multicast_queue
);
656 if (ntohl(eigrph
->ack
) == ep
->sequence_number
)
658 ep
= eigrp_fifo_pop_tail(nbr
->multicast_queue
);
659 eigrp_packet_free(ep
);
660 if (nbr
->multicast_queue
->count
> 0)
662 eigrp_send_packet_reliably(nbr
);
671 case EIGRP_OPC_HELLO
:
672 eigrp_hello_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
674 case EIGRP_OPC_PROBE
:
675 // eigrp_probe_receive(eigrp, iph, eigrph, ibuf, ei, length);
677 case EIGRP_OPC_QUERY
:
678 eigrp_query_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
680 case EIGRP_OPC_REPLY
:
681 eigrp_reply_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
683 case EIGRP_OPC_REQUEST
:
684 // eigrp_request_receive(eigrp, iph, eigrph, ibuf, ei, length);
686 case EIGRP_OPC_SIAQUERY
:
687 eigrp_query_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
689 case EIGRP_OPC_SIAREPLY
:
690 eigrp_reply_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
692 case EIGRP_OPC_UPDATE
:
693 eigrp_update_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
696 zlog_warn("interface %s: EIGRP packet header type %d unsupported",
697 IF_NAME(ei
), opcode
);
704 static struct stream
*
705 eigrp_recv_packet (int fd
, struct interface
**ifp
, struct stream
*ibuf
)
710 unsigned int ifindex
= 0;
712 /* Header and data both require alignment. */
713 char buff
[CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
716 memset(&msgh
, 0, sizeof(struct msghdr
));
719 msgh
.msg_control
= (caddr_t
) buff
;
720 msgh
.msg_controllen
= sizeof(buff
);
722 ret
= stream_recvmsg(ibuf
, fd
, &msgh
, 0, (EIGRP_PACKET_MAX_LEN
+ 1));
725 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno
));
728 if ((unsigned int) ret
< sizeof(iph
)) /* ret must be > 0 now */
730 zlog_warn("eigrp_recv_packet: discarding runt packet of length %d "
731 "(ip header size is %u)", ret
, (u_int
) sizeof(iph
));
735 /* Note that there should not be alignment problems with this assignment
736 because this is at the beginning of the stream data buffer. */
737 iph
= (struct ip
*) STREAM_DATA(ibuf
);
738 sockopt_iphdrincl_swab_systoh(iph
);
740 ip_len
= iph
->ip_len
;
742 #if !defined (GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
744 * Kernel network code touches incoming IP header parameters,
745 * before protocol specific processing.
747 * 1) Convert byteorder to host representation.
748 * --> ip_len, ip_id, ip_off
750 * 2) Adjust ip_len to strip IP header size!
751 * --> If user process receives entire IP packet via RAW
752 * socket, it must consider adding IP header size to
753 * the "ip_len" field of "ip" structure.
755 * For more details, see <netinet/ip_input.c>.
757 ip_len
= ip_len
+ (iph
->ip_hl
<< 2);
760 #if defined (__DragonFly__)
762 * in DragonFly's raw socket, ip_len/ip_off are read
763 * in network byte order.
764 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
766 ip_len
= ntohs(iph
->ip_len
) + (iph
->ip_hl
<< 2);
769 ifindex
= getsockopt_ifindex(AF_INET
, &msgh
);
771 *ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
775 zlog_warn("eigrp_recv_packet read length mismatch: ip_len is %d, "
776 "but recvmsg returned %d", ip_len
, ret
);
784 eigrp_fifo_new (void)
786 struct eigrp_fifo
*new;
788 new = XCALLOC(MTYPE_EIGRP_FIFO
, sizeof(struct eigrp_fifo
));
792 /* Free eigrp packet fifo. */
794 eigrp_fifo_free (struct eigrp_fifo
*fifo
)
796 struct eigrp_packet
*ep
;
797 struct eigrp_packet
*next
;
799 for (ep
= fifo
->head
; ep
; ep
= next
)
802 eigrp_packet_free(ep
);
804 fifo
->head
= fifo
->tail
= NULL
;
807 XFREE(MTYPE_EIGRP_FIFO
, fifo
);
810 /* Free eigrp fifo entries without destroying fifo itself*/
812 eigrp_fifo_reset (struct eigrp_fifo
*fifo
)
814 struct eigrp_packet
*ep
;
815 struct eigrp_packet
*next
;
817 for (ep
= fifo
->head
; ep
; ep
= next
)
820 eigrp_packet_free(ep
);
822 fifo
->head
= fifo
->tail
= NULL
;
826 struct eigrp_packet
*
827 eigrp_packet_new (size_t size
)
829 struct eigrp_packet
*new;
831 new = XCALLOC(MTYPE_EIGRP_PACKET
, sizeof(struct eigrp_packet
));
832 new->s
= stream_new(size
);
833 new->retrans_counter
= 0;
839 eigrp_send_packet_reliably (struct eigrp_neighbor
*nbr
)
841 struct eigrp_packet
*ep
;
843 ep
= eigrp_fifo_tail(nbr
->retrans_queue
);
847 struct eigrp_packet
*duplicate
;
848 duplicate
= eigrp_packet_duplicate(ep
, nbr
);
849 /* Add packet to the top of the interface output queue*/
850 eigrp_fifo_push_head(nbr
->ei
->obuf
, duplicate
);
852 /*Start retransmission timer*/
853 thread_add_timer(master
, eigrp_unack_packet_retrans
, nbr
,
854 EIGRP_PACKET_RETRANS_TIME
, &ep
->t_retrans_timer
);
856 /*Increment sequence number counter*/
857 nbr
->ei
->eigrp
->sequence_number
++;
859 /* Hook thread to write packet. */
860 if (nbr
->ei
->on_write_q
== 0)
862 listnode_add(nbr
->ei
->eigrp
->oi_write_q
, nbr
->ei
);
863 nbr
->ei
->on_write_q
= 1;
865 thread_add_write(master
, eigrp_write
, nbr
->ei
->eigrp
, nbr
->ei
->eigrp
->fd
,
866 &nbr
->ei
->eigrp
->t_write
);
870 /* Calculate EIGRP checksum */
872 eigrp_packet_checksum (struct eigrp_interface
*ei
, struct stream
*s
,
875 struct eigrp_header
*eigrph
;
877 eigrph
= (struct eigrp_header
*) STREAM_DATA(s
);
879 /* Calculate checksum. */
880 eigrph
->checksum
= in_cksum(eigrph
, length
);
883 /* Make EIGRP header. */
885 eigrp_packet_header_init (int type
, struct eigrp_interface
*ei
, struct stream
*s
,
886 u_int32_t flags
, u_int32_t sequence
, u_int32_t ack
)
888 struct eigrp_header
*eigrph
;
890 eigrph
= (struct eigrp_header
*) STREAM_DATA(s
);
892 eigrph
->version
= (u_char
) EIGRP_HEADER_VERSION
;
893 eigrph
->opcode
= (u_char
) type
;
894 eigrph
->checksum
= 0;
896 eigrph
->vrid
= htons(ei
->eigrp
->vrid
);
897 eigrph
->ASNumber
= htons(ei
->eigrp
->AS
);
898 eigrph
->ack
= htonl(ack
);
899 eigrph
->sequence
= htonl(sequence
);
900 // if(flags == EIGRP_INIT_FLAG)
901 // eigrph->sequence = htonl(3);
902 eigrph
->flags
= htonl(flags
);
904 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
905 zlog_debug("Packet Header Init Seq [%u] Ack [%u]",
906 htonl(eigrph
->sequence
), htonl(eigrph
->ack
));
908 stream_forward_endp(s
, EIGRP_HEADER_LEN
);
911 /* Add new packet to head of fifo. */
913 eigrp_fifo_push_head (struct eigrp_fifo
*fifo
, struct eigrp_packet
*ep
)
915 ep
->next
= fifo
->head
;
918 if (fifo
->tail
== NULL
)
921 if (fifo
->count
!= 0)
922 fifo
->head
->previous
= ep
;
929 /* Return first fifo entry. */
930 struct eigrp_packet
*
931 eigrp_fifo_head (struct eigrp_fifo
*fifo
)
936 /* Return last fifo entry. */
937 struct eigrp_packet
*
938 eigrp_fifo_tail (struct eigrp_fifo
*fifo
)
944 eigrp_packet_delete (struct eigrp_interface
*ei
)
946 struct eigrp_packet
*ep
;
948 ep
= eigrp_fifo_pop (ei
->obuf
);
951 eigrp_packet_free(ep
);
954 /* Delete first packet from fifo. */
955 struct eigrp_packet
*
956 eigrp_fifo_pop (struct eigrp_fifo
*fifo
)
958 struct eigrp_packet
*ep
;
964 fifo
->head
= ep
->next
;
966 if (fifo
->head
== NULL
)
969 fifo
->head
->previous
= NULL
;
978 eigrp_packet_free (struct eigrp_packet
*ep
)
983 THREAD_OFF(ep
->t_retrans_timer
);
985 XFREE(MTYPE_EIGRP_PACKET
, ep
);
990 /* EIGRP Header verification. */
992 eigrp_verify_header (struct stream
*ibuf
, struct eigrp_interface
*ei
,
993 struct ip
*iph
, struct eigrp_header
*eigrph
)
995 /* Check network mask, Silently discarded. */
996 if (!eigrp_check_network_mask(ei
, iph
->ip_src
))
998 zlog_warn("interface %s: eigrp_read network address is not same [%s]",
999 IF_NAME(ei
), inet_ntoa(iph
->ip_src
));
1003 // /* Check authentication. The function handles logging actions, where required. */
1004 // if (! eigrp_check_auth(ei, eigrph))
1010 /* Unbound socket will accept any Raw IP packets if proto is matched.
1011 To prevent it, compare src IP address and i/f address with masking
1012 i/f network mask. */
1014 eigrp_check_network_mask (struct eigrp_interface
*ei
, struct in_addr ip_src
)
1016 struct in_addr mask
, me
, him
;
1018 if (ei
->type
== EIGRP_IFTYPE_POINTOPOINT
)
1021 masklen2ip(ei
->address
->prefixlen
, &mask
);
1023 me
.s_addr
= ei
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
1024 him
.s_addr
= ip_src
.s_addr
& mask
.s_addr
;
1026 if (IPV4_ADDR_SAME(&me
, &him
))
1033 eigrp_unack_packet_retrans (struct thread
*thread
)
1035 struct eigrp_neighbor
*nbr
;
1036 nbr
= (struct eigrp_neighbor
*) THREAD_ARG(thread
);
1038 struct eigrp_packet
*ep
;
1039 ep
= eigrp_fifo_tail(nbr
->retrans_queue
);
1043 struct eigrp_packet
*duplicate
;
1044 duplicate
= eigrp_packet_duplicate(ep
, nbr
);
1046 /* Add packet to the top of the interface output queue*/
1047 eigrp_fifo_push_head(nbr
->ei
->obuf
, duplicate
);
1049 ep
->retrans_counter
++;
1050 if(ep
->retrans_counter
== EIGRP_PACKET_RETRANS_MAX
)
1051 return eigrp_retrans_count_exceeded(ep
, nbr
);
1053 /*Start retransmission timer*/
1054 ep
->t_retrans_timer
= NULL
;
1055 thread_add_timer(master
, eigrp_unack_packet_retrans
, nbr
, EIGRP_PACKET_RETRANS_TIME
,
1056 &ep
->t_retrans_timer
);
1058 /* Hook thread to write packet. */
1059 if (nbr
->ei
->on_write_q
== 0)
1061 listnode_add(nbr
->ei
->eigrp
->oi_write_q
, nbr
->ei
);
1062 nbr
->ei
->on_write_q
= 1;
1064 thread_add_write(master
, eigrp_write
, nbr
->ei
->eigrp
, nbr
->ei
->eigrp
->fd
,
1065 &nbr
->ei
->eigrp
->t_write
);
1072 eigrp_unack_multicast_packet_retrans (struct thread
*thread
)
1074 struct eigrp_neighbor
*nbr
;
1075 nbr
= (struct eigrp_neighbor
*) THREAD_ARG(thread
);
1077 struct eigrp_packet
*ep
;
1078 ep
= eigrp_fifo_tail(nbr
->multicast_queue
);
1082 struct eigrp_packet
*duplicate
;
1083 duplicate
= eigrp_packet_duplicate(ep
, nbr
);
1084 /* Add packet to the top of the interface output queue*/
1085 eigrp_fifo_push_head(nbr
->ei
->obuf
, duplicate
);
1087 ep
->retrans_counter
++;
1088 if(ep
->retrans_counter
== EIGRP_PACKET_RETRANS_MAX
)
1089 return eigrp_retrans_count_exceeded(ep
, nbr
);
1091 /*Start retransmission timer*/
1092 ep
->t_retrans_timer
= NULL
;
1093 thread_add_timer(master
, eigrp_unack_multicast_packet_retrans
, nbr
, EIGRP_PACKET_RETRANS_TIME
,
1094 &ep
->t_retrans_timer
);
1096 /* Hook thread to write packet. */
1097 if (nbr
->ei
->on_write_q
== 0)
1099 listnode_add(nbr
->ei
->eigrp
->oi_write_q
, nbr
->ei
);
1100 nbr
->ei
->on_write_q
= 1;
1102 thread_add_write(master
, eigrp_write
, nbr
->ei
->eigrp
, nbr
->ei
->eigrp
->fd
,
1103 &nbr
->ei
->eigrp
->t_write
);
1109 /* Get packet from tail of fifo. */
1110 struct eigrp_packet
*
1111 eigrp_fifo_pop_tail (struct eigrp_fifo
*fifo
)
1113 struct eigrp_packet
*ep
;
1119 fifo
->tail
= ep
->previous
;
1121 if (fifo
->tail
== NULL
)
1124 fifo
->tail
->next
= NULL
;
1132 struct eigrp_packet
*
1133 eigrp_packet_duplicate (struct eigrp_packet
*old
, struct eigrp_neighbor
*nbr
)
1135 struct eigrp_packet
*new;
1137 new = eigrp_packet_new(nbr
->ei
->ifp
->mtu
);
1138 new->length
= old
->length
;
1139 new->retrans_counter
= old
->retrans_counter
;
1140 new->dst
= old
->dst
;
1141 new->sequence_number
= old
->sequence_number
;
1142 stream_copy(new->s
, old
->s
);
1147 struct TLV_IPv4_Internal_type
*
1148 eigrp_read_ipv4_tlv (struct stream
*s
)
1150 struct TLV_IPv4_Internal_type
*tlv
;
1152 tlv
= eigrp_IPv4_InternalTLV_new ();
1154 tlv
->type
= stream_getw(s
);
1155 tlv
->length
= stream_getw(s
);
1156 tlv
->forward
.s_addr
= stream_getl(s
);
1157 tlv
->metric
.delay
= stream_getl(s
);
1158 tlv
->metric
.bandwith
= stream_getl(s
);
1159 tlv
->metric
.mtu
[0] = stream_getc(s
);
1160 tlv
->metric
.mtu
[1] = stream_getc(s
);
1161 tlv
->metric
.mtu
[2] = stream_getc(s
);
1162 tlv
->metric
.hop_count
= stream_getc(s
);
1163 tlv
->metric
.reliability
= stream_getc(s
);
1164 tlv
->metric
.load
= stream_getc(s
);
1165 tlv
->metric
.tag
= stream_getc(s
);
1166 tlv
->metric
.flags
= stream_getc(s
);
1168 tlv
->prefix_length
= stream_getc(s
);
1170 if (tlv
->prefix_length
<= 8)
1172 tlv
->destination_part
[0] = stream_getc(s
);
1173 tlv
->destination
.s_addr
= (tlv
->destination_part
[0]);
1175 else if (tlv
->prefix_length
> 8 && tlv
->prefix_length
<= 16)
1177 tlv
->destination_part
[0] = stream_getc(s
);
1178 tlv
->destination_part
[1] = stream_getc(s
);
1179 tlv
->destination
.s_addr
= ((tlv
->destination_part
[1] << 8)
1180 + tlv
->destination_part
[0]);
1182 else if (tlv
->prefix_length
> 16 && tlv
->prefix_length
<= 24)
1184 tlv
->destination_part
[0] = stream_getc(s
);
1185 tlv
->destination_part
[1] = stream_getc(s
);
1186 tlv
->destination_part
[2] = stream_getc(s
);
1187 tlv
->destination
.s_addr
= ((tlv
->destination_part
[2] << 16) +
1188 (tlv
->destination_part
[1] << 8) +
1189 tlv
->destination_part
[0]);
1191 else if (tlv
->prefix_length
> 24 && tlv
->prefix_length
<= 32)
1193 tlv
->destination_part
[0] = stream_getc(s
);
1194 tlv
->destination_part
[1] = stream_getc(s
);
1195 tlv
->destination_part
[2] = stream_getc(s
);
1196 tlv
->destination_part
[3] = stream_getc(s
);
1197 tlv
->destination
.s_addr
= ((tlv
->destination_part
[3] << 24) +
1198 (tlv
->destination_part
[2] << 16) +
1199 (tlv
->destination_part
[1] << 8) +
1200 tlv
->destination_part
[0]);
1206 eigrp_add_internalTLV_to_stream (struct stream
*s
,
1207 struct eigrp_prefix_entry
*pe
)
1211 stream_putw(s
, EIGRP_TLV_IPv4_INT
);
1212 if (pe
->destination_ipv4
->prefixlen
<= 8)
1214 stream_putw(s
, 0x001A);
1217 if ((pe
->destination_ipv4
->prefixlen
> 8)
1218 && (pe
->destination_ipv4
->prefixlen
<= 16))
1220 stream_putw(s
, 0x001B);
1223 if ((pe
->destination_ipv4
->prefixlen
> 16)
1224 && (pe
->destination_ipv4
->prefixlen
<= 24))
1226 stream_putw(s
, 0x001C);
1229 if (pe
->destination_ipv4
->prefixlen
> 24)
1231 stream_putw(s
, 0x001D);
1235 stream_putl(s
, 0x00000000);
1238 stream_putl(s
, pe
->reported_metric
.delay
);
1239 stream_putl(s
, pe
->reported_metric
.bandwith
);
1240 stream_putc(s
, pe
->reported_metric
.mtu
[2]);
1241 stream_putc(s
, pe
->reported_metric
.mtu
[1]);
1242 stream_putc(s
, pe
->reported_metric
.mtu
[0]);
1243 stream_putc(s
, pe
->reported_metric
.hop_count
);
1244 stream_putc(s
, pe
->reported_metric
.reliability
);
1245 stream_putc(s
, pe
->reported_metric
.load
);
1246 stream_putc(s
, pe
->reported_metric
.tag
);
1247 stream_putc(s
, pe
->reported_metric
.flags
);
1249 stream_putc(s
, pe
->destination_ipv4
->prefixlen
);
1251 if (pe
->destination_ipv4
->prefixlen
<= 8)
1253 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1255 if ((pe
->destination_ipv4
->prefixlen
> 8)
1256 && (pe
->destination_ipv4
->prefixlen
<= 16))
1258 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1259 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 8) & 0xFF);
1261 if ((pe
->destination_ipv4
->prefixlen
> 16)
1262 && (pe
->destination_ipv4
->prefixlen
<= 24))
1264 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1265 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 8) & 0xFF);
1266 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 16) & 0xFF);
1268 if (pe
->destination_ipv4
->prefixlen
> 24)
1270 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1271 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 8) & 0xFF);
1272 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 16) & 0xFF);
1273 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 24) & 0xFF);
1280 eigrp_add_authTLV_MD5_to_stream (struct stream
*s
,
1281 struct eigrp_interface
*ei
)
1284 struct keychain
*keychain
;
1285 struct TLV_MD5_Authentication_Type
*authTLV
;
1287 authTLV
= eigrp_authTLV_MD5_new();
1289 authTLV
->type
= htons(EIGRP_TLV_AUTH
);
1290 authTLV
->length
= htons(EIGRP_AUTH_MD5_TLV_SIZE
);
1291 authTLV
->auth_type
= htons(EIGRP_AUTH_TYPE_MD5
);
1292 authTLV
->auth_length
= htons(EIGRP_AUTH_TYPE_MD5_LEN
);
1293 authTLV
->key_sequence
= 0;
1294 memset(authTLV
->Nullpad
,0,sizeof(authTLV
->Nullpad
));
1296 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1298 key
= key_lookup_for_send(keychain
);
1301 free(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1302 IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
= NULL
;
1303 eigrp_authTLV_MD5_free(authTLV
);
1309 authTLV
->key_id
= htonl(key
->index
);
1310 memset(authTLV
->digest
,0,EIGRP_AUTH_TYPE_MD5_LEN
);
1311 stream_put(s
,authTLV
, sizeof(struct TLV_MD5_Authentication_Type
));
1312 eigrp_authTLV_MD5_free(authTLV
);
1313 return EIGRP_AUTH_MD5_TLV_SIZE
;
1316 eigrp_authTLV_MD5_free(authTLV
);
1322 eigrp_add_authTLV_SHA256_to_stream (struct stream
*s
,
1323 struct eigrp_interface
*ei
)
1326 struct keychain
*keychain
;
1327 struct TLV_SHA256_Authentication_Type
*authTLV
;
1329 authTLV
= eigrp_authTLV_SHA256_new();
1331 authTLV
->type
= htons(EIGRP_TLV_AUTH
);
1332 authTLV
->length
= htons(EIGRP_AUTH_SHA256_TLV_SIZE
);
1333 authTLV
->auth_type
= htons(EIGRP_AUTH_TYPE_SHA256
);
1334 authTLV
->auth_length
= htons(EIGRP_AUTH_TYPE_SHA256_LEN
);
1335 authTLV
->key_sequence
= 0;
1336 memset(authTLV
->Nullpad
,0,sizeof(authTLV
->Nullpad
));
1338 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1340 key
= key_lookup_for_send(keychain
);
1343 free(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1344 IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
= NULL
;
1345 eigrp_authTLV_SHA256_free(authTLV
);
1351 authTLV
->key_id
= 0;
1352 memset(authTLV
->digest
,0,EIGRP_AUTH_TYPE_SHA256_LEN
);
1353 stream_put(s
,authTLV
, sizeof(struct TLV_SHA256_Authentication_Type
));
1354 eigrp_authTLV_SHA256_free(authTLV
);
1355 return EIGRP_AUTH_SHA256_TLV_SIZE
;
1358 eigrp_authTLV_SHA256_free(authTLV
);
1363 struct TLV_MD5_Authentication_Type
*
1364 eigrp_authTLV_MD5_new ()
1366 struct TLV_MD5_Authentication_Type
*new;
1368 new = XCALLOC(MTYPE_EIGRP_AUTH_TLV
, sizeof(struct TLV_MD5_Authentication_Type
));
1374 eigrp_authTLV_MD5_free (struct TLV_MD5_Authentication_Type
*authTLV
)
1376 XFREE(MTYPE_EIGRP_AUTH_TLV
, authTLV
);
1379 struct TLV_SHA256_Authentication_Type
*
1380 eigrp_authTLV_SHA256_new ()
1382 struct TLV_SHA256_Authentication_Type
*new;
1384 new = XCALLOC(MTYPE_EIGRP_AUTH_SHA256_TLV
, sizeof(struct TLV_SHA256_Authentication_Type
));
1390 eigrp_authTLV_SHA256_free (struct TLV_SHA256_Authentication_Type
*authTLV
)
1392 XFREE(MTYPE_EIGRP_AUTH_SHA256_TLV
, authTLV
);
1395 struct TLV_IPv4_Internal_type
*
1396 eigrp_IPv4_InternalTLV_new ()
1398 struct TLV_IPv4_Internal_type
*new;
1400 new = XCALLOC(MTYPE_EIGRP_IPV4_INT_TLV
,sizeof(struct TLV_IPv4_Internal_type
));
1406 eigrp_IPv4_InternalTLV_free (struct TLV_IPv4_Internal_type
*IPv4_InternalTLV
)
1408 XFREE(MTYPE_EIGRP_IPV4_INT_TLV
, IPv4_InternalTLV
);
1411 struct TLV_Sequence_Type
*
1412 eigrp_SequenceTLV_new ()
1414 struct TLV_Sequence_Type
*new;
1416 new = XCALLOC(MTYPE_EIGRP_SEQ_TLV
,sizeof(struct TLV_Sequence_Type
));