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
);
116 return EIGRP_AUTH_TYPE_NONE
;
118 memset(&ctx
, 0, sizeof(ctx
));
121 /* Generate a digest. Each situation needs different handling */
122 if(flags
& EIGRP_AUTH_BASIC_HELLO_FLAG
)
124 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
125 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
126 if(strlen(key
->string
) < 16)
127 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
129 else if(flags
& EIGRP_AUTH_UPDATE_INIT_FLAG
)
131 MD5Update(&ctx
, ibuf
, EIGRP_MD5_UPDATE_INIT_COMPUTE
);
133 else if(flags
& EIGRP_AUTH_UPDATE_FLAG
)
135 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
136 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
137 if(strlen(key
->string
) < 16)
138 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
139 if(backup_end
> (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
))
141 MD5Update(&ctx
, ibuf
+ (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
),
142 backup_end
- 20 - (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
));
146 MD5Final(digest
, &ctx
);
148 /* Append md5 digest to the end of the stream. */
149 memcpy(auth_TLV
->digest
,digest
,EIGRP_AUTH_TYPE_MD5_LEN
);
151 stream_set_endp(s
,EIGRP_HEADER_LEN
);
152 stream_put(s
,auth_TLV
,EIGRP_AUTH_MD5_TLV_SIZE
);
153 stream_set_endp(s
, backup_end
);
155 eigrp_authTLV_MD5_free(auth_TLV
);
156 return EIGRP_AUTH_TYPE_MD5_LEN
;
160 eigrp_check_md5_digest (struct stream
*s
,
161 struct TLV_MD5_Authentication_Type
*authTLV
,struct eigrp_neighbor
*nbr
, u_char flags
)
164 unsigned char digest
[EIGRP_AUTH_TYPE_MD5_LEN
];
165 struct key
*key
= NULL
;
166 struct keychain
*keychain
;
169 struct TLV_MD5_Authentication_Type
*auth_TLV
;
170 struct eigrp_header
*eigrph
;
172 if (nbr
&& ntohl(nbr
->crypt_seqnum
) > ntohl(authTLV
->key_sequence
))
174 zlog_warn ("interface %s: eigrp_check_md5 bad sequence %d (expect %d)",
176 ntohl(authTLV
->key_sequence
),
177 ntohl(nbr
->crypt_seqnum
));
181 eigrph
= (struct eigrp_header
*) s
->data
;
182 eigrph
->checksum
= 0;
184 auth_TLV
=(struct TLV_MD5_Authentication_Type
*) (s
->data
+ EIGRP_HEADER_LEN
);
185 memcpy(auth_TLV
->digest
, "0", sizeof(auth_TLV
->digest
));
188 backup_end
= s
->endp
;
190 keychain
= keychain_lookup(IF_DEF_PARAMS (nbr
->ei
->ifp
)->auth_keychain
);
192 key
= key_lookup_for_send(keychain
);
194 memset(&ctx
, 0, sizeof(ctx
));
197 /* Generate a digest. Each situation needs different handling */
198 if(flags
& EIGRP_AUTH_BASIC_HELLO_FLAG
)
200 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
201 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
202 if(strlen(key
->string
) < 16)
203 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
205 else if(flags
& EIGRP_AUTH_UPDATE_INIT_FLAG
)
207 MD5Update(&ctx
, ibuf
, EIGRP_MD5_UPDATE_INIT_COMPUTE
);
209 else if(flags
& EIGRP_AUTH_UPDATE_FLAG
)
211 MD5Update(&ctx
, ibuf
, EIGRP_MD5_BASIC_COMPUTE
);
212 MD5Update(&ctx
, key
->string
, strlen(key
->string
));
213 if(strlen(key
->string
) < 16)
214 MD5Update(&ctx
, zeropad
, 16 - strlen(key
->string
));
215 if(backup_end
> (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
))
217 MD5Update(&ctx
, ibuf
+ (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
),
218 backup_end
- 20 - (EIGRP_HEADER_LEN
+ EIGRP_AUTH_MD5_TLV_SIZE
));
222 MD5Final(digest
, &ctx
);
224 /* compare the two */
225 if (memcmp (authTLV
->digest
, digest
, EIGRP_AUTH_TYPE_MD5_LEN
) == 0)
227 zlog_debug("VSETKO OK");
231 zlog_warn ("interface %s: eigrp_check_md5 checksum mismatch",
236 /* save neighbor's crypt_seqnum */
238 nbr
->crypt_seqnum
= authTLV
->key_sequence
;
244 eigrp_make_sha256_digest (struct eigrp_interface
*ei
, struct stream
*s
, u_char flags
)
246 struct key
*key
= NULL
;
247 struct keychain
*keychain
;
250 unsigned char digest
[EIGRP_AUTH_TYPE_SHA256_LEN
];
251 unsigned char buffer
[1 + PLAINTEXT_LENGTH
+ 45 + 1] = { 0 };
254 size_t backup_get
, backup_end
;
255 struct TLV_SHA256_Authentication_Type
*auth_TLV
;
258 backup_end
= s
->endp
;
259 backup_get
= s
->getp
;
261 auth_TLV
= eigrp_authTLV_SHA256_new ();
263 stream_set_getp(s
,EIGRP_HEADER_LEN
);
264 stream_get(auth_TLV
,s
,EIGRP_AUTH_SHA256_TLV_SIZE
);
265 stream_set_getp(s
, backup_get
);
267 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
269 key
= key_lookup_for_send(keychain
);
271 // saved_len[index] = strnzcpyn(saved_key[index], key,
272 // PLAINTEXT_LENGTH + 1);
274 source_ip
= calloc(16, sizeof(char));
275 inet_ntop(AF_INET
, &ei
->address
->u
.prefix4
, source_ip
, 16);
277 memset(&ctx
, 0, sizeof(ctx
));
279 memcpy(buffer
+ 1, key
, strlen (key
->string
));
280 memcpy(buffer
+ 1 + strlen(key
->string
), source_ip
, strlen(source_ip
));
281 HMAC__SHA256_Init(&ctx
, buffer
, 1 + strlen (key
->string
) + strlen(source_ip
));
282 HMAC__SHA256_Update(&ctx
, ibuf
, strlen(ibuf
));
283 HMAC__SHA256_Final(digest
, &ctx
);
286 /* Put hmac-sha256 digest to it's place */
287 memcpy(auth_TLV
->digest
,digest
,EIGRP_AUTH_TYPE_SHA256_LEN
);
289 stream_set_endp(s
,EIGRP_HEADER_LEN
);
290 stream_put(s
,auth_TLV
,EIGRP_AUTH_SHA256_TLV_SIZE
);
291 stream_set_endp(s
, backup_end
);
293 eigrp_authTLV_SHA256_free(auth_TLV
);
296 return EIGRP_AUTH_TYPE_SHA256_LEN
;
300 eigrp_check_sha256_digest (struct stream
*s
,
301 struct TLV_SHA256_Authentication_Type
*authTLV
,
302 struct eigrp_neighbor
*nbr
, u_char flags
)
310 * This routing dumps the contents of the IP packet either received or
314 eigrp_packet_dump (struct stream
*s
)
321 eigrp_write (struct thread
*thread
)
323 struct eigrp
*eigrp
= THREAD_ARG(thread
);
324 struct eigrp_header
*eigrph
;
325 struct eigrp_interface
*ei
;
326 struct eigrp_packet
*ep
;
327 struct sockaddr_in sa_dst
;
331 u_int16_t opcode
= 0;
335 struct listnode
*node
;
336 #ifdef WANT_EIGRP_WRITE_FRAGMENT
337 static u_int16_t ipid
= 0;
338 #endif /* WANT_EIGRP_WRITE_FRAGMENT */
339 #define EIGRP_WRITE_IPHL_SHIFT 2
341 eigrp
->t_write
= NULL
;
343 node
= listhead(eigrp
->oi_write_q
);
345 ei
= listgetdata(node
);
348 #ifdef WANT_EIGRP_WRITE_FRAGMENT
349 /* seed ipid static with low order bits of time */
351 ipid
= (time(NULL
) & 0xffff);
352 #endif /* WANT_EIGRP_WRITE_FRAGMENT */
354 /* Get one packet from queue. */
355 ep
= eigrp_fifo_head(ei
->obuf
);
357 assert(ep
->length
>= EIGRP_HEADER_LEN
);
359 if (ep
->dst
.s_addr
== htonl(EIGRP_MULTICAST_ADDRESS
))
360 eigrp_if_ipmulticast(eigrp
, ei
->address
, ei
->ifp
->ifindex
);
362 memset(&iph
, 0, sizeof(struct ip
));
363 memset(&sa_dst
, 0, sizeof(sa_dst
));
365 sa_dst
.sin_family
= AF_INET
;
366 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
367 sa_dst
.sin_len
= sizeof(sa_dst
);
368 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
369 sa_dst
.sin_addr
= ep
->dst
;
370 sa_dst
.sin_port
= htons(0);
372 /* Set DONTROUTE flag if dst is unicast. */
373 if (!IN_MULTICAST(htonl(ep
->dst
.s_addr
)))
374 flags
= MSG_DONTROUTE
;
376 iph
.ip_hl
= sizeof(struct ip
) >> EIGRP_WRITE_IPHL_SHIFT
;
377 /* it'd be very strange for header to not be 4byte-word aligned but.. */
378 if (sizeof(struct ip
) > (unsigned int)(iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
))
379 iph
.ip_hl
++; /* we presume sizeof struct ip cant overflow ip_hl.. */
381 iph
.ip_v
= IPVERSION
;
382 iph
.ip_tos
= IPTOS_PREC_INTERNETCONTROL
;
383 iph
.ip_len
= (iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
) + ep
->length
;
385 #if defined (__DragonFly__)
387 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
389 iph
.ip_len
= htons(iph
.ip_len
);
393 iph
.ip_ttl
= EIGRP_IP_TTL
;
394 iph
.ip_p
= IPPROTO_EIGRPIGP
;
396 iph
.ip_src
.s_addr
= ei
->address
->u
.prefix4
.s_addr
;
397 iph
.ip_dst
.s_addr
= ep
->dst
.s_addr
;
399 memset(&msg
, 0, sizeof(msg
));
400 msg
.msg_name
= (caddr_t
) &sa_dst
;
401 msg
.msg_namelen
= sizeof(sa_dst
);
405 iov
[0].iov_base
= (char*)&iph
;
406 iov
[0].iov_len
= iph
.ip_hl
<< EIGRP_WRITE_IPHL_SHIFT
;
407 iov
[1].iov_base
= STREAM_PNT(ep
->s
);
408 iov
[1].iov_len
= ep
->length
;
410 /* send final fragment (could be first) */
411 sockopt_iphdrincl_swab_htosys(&iph
);
412 ret
= sendmsg(eigrp
->fd
, &msg
, flags
);
413 sockopt_iphdrincl_swab_systoh(&iph
);
415 if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND
))
417 eigrph
= (struct eigrp_header
*) STREAM_DATA(ep
->s
);
418 opcode
= eigrph
->opcode
;
419 zlog_debug("Sending [%s] to [%s] via [%s] ret [%d].",
420 LOOKUP(eigrp_packet_type_str
, opcode
), inet_ntoa(ep
->dst
),
425 zlog_warn("*** sendmsg in eigrp_write failed to %s, "
426 "id %d, off %d, len %d, interface %s, mtu %u: %s",
427 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
, iph
.ip_len
, ei
->ifp
->name
,
428 ei
->ifp
->mtu
, safe_strerror(errno
));
430 /* Show debug sending packet. */
431 if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND
) && (IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL
)))
433 zlog_debug("-----------------------------------------------------");
434 eigrp_ip_header_dump(&iph
);
435 stream_set_getp(ep
->s
, 0);
436 eigrp_packet_dump(ep
->s
);
437 zlog_debug("-----------------------------------------------------");
440 /* Now delete packet from queue. */
441 eigrp_packet_delete(ei
);
443 if (eigrp_fifo_head(ei
->obuf
) == NULL
)
446 list_delete_node(eigrp
->oi_write_q
, node
);
449 /* If packets still remain in queue, call write thread. */
450 if (!list_isempty(eigrp
->oi_write_q
)) {
451 eigrp
->t_write
= NULL
;
452 thread_add_write(master
, eigrp_write
, eigrp
, eigrp
->fd
, &eigrp
->t_write
);
458 /* Starting point of packet process function. */
460 eigrp_read (struct thread
*thread
)
465 struct eigrp_interface
*ei
;
467 struct eigrp_header
*eigrph
;
468 struct interface
*ifp
;
469 struct eigrp_neighbor
*nbr
;
471 u_int16_t opcode
= 0;
472 u_int16_t length
= 0;
474 /* first of all get interface pointer. */
475 eigrp
= THREAD_ARG(thread
);
477 /* prepare for next packet. */
478 eigrp
->t_read
= NULL
;
479 thread_add_read(master
, eigrp_read
, eigrp
, eigrp
->fd
, &eigrp
->t_read
);
481 stream_reset(eigrp
->ibuf
);
482 if (!(ibuf
= eigrp_recv_packet(eigrp
->fd
, &ifp
, eigrp
->ibuf
)))
484 /* This raw packet is known to be at least as big as its IP header. */
488 /* Note that there should not be alignment problems with this assignment
489 because this is at the beginning of the stream data buffer. */
490 iph
= (struct ip
*)STREAM_DATA(ibuf
);
492 //Substract IPv4 header size from EIGRP Packet itself
494 length
= (iph
->ip_len
) - 20U;
497 /* IP Header dump. */
498 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
) && IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL
))
499 eigrp_ip_header_dump(iph
);
501 /* Note that sockopt_iphdrincl_swab_systoh was called in eigrp_recv_packet. */
505 /* Handle cases where the platform does not support retrieving the ifindex,
506 and also platforms (such as Solaris 8) that claim to support ifindex
507 retrieval but do not. */
508 c
= if_lookup_address((void *)&iph
->ip_src
, AF_INET
, VRF_DEFAULT
);
516 /* associate packet with eigrp interface */
517 ei
= eigrp_if_lookup_recv_if(eigrp
, iph
->ip_src
, ifp
);
519 /* eigrp_verify_header() relies on a valid "ei" and thus can be called only
520 after the checks below are passed. These checks in turn access the
521 fields of unverified "eigrph" structure for their own purposes and
522 must remain very accurate in doing this.
527 /* Self-originated packet should be discarded silently. */
528 if (eigrp_if_lookup_by_local_addr(eigrp
, NULL
, iph
->ip_src
) ||
529 (IPV4_ADDR_SAME(&iph
->ip_src
.s_addr
, &ei
->address
->u
.prefix4
)))
531 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
532 zlog_debug("eigrp_read[%s]: Dropping self-originated packet",
533 inet_ntoa(iph
->ip_src
));
537 /* Advance from IP header to EIGRP header (iph->ip_hl has been verified
538 by eigrp_recv_packet() to be correct). */
540 stream_forward_getp(ibuf
, (iph
->ip_hl
* 4));
541 eigrph
= (struct eigrp_header
*) STREAM_PNT(ibuf
);
543 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
) && IS_DEBUG_EIGRP_TRANSMIT(0, PACKET_DETAIL
))
544 eigrp_header_dump(eigrph
);
546 // if (MSG_OK != eigrp_packet_examin(eigrph, stream_get_endp(ibuf) - stream_get_getp(ibuf)))
549 /* Now it is safe to access all fields of EIGRP packet header. */
550 /* associate packet with eigrp interface */
551 ei
= eigrp_if_lookup_recv_if(eigrp
, iph
->ip_src
, ifp
);
553 /* eigrp_verify_header() relies on a valid "ei" and thus can be called only
554 after the checks below are passed. These checks in turn access the
555 fields of unverified "eigrph" structure for their own purposes and
556 must remain very accurate in doing this.
561 /* If incoming interface is passive one, ignore it. */
562 if (ei
&& EIGRP_IF_PASSIVE_STATUS(ei
) == EIGRP_IF_PASSIVE
)
564 char buf
[3][INET_ADDRSTRLEN
];
566 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
567 zlog_debug("ignoring packet from router %s sent to %s, "
568 "received on a passive interface, %s",
569 inet_ntop(AF_INET
, &eigrph
->vrid
, buf
[0], sizeof(buf
[0])),
570 inet_ntop(AF_INET
, &iph
->ip_dst
, buf
[1], sizeof(buf
[1])),
571 inet_ntop(AF_INET
, &ei
->address
->u
.prefix4
,
572 buf
[2], sizeof(buf
[2])));
574 if (iph
->ip_dst
.s_addr
== htonl(EIGRP_MULTICAST_ADDRESS
))
576 /* Try to fix multicast membership.
577 * Some OS:es may have problems in this area,
578 * make sure it is removed.
580 EI_MEMBER_JOINED(ei
, MEMBER_ALLROUTERS
);
581 eigrp_if_set_multicast(ei
);
586 /* else it must be a local eigrp interface, check it was received on
589 else if (ei
->ifp
!= ifp
)
591 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
592 zlog_warn("Packet from [%s] received on wrong link %s",
593 inet_ntoa(iph
->ip_src
), ifp
->name
);
597 /* Verify more EIGRP header fields. */
598 ret
= eigrp_verify_header(ibuf
, ei
, iph
, eigrph
);
601 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
602 zlog_debug("eigrp_read[%s]: Header check failed, dropping.",
603 inet_ntoa(iph
->ip_src
));
607 /* calcualte the eigrp packet length, and move the pounter to the
608 start of the eigrp TLVs */
609 opcode
= eigrph
->opcode
;
611 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
612 zlog_debug("Received [%s] length [%u] via [%s] src [%s] dst [%s]",
613 LOOKUP(eigrp_packet_type_str
, opcode
), length
,
614 IF_NAME(ei
), inet_ntoa(iph
->ip_src
), inet_ntoa(iph
->ip_dst
));
616 /* Read rest of the packet and call each sort of packet routine. */
617 stream_forward_getp(ibuf
, EIGRP_HEADER_LEN
);
619 /* New testing block of code for handling Acks */
620 if (ntohl(eigrph
->ack
) != 0)
622 nbr
= eigrp_nbr_get(ei
, eigrph
, iph
);
624 /* neighbor must be valid, eigrp_nbr_get creates if none existed */
627 struct eigrp_packet
*ep
;
629 ep
= eigrp_fifo_tail(nbr
->retrans_queue
);
632 if (ntohl(eigrph
->ack
) == ep
->sequence_number
)
634 if((nbr
->state
== EIGRP_NEIGHBOR_PENDING
) &&
635 (ntohl(eigrph
->ack
) == nbr
->init_sequence_number
))
637 eigrp_nbr_state_set(nbr
, EIGRP_NEIGHBOR_UP
);
638 zlog_info("Neighbor adjacency became full");
639 nbr
->init_sequence_number
= 0;
640 nbr
->recv_sequence_number
= ntohl(eigrph
->sequence
);
641 eigrp_update_send_EOT(nbr
);
643 ep
= eigrp_fifo_pop_tail(nbr
->retrans_queue
);
644 /*eigrp_packet_free(ep);*/
645 if (nbr
->retrans_queue
->count
> 0)
647 eigrp_send_packet_reliably(nbr
);
651 ep
= eigrp_fifo_tail(nbr
->multicast_queue
);
654 if (ntohl(eigrph
->ack
) == ep
->sequence_number
)
656 ep
= eigrp_fifo_pop_tail(nbr
->multicast_queue
);
657 eigrp_packet_free(ep
);
658 if (nbr
->multicast_queue
->count
> 0)
660 eigrp_send_packet_reliably(nbr
);
669 case EIGRP_OPC_HELLO
:
670 eigrp_hello_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
672 case EIGRP_OPC_PROBE
:
673 // eigrp_probe_receive(eigrp, iph, eigrph, ibuf, ei, length);
675 case EIGRP_OPC_QUERY
:
676 eigrp_query_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
678 case EIGRP_OPC_REPLY
:
679 eigrp_reply_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
681 case EIGRP_OPC_REQUEST
:
682 // eigrp_request_receive(eigrp, iph, eigrph, ibuf, ei, length);
684 case EIGRP_OPC_SIAQUERY
:
685 eigrp_query_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
687 case EIGRP_OPC_SIAREPLY
:
688 eigrp_reply_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
690 case EIGRP_OPC_UPDATE
:
691 eigrp_update_receive(eigrp
, iph
, eigrph
, ibuf
, ei
, length
);
694 zlog_warn("interface %s: EIGRP packet header type %d unsupported",
695 IF_NAME(ei
), opcode
);
702 static struct stream
*
703 eigrp_recv_packet (int fd
, struct interface
**ifp
, struct stream
*ibuf
)
708 unsigned int ifindex
= 0;
710 /* Header and data both require alignment. */
711 char buff
[CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
714 memset(&msgh
, 0, sizeof(struct msghdr
));
717 msgh
.msg_control
= (caddr_t
) buff
;
718 msgh
.msg_controllen
= sizeof(buff
);
720 ret
= stream_recvmsg(ibuf
, fd
, &msgh
, 0, (EIGRP_PACKET_MAX_LEN
+ 1));
723 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno
));
726 if ((unsigned int) ret
< sizeof(iph
)) /* ret must be > 0 now */
728 zlog_warn("eigrp_recv_packet: discarding runt packet of length %d "
729 "(ip header size is %u)", ret
, (u_int
) sizeof(iph
));
733 /* Note that there should not be alignment problems with this assignment
734 because this is at the beginning of the stream data buffer. */
735 iph
= (struct ip
*) STREAM_DATA(ibuf
);
736 sockopt_iphdrincl_swab_systoh(iph
);
738 ip_len
= iph
->ip_len
;
740 #if !defined (GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
742 * Kernel network code touches incoming IP header parameters,
743 * before protocol specific processing.
745 * 1) Convert byteorder to host representation.
746 * --> ip_len, ip_id, ip_off
748 * 2) Adjust ip_len to strip IP header size!
749 * --> If user process receives entire IP packet via RAW
750 * socket, it must consider adding IP header size to
751 * the "ip_len" field of "ip" structure.
753 * For more details, see <netinet/ip_input.c>.
755 ip_len
= ip_len
+ (iph
->ip_hl
<< 2);
758 #if defined (__DragonFly__)
760 * in DragonFly's raw socket, ip_len/ip_off are read
761 * in network byte order.
762 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
764 ip_len
= ntohs(iph
->ip_len
) + (iph
->ip_hl
<< 2);
767 ifindex
= getsockopt_ifindex(AF_INET
, &msgh
);
769 *ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
773 zlog_warn("eigrp_recv_packet read length mismatch: ip_len is %d, "
774 "but recvmsg returned %d", ip_len
, ret
);
782 eigrp_fifo_new (void)
784 struct eigrp_fifo
*new;
786 new = XCALLOC(MTYPE_EIGRP_FIFO
, sizeof(struct eigrp_fifo
));
790 /* Free eigrp packet fifo. */
792 eigrp_fifo_free (struct eigrp_fifo
*fifo
)
794 struct eigrp_packet
*ep
;
795 struct eigrp_packet
*next
;
797 for (ep
= fifo
->head
; ep
; ep
= next
)
800 eigrp_packet_free(ep
);
802 fifo
->head
= fifo
->tail
= NULL
;
805 XFREE(MTYPE_EIGRP_FIFO
, fifo
);
808 /* Free eigrp fifo entries without destroying fifo itself*/
810 eigrp_fifo_reset (struct eigrp_fifo
*fifo
)
812 struct eigrp_packet
*ep
;
813 struct eigrp_packet
*next
;
815 for (ep
= fifo
->head
; ep
; ep
= next
)
818 eigrp_packet_free(ep
);
820 fifo
->head
= fifo
->tail
= NULL
;
824 struct eigrp_packet
*
825 eigrp_packet_new (size_t size
)
827 struct eigrp_packet
*new;
829 new = XCALLOC(MTYPE_EIGRP_PACKET
, sizeof(struct eigrp_packet
));
830 new->s
= stream_new(size
);
831 new->retrans_counter
= 0;
837 eigrp_send_packet_reliably (struct eigrp_neighbor
*nbr
)
839 struct eigrp_packet
*ep
;
841 ep
= eigrp_fifo_tail(nbr
->retrans_queue
);
845 struct eigrp_packet
*duplicate
;
846 duplicate
= eigrp_packet_duplicate(ep
, nbr
);
847 /* Add packet to the top of the interface output queue*/
848 eigrp_fifo_push_head(nbr
->ei
->obuf
, duplicate
);
850 /*Start retransmission timer*/
851 thread_add_timer(master
, eigrp_unack_packet_retrans
, nbr
,
852 EIGRP_PACKET_RETRANS_TIME
, &ep
->t_retrans_timer
);
854 /*Increment sequence number counter*/
855 nbr
->ei
->eigrp
->sequence_number
++;
857 /* Hook thread to write packet. */
858 if (nbr
->ei
->on_write_q
== 0)
860 listnode_add(nbr
->ei
->eigrp
->oi_write_q
, nbr
->ei
);
861 nbr
->ei
->on_write_q
= 1;
863 thread_add_write(master
, eigrp_write
, nbr
->ei
->eigrp
, nbr
->ei
->eigrp
->fd
,
864 &nbr
->ei
->eigrp
->t_write
);
868 /* Calculate EIGRP checksum */
870 eigrp_packet_checksum (struct eigrp_interface
*ei
, struct stream
*s
,
873 struct eigrp_header
*eigrph
;
875 eigrph
= (struct eigrp_header
*) STREAM_DATA(s
);
877 /* Calculate checksum. */
878 eigrph
->checksum
= in_cksum(eigrph
, length
);
881 /* Make EIGRP header. */
883 eigrp_packet_header_init (int type
, struct eigrp_interface
*ei
, struct stream
*s
,
884 u_int32_t flags
, u_int32_t sequence
, u_int32_t ack
)
886 struct eigrp_header
*eigrph
;
888 eigrph
= (struct eigrp_header
*) STREAM_DATA(s
);
890 eigrph
->version
= (u_char
) EIGRP_HEADER_VERSION
;
891 eigrph
->opcode
= (u_char
) type
;
892 eigrph
->checksum
= 0;
894 eigrph
->vrid
= htons(ei
->eigrp
->vrid
);
895 eigrph
->ASNumber
= htons(ei
->eigrp
->AS
);
896 eigrph
->ack
= htonl(ack
);
897 eigrph
->sequence
= htonl(sequence
);
898 // if(flags == EIGRP_INIT_FLAG)
899 // eigrph->sequence = htonl(3);
900 eigrph
->flags
= htonl(flags
);
902 if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV
))
903 zlog_debug("Packet Header Init Seq [%u] Ack [%u]",
904 htonl(eigrph
->sequence
), htonl(eigrph
->ack
));
906 stream_forward_endp(s
, EIGRP_HEADER_LEN
);
909 /* Add new packet to head of fifo. */
911 eigrp_fifo_push_head (struct eigrp_fifo
*fifo
, struct eigrp_packet
*ep
)
913 ep
->next
= fifo
->head
;
916 if (fifo
->tail
== NULL
)
919 if (fifo
->count
!= 0)
920 fifo
->head
->previous
= ep
;
927 /* Return first fifo entry. */
928 struct eigrp_packet
*
929 eigrp_fifo_head (struct eigrp_fifo
*fifo
)
934 /* Return last fifo entry. */
935 struct eigrp_packet
*
936 eigrp_fifo_tail (struct eigrp_fifo
*fifo
)
942 eigrp_packet_delete (struct eigrp_interface
*ei
)
944 struct eigrp_packet
*ep
;
946 ep
= eigrp_fifo_pop (ei
->obuf
);
949 eigrp_packet_free(ep
);
952 /* Delete first packet from fifo. */
953 struct eigrp_packet
*
954 eigrp_fifo_pop (struct eigrp_fifo
*fifo
)
956 struct eigrp_packet
*ep
;
962 fifo
->head
= ep
->next
;
964 if (fifo
->head
== NULL
)
967 fifo
->head
->previous
= NULL
;
976 eigrp_packet_free (struct eigrp_packet
*ep
)
981 THREAD_OFF(ep
->t_retrans_timer
);
983 XFREE(MTYPE_EIGRP_PACKET
, ep
);
988 /* EIGRP Header verification. */
990 eigrp_verify_header (struct stream
*ibuf
, struct eigrp_interface
*ei
,
991 struct ip
*iph
, struct eigrp_header
*eigrph
)
993 /* Check network mask, Silently discarded. */
994 if (!eigrp_check_network_mask(ei
, iph
->ip_src
))
996 zlog_warn("interface %s: eigrp_read network address is not same [%s]",
997 IF_NAME(ei
), inet_ntoa(iph
->ip_src
));
1001 // /* Check authentication. The function handles logging actions, where required. */
1002 // if (! eigrp_check_auth(ei, eigrph))
1008 /* Unbound socket will accept any Raw IP packets if proto is matched.
1009 To prevent it, compare src IP address and i/f address with masking
1010 i/f network mask. */
1012 eigrp_check_network_mask (struct eigrp_interface
*ei
, struct in_addr ip_src
)
1014 struct in_addr mask
, me
, him
;
1016 if (ei
->type
== EIGRP_IFTYPE_POINTOPOINT
)
1019 masklen2ip(ei
->address
->prefixlen
, &mask
);
1021 me
.s_addr
= ei
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
1022 him
.s_addr
= ip_src
.s_addr
& mask
.s_addr
;
1024 if (IPV4_ADDR_SAME(&me
, &him
))
1031 eigrp_unack_packet_retrans (struct thread
*thread
)
1033 struct eigrp_neighbor
*nbr
;
1034 nbr
= (struct eigrp_neighbor
*) THREAD_ARG(thread
);
1036 struct eigrp_packet
*ep
;
1037 ep
= eigrp_fifo_tail(nbr
->retrans_queue
);
1041 struct eigrp_packet
*duplicate
;
1042 duplicate
= eigrp_packet_duplicate(ep
, nbr
);
1044 /* Add packet to the top of the interface output queue*/
1045 eigrp_fifo_push_head(nbr
->ei
->obuf
, duplicate
);
1047 ep
->retrans_counter
++;
1048 if(ep
->retrans_counter
== EIGRP_PACKET_RETRANS_MAX
)
1049 return eigrp_retrans_count_exceeded(ep
, nbr
);
1051 /*Start retransmission timer*/
1052 ep
->t_retrans_timer
= NULL
;
1053 thread_add_timer(master
, eigrp_unack_packet_retrans
, nbr
, EIGRP_PACKET_RETRANS_TIME
,
1054 &ep
->t_retrans_timer
);
1056 /* Hook thread to write packet. */
1057 if (nbr
->ei
->on_write_q
== 0)
1059 listnode_add(nbr
->ei
->eigrp
->oi_write_q
, nbr
->ei
);
1060 nbr
->ei
->on_write_q
= 1;
1062 thread_add_write(master
, eigrp_write
, nbr
->ei
->eigrp
, nbr
->ei
->eigrp
->fd
,
1063 &nbr
->ei
->eigrp
->t_write
);
1070 eigrp_unack_multicast_packet_retrans (struct thread
*thread
)
1072 struct eigrp_neighbor
*nbr
;
1073 nbr
= (struct eigrp_neighbor
*) THREAD_ARG(thread
);
1075 struct eigrp_packet
*ep
;
1076 ep
= eigrp_fifo_tail(nbr
->multicast_queue
);
1080 struct eigrp_packet
*duplicate
;
1081 duplicate
= eigrp_packet_duplicate(ep
, nbr
);
1082 /* Add packet to the top of the interface output queue*/
1083 eigrp_fifo_push_head(nbr
->ei
->obuf
, duplicate
);
1085 ep
->retrans_counter
++;
1086 if(ep
->retrans_counter
== EIGRP_PACKET_RETRANS_MAX
)
1087 return eigrp_retrans_count_exceeded(ep
, nbr
);
1089 /*Start retransmission timer*/
1090 ep
->t_retrans_timer
= NULL
;
1091 thread_add_timer(master
, eigrp_unack_multicast_packet_retrans
, nbr
, EIGRP_PACKET_RETRANS_TIME
,
1092 &ep
->t_retrans_timer
);
1094 /* Hook thread to write packet. */
1095 if (nbr
->ei
->on_write_q
== 0)
1097 listnode_add(nbr
->ei
->eigrp
->oi_write_q
, nbr
->ei
);
1098 nbr
->ei
->on_write_q
= 1;
1100 thread_add_write(master
, eigrp_write
, nbr
->ei
->eigrp
, nbr
->ei
->eigrp
->fd
,
1101 &nbr
->ei
->eigrp
->t_write
);
1107 /* Get packet from tail of fifo. */
1108 struct eigrp_packet
*
1109 eigrp_fifo_pop_tail (struct eigrp_fifo
*fifo
)
1111 struct eigrp_packet
*ep
;
1117 fifo
->tail
= ep
->previous
;
1119 if (fifo
->tail
== NULL
)
1122 fifo
->tail
->next
= NULL
;
1130 struct eigrp_packet
*
1131 eigrp_packet_duplicate (struct eigrp_packet
*old
, struct eigrp_neighbor
*nbr
)
1133 struct eigrp_packet
*new;
1135 new = eigrp_packet_new(nbr
->ei
->ifp
->mtu
);
1136 new->length
= old
->length
;
1137 new->retrans_counter
= old
->retrans_counter
;
1138 new->dst
= old
->dst
;
1139 new->sequence_number
= old
->sequence_number
;
1140 stream_copy(new->s
, old
->s
);
1145 struct TLV_IPv4_Internal_type
*
1146 eigrp_read_ipv4_tlv (struct stream
*s
)
1148 struct TLV_IPv4_Internal_type
*tlv
;
1150 tlv
= eigrp_IPv4_InternalTLV_new ();
1152 tlv
->type
= stream_getw(s
);
1153 tlv
->length
= stream_getw(s
);
1154 tlv
->forward
.s_addr
= stream_getl(s
);
1155 tlv
->metric
.delay
= stream_getl(s
);
1156 tlv
->metric
.bandwith
= stream_getl(s
);
1157 tlv
->metric
.mtu
[0] = stream_getc(s
);
1158 tlv
->metric
.mtu
[1] = stream_getc(s
);
1159 tlv
->metric
.mtu
[2] = stream_getc(s
);
1160 tlv
->metric
.hop_count
= stream_getc(s
);
1161 tlv
->metric
.reliability
= stream_getc(s
);
1162 tlv
->metric
.load
= stream_getc(s
);
1163 tlv
->metric
.tag
= stream_getc(s
);
1164 tlv
->metric
.flags
= stream_getc(s
);
1166 tlv
->prefix_length
= stream_getc(s
);
1168 if (tlv
->prefix_length
<= 8)
1170 tlv
->destination_part
[0] = stream_getc(s
);
1171 tlv
->destination
.s_addr
= (tlv
->destination_part
[0]);
1173 else if (tlv
->prefix_length
> 8 && tlv
->prefix_length
<= 16)
1175 tlv
->destination_part
[0] = stream_getc(s
);
1176 tlv
->destination_part
[1] = stream_getc(s
);
1177 tlv
->destination
.s_addr
= ((tlv
->destination_part
[1] << 8)
1178 + tlv
->destination_part
[0]);
1180 else if (tlv
->prefix_length
> 16 && tlv
->prefix_length
<= 24)
1182 tlv
->destination_part
[0] = stream_getc(s
);
1183 tlv
->destination_part
[1] = stream_getc(s
);
1184 tlv
->destination_part
[2] = stream_getc(s
);
1185 tlv
->destination
.s_addr
= ((tlv
->destination_part
[2] << 16) +
1186 (tlv
->destination_part
[1] << 8) +
1187 tlv
->destination_part
[0]);
1189 else if (tlv
->prefix_length
> 24 && tlv
->prefix_length
<= 32)
1191 tlv
->destination_part
[0] = stream_getc(s
);
1192 tlv
->destination_part
[1] = stream_getc(s
);
1193 tlv
->destination_part
[2] = stream_getc(s
);
1194 tlv
->destination_part
[3] = stream_getc(s
);
1195 tlv
->destination
.s_addr
= ((tlv
->destination_part
[3] << 24) +
1196 (tlv
->destination_part
[2] << 16) +
1197 (tlv
->destination_part
[1] << 8) +
1198 tlv
->destination_part
[0]);
1204 eigrp_add_internalTLV_to_stream (struct stream
*s
,
1205 struct eigrp_prefix_entry
*pe
)
1209 stream_putw(s
, EIGRP_TLV_IPv4_INT
);
1210 if (pe
->destination_ipv4
->prefixlen
<= 8)
1212 stream_putw(s
, 0x001A);
1215 if ((pe
->destination_ipv4
->prefixlen
> 8)
1216 && (pe
->destination_ipv4
->prefixlen
<= 16))
1218 stream_putw(s
, 0x001B);
1221 if ((pe
->destination_ipv4
->prefixlen
> 16)
1222 && (pe
->destination_ipv4
->prefixlen
<= 24))
1224 stream_putw(s
, 0x001C);
1227 if (pe
->destination_ipv4
->prefixlen
> 24)
1229 stream_putw(s
, 0x001D);
1233 stream_putl(s
, 0x00000000);
1236 stream_putl(s
, pe
->reported_metric
.delay
);
1237 stream_putl(s
, pe
->reported_metric
.bandwith
);
1238 stream_putc(s
, pe
->reported_metric
.mtu
[2]);
1239 stream_putc(s
, pe
->reported_metric
.mtu
[1]);
1240 stream_putc(s
, pe
->reported_metric
.mtu
[0]);
1241 stream_putc(s
, pe
->reported_metric
.hop_count
);
1242 stream_putc(s
, pe
->reported_metric
.reliability
);
1243 stream_putc(s
, pe
->reported_metric
.load
);
1244 stream_putc(s
, pe
->reported_metric
.tag
);
1245 stream_putc(s
, pe
->reported_metric
.flags
);
1247 stream_putc(s
, pe
->destination_ipv4
->prefixlen
);
1249 if (pe
->destination_ipv4
->prefixlen
<= 8)
1251 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1253 if ((pe
->destination_ipv4
->prefixlen
> 8)
1254 && (pe
->destination_ipv4
->prefixlen
<= 16))
1256 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1257 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 8) & 0xFF);
1259 if ((pe
->destination_ipv4
->prefixlen
> 16)
1260 && (pe
->destination_ipv4
->prefixlen
<= 24))
1262 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1263 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 8) & 0xFF);
1264 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 16) & 0xFF);
1266 if (pe
->destination_ipv4
->prefixlen
> 24)
1268 stream_putc(s
, pe
->destination_ipv4
->prefix
.s_addr
& 0xFF);
1269 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 8) & 0xFF);
1270 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 16) & 0xFF);
1271 stream_putc(s
, (pe
->destination_ipv4
->prefix
.s_addr
>> 24) & 0xFF);
1278 eigrp_add_authTLV_MD5_to_stream (struct stream
*s
,
1279 struct eigrp_interface
*ei
)
1282 struct keychain
*keychain
;
1283 struct TLV_MD5_Authentication_Type
*authTLV
;
1285 authTLV
= eigrp_authTLV_MD5_new();
1287 authTLV
->type
= htons(EIGRP_TLV_AUTH
);
1288 authTLV
->length
= htons(EIGRP_AUTH_MD5_TLV_SIZE
);
1289 authTLV
->auth_type
= htons(EIGRP_AUTH_TYPE_MD5
);
1290 authTLV
->auth_length
= htons(EIGRP_AUTH_TYPE_MD5_LEN
);
1291 authTLV
->key_sequence
= 0;
1292 memset(authTLV
->Nullpad
,0,sizeof(authTLV
->Nullpad
));
1294 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1296 key
= key_lookup_for_send(keychain
);
1299 free(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1300 IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
= NULL
;
1301 eigrp_authTLV_MD5_free(authTLV
);
1307 authTLV
->key_id
= htonl(key
->index
);
1308 memset(authTLV
->digest
,0,EIGRP_AUTH_TYPE_MD5_LEN
);
1309 stream_put(s
,authTLV
, sizeof(struct TLV_MD5_Authentication_Type
));
1310 eigrp_authTLV_MD5_free(authTLV
);
1311 return EIGRP_AUTH_MD5_TLV_SIZE
;
1314 eigrp_authTLV_MD5_free(authTLV
);
1320 eigrp_add_authTLV_SHA256_to_stream (struct stream
*s
,
1321 struct eigrp_interface
*ei
)
1324 struct keychain
*keychain
;
1325 struct TLV_SHA256_Authentication_Type
*authTLV
;
1327 authTLV
= eigrp_authTLV_SHA256_new();
1329 authTLV
->type
= htons(EIGRP_TLV_AUTH
);
1330 authTLV
->length
= htons(EIGRP_AUTH_SHA256_TLV_SIZE
);
1331 authTLV
->auth_type
= htons(EIGRP_AUTH_TYPE_SHA256
);
1332 authTLV
->auth_length
= htons(EIGRP_AUTH_TYPE_SHA256_LEN
);
1333 authTLV
->key_sequence
= 0;
1334 memset(authTLV
->Nullpad
,0,sizeof(authTLV
->Nullpad
));
1336 keychain
= keychain_lookup(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1338 key
= key_lookup_for_send(keychain
);
1341 free(IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
);
1342 IF_DEF_PARAMS (ei
->ifp
)->auth_keychain
= NULL
;
1343 eigrp_authTLV_SHA256_free(authTLV
);
1349 authTLV
->key_id
= 0;
1350 memset(authTLV
->digest
,0,EIGRP_AUTH_TYPE_SHA256_LEN
);
1351 stream_put(s
,authTLV
, sizeof(struct TLV_SHA256_Authentication_Type
));
1352 eigrp_authTLV_SHA256_free(authTLV
);
1353 return EIGRP_AUTH_SHA256_TLV_SIZE
;
1356 eigrp_authTLV_SHA256_free(authTLV
);
1361 struct TLV_MD5_Authentication_Type
*
1362 eigrp_authTLV_MD5_new ()
1364 struct TLV_MD5_Authentication_Type
*new;
1366 new = XCALLOC(MTYPE_EIGRP_AUTH_TLV
, sizeof(struct TLV_MD5_Authentication_Type
));
1372 eigrp_authTLV_MD5_free (struct TLV_MD5_Authentication_Type
*authTLV
)
1374 XFREE(MTYPE_EIGRP_AUTH_TLV
, authTLV
);
1377 struct TLV_SHA256_Authentication_Type
*
1378 eigrp_authTLV_SHA256_new ()
1380 struct TLV_SHA256_Authentication_Type
*new;
1382 new = XCALLOC(MTYPE_EIGRP_AUTH_SHA256_TLV
, sizeof(struct TLV_SHA256_Authentication_Type
));
1388 eigrp_authTLV_SHA256_free (struct TLV_SHA256_Authentication_Type
*authTLV
)
1390 XFREE(MTYPE_EIGRP_AUTH_SHA256_TLV
, authTLV
);
1393 struct TLV_IPv4_Internal_type
*
1394 eigrp_IPv4_InternalTLV_new ()
1396 struct TLV_IPv4_Internal_type
*new;
1398 new = XCALLOC(MTYPE_EIGRP_IPV4_INT_TLV
,sizeof(struct TLV_IPv4_Internal_type
));
1404 eigrp_IPv4_InternalTLV_free (struct TLV_IPv4_Internal_type
*IPv4_InternalTLV
)
1406 XFREE(MTYPE_EIGRP_IPV4_INT_TLV
, IPv4_InternalTLV
);
1409 struct TLV_Sequence_Type
*
1410 eigrp_SequenceTLV_new ()
1412 struct TLV_Sequence_Type
*new;
1414 new = XCALLOC(MTYPE_EIGRP_SEQ_TLV
,sizeof(struct TLV_Sequence_Type
));