FreeBSD/sbin/routed/rdisc.c
/* Send a router discovery advertisement or solicitation ICMP packet.
 */
Send a router discovery advertisement or solicitation ICMP packet.
Send a router discovery advertisement or solicitation ICMP packet .
static void
send_rdisc(union ad_u *p,
	   int p_size,
	   struct interface *ifp,
	   naddr dst,			
	   int	type)			
{
	struct sockaddr_in rsin;
	int flags;
	const char *msg;
	memset(&rsin, 0, sizeof(rsin));
	rsin.sin_addr.s_addr = dst;
	rsin.sin_family = AF_INET;
#ifdef _HAVE_SIN_LEN
	rsin.sin_len = sizeof(rsin);
#endif
	flags = MSG_DONTROUTE;
	switch (type) {
	case 0:				
	default:
		msg = "Send";
		break;
	case 1:				
		if (ifp->int_if_flags & IFF_POINTOPOINT) {
			msg = "Send pt-to-pt";
			rsin.sin_addr.s_addr = ifp->int_dstaddr;
		} else {
			msg = "Send broadcast";
			rsin.sin_addr.s_addr = ifp->int_brdaddr;
		}
		break;
	case 2:				
		msg = "Send multicast";
		if (ifp->int_state & IS_DUP) {
			trace_act("abort multicast output via %s"
				  " with duplicate address",
				  ifp->int_name);
			return;
		}
		if (rdisc_sock_mcast != ifp) {
			struct ip_mreqn mreqn;
			memset(&mreqn, 0, sizeof(struct ip_mreqn));
			mreqn.imr_ifindex = ifp->int_index;
			if (0 > setsockopt(rdisc_sock,
					   IPPROTO_IP, IP_MULTICAST_IF,
					   &mreqn,
					   sizeof(mreqn))) {
				LOGERR("setsockopt(rdisc_sock,"
				       "IP_MULTICAST_IF)");
				rdisc_sock_mcast = NULL;
				return;
			}
			rdisc_sock_mcast = ifp;
		}
		flags = 0;
		break;
	}
	if (rdisc_sock < 0)
		get_rdisc_sock();
	trace_rdisc(msg, (ifp ? ifp->int_addr : 0), rsin.sin_addr.s_addr, ifp,
		    p, p_size);
	if (0 > sendto(rdisc_sock, p, p_size, flags,
		       (struct sockaddr *)&rsin, sizeof(rsin))) {
		if (ifp == NULL || !(ifp->int_state & IS_BROKE))
			msglog("sendto(%s%s%s): %s",
			       ifp != NULL ? ifp->int_name : "",
			       ifp != NULL ? ", " : "",
			       inet_ntoa(rsin.sin_addr),
			       strerror(errno));
		if (ifp != NULL)
			if_sick(ifp);
	}
}
static void send_rdisc ( union ad_u * p , int p_size , struct interface * ifp , naddr dst , int type ) { struct sockaddr_in rsin ; int flags ; const char * msg ; memset ( & rsin , 0 , sizeof ( rsin ) ) ; rsin . sin_addr . s_addr = dst ; rsin . sin_family = AF_INET ; #ifdef _HAVE_SIN_LEN rsin . sin_len = sizeof ( rsin ) ; #endif flags = MSG_DONTROUTE ; switch ( type ) { case 0 : default : msg = " " ; break ; case 1 : if ( ifp -> int_if_flags & IFF_POINTOPOINT ) { msg = " " ; rsin . sin_addr . s_addr = ifp -> int_dstaddr ; } else { msg = " " ; rsin . sin_addr . s_addr = ifp -> int_brdaddr ; } break ; case 2 : msg = " " ; if ( ifp -> int_state & IS_DUP ) { trace_act ( " " " " , ifp -> int_name ) ; return ; } if ( rdisc_sock_mcast != ifp ) { struct ip_mreqn mreqn ; memset ( & mreqn , 0 , sizeof ( struct ip_mreqn ) ) ; mreqn . imr_ifindex = ifp -> int_index ; if ( 0 > setsockopt ( rdisc_sock , IPPROTO_IP , IP_MULTICAST_IF , & mreqn , sizeof ( mreqn ) ) ) { LOGERR ( " " " " ) ; rdisc_sock_mcast = NULL ; return ; } rdisc_sock_mcast = ifp ; } flags = 0 ; break ; } if ( rdisc_sock < 0 ) get_rdisc_sock ( ) ; trace_rdisc ( msg , ( ifp ? ifp -> int_addr : 0 ) , rsin . sin_addr . s_addr , ifp , p , p_size ) ; if ( 0 > sendto ( rdisc_sock , p , p_size , flags , ( struct sockaddr * ) & rsin , sizeof ( rsin ) ) ) { if ( ifp == NULL || ! ( ifp -> int_state & IS_BROKE ) ) msglog ( " " , ifp != NULL ? ifp -> int_name : " " , ifp != NULL ? " " : " " , inet_ntoa ( rsin . sin_addr ) , strerror ( errno ) ) ; if ( ifp != NULL ) if_sick ( ifp ) ; } }
Send a router discovery advertisement or solicitation ICMP packet.
Send a router discovery advertisement or solicitation ICMP packet .
/* 0 or unicast destination */ /* 0=unicast, 1=bcast, 2=mcast */ /* unicast */ /* broadcast */ /* multicast */ /* select the right interface. */