Ejemplo n.º 1
0
/* 
 * Call build_igmp() to build an IGMP message in the output packet buffer.
 * Then send the message from the interface with IP address 'src' to
 * destination 'dst'.
 */
void sendIgmp(uint32_t src, uint32_t dst, int type, int code, uint32_t group, int datalen) {
    struct sockaddr_in sdst;
    int setloop = 0, setigmpsource = 0;

    buildIgmp(src, dst, type, code, group, datalen);

    if (IN_MULTICAST(ntohl(dst))) {
        k_set_if(src);
        setigmpsource = 1;
        if (type != IGMP_DVMRP || dst == allhosts_group) {
            setloop = 1;
            k_set_loop(true);
        }
    }

    memset(&sdst, 0, sizeof(sdst));
    sdst.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
    sdst.sin_len = sizeof(sdst);
#endif
    sdst.sin_addr.s_addr = dst;
    if (sendto(MRouterFD, send_buf,
               IP_HEADER_RAOPT_LEN + IGMP_MINLEN + datalen, 0,
               (struct sockaddr *)&sdst, sizeof(sdst)) < 0) {
        if (errno == ENETDOWN)
            my_log(LOG_ERR, errno, "Sender VIF was down.");
        else
            my_log(LOG_INFO, errno,
                "sendto to %s on %s",
                inetFmt(dst, s1), inetFmt(src, s2));
    }

    if(setigmpsource) {
        if (setloop) {
            k_set_loop(false);
        }
        // Restore original...
        k_set_if(INADDR_ANY);
    }

    my_log(LOG_DEBUG, 0, "SENT %s from %-15s to %s",
	    igmpPacketKind(type, code), src == INADDR_ANY ? "INADDR_ANY" :
	    inetFmt(src, s1), inetFmt(dst, s2));
}
Ejemplo n.º 2
0
int pimdm_output(char *buf,u_int32 src,u_int32 dst,int type,int length)
{//提供缓存,源、目的、类型和长度,发送PIM报文
	struct sockaddr_in sockdst;
	struct ip *ip;
	struct pim *pim;
	int sendlen;
	int setloop=0;
	ip=(struct ip*)buf;
	ip->ip_v=4;
	ip->ip_hl=(sizeof(struct ip)>>2);
	ip->ip_tos=0;
	ip->ip_id=0;
	ip->ip_off=0;
	ip->ip_p=IPPROTO_PIM;
	ip->ip_sum=0;
	ip->ip_len=sizeof(struct ip)+sizeof(struct pim)+length;
	ip->ip_src.s_addr=src;
	ip->ip_dst.s_addr=dst;
	ip->ip_ttl=1;
	sendlen=ip->ip_len;

	pim=(struct pim *)(buf+sizeof(struct ip));
	pim->pim_type=type;
	pim->pim_vers=2;
	pim->pim_cksum=0;
	pim->pim_cksum=inet_cksum((u_int16 *)pim,sizeof(struct pim)+length);

	if(IN_MULTICAST(ntohl(dst)))
	{
		k_set_if(pimsocket,src);
		setloop=1;
		k_set_loop(pimsocket,1);
	}
	bzero((void *)&sockdst,sizeof(sockdst));
    	sockdst.sin_family=AF_INET;
    	sockdst.sin_len=sizeof(sockdst);
	sockdst.sin_addr.s_addr=dst;
    
	if (sendto(pimsocket,pim_send_buf,sendlen,0,(struct sockaddr *)&sockdst,sizeof(sockdst))<0) 
	{	
		if (setloop)
	    		k_set_loop(pimsocket,0);
		return 0;    
	}

	if (setloop)
		k_set_loop(pimsocket,0);
	return 1;
}
Ejemplo n.º 3
0
/* 
 * Call build_igmp() to build an IGMP message in the output packet buffer.
 * Then send the message from the interface with IP address 'src' to
 * destination 'dst'.
 */
void send_igmp(u_int32 src, u_int32 dst, int type, int code, u_int32 group, int datalen)
{
    struct sockaddr_in sdst;
    int setloop = 0;
    size_t len;

    len = build_igmp(src, dst, type, code, group, datalen);

    if (IN_MULTICAST(ntohl(dst))) {
	k_set_if(src);
	if (type != IGMP_DVMRP || dst == allhosts_group) {
	    setloop = 1;
	    k_set_loop(TRUE);
	}
    }

    memset(&sdst, 0, sizeof(sdst));
    sdst.sin_family = AF_INET;
#ifdef HAVE_SA_LEN
    sdst.sin_len = sizeof(sdst);
#endif
    sdst.sin_addr.s_addr = dst;
    if (sendto(igmp_socket, send_buf, len, 0, (struct sockaddr *)&sdst, sizeof(sdst)) < 0) {
	if (errno == ENETDOWN)
	    check_vif_state();
	else
	    logit(igmp_log_level(type, code), errno,
		"sendto to %s on %s",
		inet_fmt(dst, s1, sizeof(s1)), inet_fmt(src, s2, sizeof(s2)));
    }

    if (setloop)
	    k_set_loop(FALSE);

    IF_DEBUG(DEBUG_PKT|igmp_debug_kind(type, code))
    logit(LOG_DEBUG, 0, "SENT %s from %-15s to %s",
	igmp_packet_kind(type, code), src == INADDR_ANY ? "INADDR_ANY" :
				 inet_fmt(src, s1, sizeof(s1)), inet_fmt(dst, s2, sizeof(s2)));
}