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"},
76 static unsigned char zeropad
[16] = {0};
78 /* Forward function reference*/
79 static struct stream
* eigrp_recv_packet (int, struct interface
**, struct stream
*);
80 static int eigrp_verify_header (struct stream
*, struct eigrp_interface
*, struct ip
*,
81 struct eigrp_header
*);
82 static int eigrp_check_network_mask (struct eigrp_interface
*, struct in_addr
);
84 static int eigrp_retrans_count_exceeded(struct eigrp_packet
*ep
, struct eigrp_neighbor
*nbr
)
90 eigrp_make_md5_digest (struct eigrp_interface
*ei
, struct stream
*s
, u_char flags
)
92 struct key
*key
= NULL
;
93 struct keychain
*keychain
;
95 unsigned char digest
[EIGRP_AUTH_TYPE_MD5_LEN
];
98 size_t backup_get
, backup_end
;
99 struct TLV_MD5_Authentication_Type
*auth_TLV
;
102 backup_end
= s
->endp
;
103 backup_get
= s
->getp
;
105 auth_TLV
= eigrp_authTLV_MD5_new();
107 stream_set_getp(s
,EIGRP_HEADER_LEN
);
108 stream_get(auth_TLV
,s
,EIGRP_AUTH_MD5_TLV_SIZE
);
109 stream_set_getp(s
, backup_get
);
111 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
113 key
= key_lookup_for_send(keychain
);
116 eigrp_authTLV_MD5_free(auth_TLV
);
117 return EIGRP_AUTH_TYPE_NONE
;
120 memset(&ctx
, 0, sizeof(ctx
));
123 /* Generate a digest. Each situation needs different handling */
124 if(flags
& EIGRP_AUTH_BASIC_HELLO_FLAG
)
126 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
127 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
128 if(strlen(key
->string
) < 16)
129 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
131 else if(flags
& EIGRP_AUTH_UPDATE_INIT_FLAG
)
133 MD5Update(&ctx
, ibuf
, EIGRP_MD5_UPDATE_INIT_COMPUTE
);
135 else if(flags
& EIGRP_AUTH_UPDATE_FLAG
)
137 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
138 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
139 if(strlen(key
->string
) < 16)
140 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
141 if(backup_end
> (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
))
143 MD5Update(&ctx
, ibuf
+ (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
),
144 backup_end
- 20 - (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
));
148 MD5Final(digest
, &ctx
);
150 /* Append md5 digest to the end of the stream. */
151 memcpy(auth_TLV
->digest
,digest
,EIGRP_AUTH_TYPE_MD5_LEN
);
153 stream_set_endp(s
,EIGRP_HEADER_LEN
);
154 stream_put(s
,auth_TLV
,EIGRP_AUTH_MD5_TLV_SIZE
);
155 stream_set_endp(s
, backup_end
);
157 eigrp_authTLV_MD5_free(auth_TLV
);
158 return EIGRP_AUTH_TYPE_MD5_LEN
;
162 eigrp_check_md5_digest (struct stream
*s
,
163 struct TLV_MD5_Authentication_Type
*authTLV
,struct eigrp_neighbor
*nbr
, u_char flags
)
166 unsigned char digest
[EIGRP_AUTH_TYPE_MD5_LEN
];
167 struct key
*key
= NULL
;
168 struct keychain
*keychain
;
171 struct TLV_MD5_Authentication_Type
*auth_TLV
;
172 struct eigrp_header
*eigrph
;
174 if (nbr
&& ntohl(nbr
->crypt_seqnum
) > ntohl(authTLV
->key_sequence
))
176 zlog_warn ("interface %s: eigrp_check_md5 bad sequence %d (expect %d)",
178 ntohl(authTLV
->key_sequence
),
179 ntohl(nbr
->crypt_seqnum
));
183 eigrph
= (struct eigrp_header
*) s
->data
;
184 eigrph
->checksum
= 0;
186 auth_TLV
=(struct TLV_MD5_Authentication_Type
*) (s
->data
+ EIGRP_HEADER_LEN
);
187 memset(auth_TLV
->digest
, 0, sizeof(auth_TLV
->digest
));
190 backup_end
= s
->endp
;
192 keychain
= keychain_lookup(IF_DEF_PARAMS (nbr
->ei
->ifp
)->auth_keychain
);
194 key
= key_lookup_for_send(keychain
);
196 memset(&ctx
, 0, sizeof(ctx
));
199 /* Generate a digest. Each situation needs different handling */
200 if(flags
& EIGRP_AUTH_BASIC_HELLO_FLAG
)
202 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
203 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
204 if(strlen(key
->string
) < 16)
205 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
207 else if(flags
& EIGRP_AUTH_UPDATE_INIT_FLAG
)
209 MD5Update(&ctx
, ibuf
, EIGRP_MD5_UPDATE_INIT_COMPUTE
);
211 else if(flags
& EIGRP_AUTH_UPDATE_FLAG
)
213 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
214 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
215 if(strlen(key
->string
) < 16)
216 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
217 if(backup_end
> (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
))
219 MD5Update(&ctx
, ibuf
+ (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
),
220 backup_end
- 20 - (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
));
224 MD5Final(digest
, &ctx
);
226 /* compare the two */
227 if (memcmp (authTLV
->digest
, digest
, EIGRP_AUTH_TYPE_MD5_LEN
) == 0)
229 zlog_debug("VSETKO OK");
233 zlog_warn ("interface %s: eigrp_check_md5 checksum mismatch",
238 /* save neighbor's crypt_seqnum */
239 nbr
->crypt_seqnum
= authTLV
->key_sequence
;
245 eigrp_make_sha256_digest (struct eigrp_interface
*ei
, struct stream
*s
, u_char flags
)
247 struct key
*key
= NULL
;
248 struct keychain
*keychain
;
251 unsigned char digest
[EIGRP_AUTH_TYPE_SHA256_LEN
];
252 unsigned char buffer
[1 + PLAINTEXT_LENGTH
+ 45 + 1] = { 0 };
255 size_t backup_get
, backup_end
;
256 struct TLV_SHA256_Authentication_Type
*auth_TLV
;
259 backup_end
= s
->endp
;
260 backup_get
= s
->getp
;
262 auth_TLV
= eigrp_authTLV_SHA256_new ();
264 stream_set_getp(s
,EIGRP_HEADER_LEN
);
265 stream_get(auth_TLV
,s
,EIGRP_AUTH_SHA256_TLV_SIZE
);
266 stream_set_getp(s
, backup_get
);
268 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
270 key
= key_lookup_for_send(keychain
);
272 // saved_len[index] = strnzcpyn(saved_key[index], key,
273 // PLAINTEXT_LENGTH + 1);
275 source_ip
= calloc(16, sizeof(char));
276 inet_ntop(AF_INET
, &ei
->address
->u
.prefix4
, source_ip
, 16);
278 memset(&ctx
, 0, sizeof(ctx
));
280 memcpy(buffer
+ 1, key
, strlen (key
->string
));
281 memcpy(buffer
+ 1 + strlen(key
->string
), source_ip
, strlen(source_ip
));
282 HMAC__SHA256_Init(&ctx
, buffer
, 1 + strlen (key
->string
) + strlen(source_ip
));
283 HMAC__SHA256_Update(&ctx
, ibuf
, strlen(ibuf
));
284 HMAC__SHA256_Final(digest
, &ctx
);
287 /* Put hmac-sha256 digest to it's place */
288 memcpy(auth_TLV
->digest
,digest
,EIGRP_AUTH_TYPE_SHA256_LEN
);
290 stream_set_endp(s
,EIGRP_HEADER_LEN
);
291 stream_put(s
,auth_TLV
,EIGRP_AUTH_SHA256_TLV_SIZE
);
292 stream_set_endp(s
, backup_end
);
294 eigrp_authTLV_SHA256_free(auth_TLV
);
297 return EIGRP_AUTH_TYPE_SHA256_LEN
;
301 eigrp_check_sha256_digest (struct stream
*s
,
302 struct TLV_SHA256_Authentication_Type
*authTLV
,
303 struct eigrp_neighbor
*nbr
, u_char flags
)
311 * This routing dumps the contents of the IP packet either received or
315 eigrp_packet_dump (struct stream
*s
)
322 eigrp_write (struct thread
*thread
)
324 struct eigrp
*eigrp
= THREAD_ARG(thread
);
325 struct eigrp_header
*eigrph
;
326 struct eigrp_interface
*ei
;
327 struct eigrp_packet
*ep
;
328 struct sockaddr_in sa_dst
;
332 u_int16_t opcode
= 0;
336 struct listnode
*node
;
337 #ifdef WANT_EIGRP_WRITE_FRAGMENT
338 static u_int16_t ipid
= 0;
339 #endif /* WANT_EIGRP_WRITE_FRAGMENT */
340 #define EIGRP_WRITE_IPHL_SHIFT 2
342 eigrp
->t_write
= NULL
;
344 node
= listhead(eigrp
->oi_write_q
);
346 ei
= listgetdata(node
);
349 #ifdef WANT_EIGRP_WRITE_FRAGMENT
350 /* seed ipid static with low order bits of time */
352 ipid
= (time(NULL
) & 0xffff);
353 #endif /* WANT_EIGRP_WRITE_FRAGMENT */
355 /* Get one packet from queue. */
356 ep
= eigrp_fifo_head(ei
->obuf
);
358 assert(ep
->length
>= EIGRP_HEADER_LEN
);
360 if (ep
->dst
.s_addr
== htonl(EIGRP_MULTICAST_ADDRESS
))
361 eigrp_if_ipmulticast(eigrp
, ei
->address
, ei
->ifp
->ifindex
);
363 memset(&iph
, 0, sizeof(struct ip
));
364 memset(&sa_dst
, 0, sizeof(sa_dst
));
366 sa_dst
.sin_family
= AF_INET
;
367 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
368 sa_dst
.sin_len
= sizeof(sa_dst
);
369 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
370 sa_dst
.sin_addr
= ep
->dst
;
371 sa_dst
.sin_port
= htons(0);
373 /* Set DONTROUTE flag if dst is unicast. */
374 if (!IN_MULTICAST(htonl(ep
->dst
.s_addr
)))
375 flags
= MSG_DONTROUTE
;
377 iph
.ip_hl
= sizeof(struct ip
) >> EIGRP_WRITE_IPHL_SHIFT
;
378 /* it'd be very strange for header to not be 4byte-word aligned but.. */
379 if (sizeof(struct ip
) > (unsigned int)(iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
))
380 iph
.ip_hl
++; /* we presume sizeof struct ip cant overflow ip_hl.. */
382 iph
.ip_v
= IPVERSION
;
383 iph
.ip_tos
= IPTOS_PREC_INTERNETCONTROL
;
384 iph
.ip_len
= (iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
) + ep
->length
;
386 #if defined (__DragonFly__)
388 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
390 iph
.ip_len
= htons(iph
.ip_len
);
394 iph
.ip_ttl
= EIGRP_IP_TTL
;
395 iph
.ip_p
= IPPROTO_EIGRPIGP
;
397 iph
.ip_src
.s_addr
= ei
->address
->u
.prefix4
.s_addr
;
398 iph
.ip_dst
.s_addr
= ep
->dst
.s_addr
;
400 memset(&msg
, 0, sizeof(msg
));
401 msg
.msg_name
= (caddr_t
) &sa_dst
;
402 msg
.msg_namelen
= sizeof(sa_dst
);
406 iov
[0].iov_base
= (char*)&iph
;
407 iov
[0].iov_len
= iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
;
408 iov
[1].iov_base
= STREAM_PNT(ep
->s
);
409 iov
[1].iov_len
= ep
->length
;
411 /* send final fragment (could be first) */
412 sockopt_iphdrincl_swab_htosys(&iph
);
413 ret
= sendmsg(eigrp
->fd
, &msg
, flags
);
414 sockopt_iphdrincl_swab_systoh(&iph
);
416 if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND
))
418 eigrph
= (struct eigrp_header
*) STREAM_DATA(ep
->s
);
419 opcode
= eigrph
->opcode
;
420 zlog_debug("Sending [%s] to [%s] via [%s] ret [%d].",
421 lookup_msg(eigrp_packet_type_str
, opcode
, NULL
),
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_msg(eigrp_packet_type_str
, opcode
, NULL
), 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
));