Пример #1
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;
}
Пример #2
0
/*
 * Open and initialize the igmp socket, and fill in the non-changing
 * IP header fields in the output packet buffer.
 */
void initIgmp() {
    struct ip *ip;

    recv_buf = malloc(RECV_BUF_SIZE);
    send_buf = malloc(RECV_BUF_SIZE);

    k_hdr_include(true);    /* include IP header when sending */
    k_set_rcvbuf(256*1024,48*1024); /* lots of input buffering        */
    k_set_ttl(1);       /* restrict multicasts to one hop */
    k_set_loop(false);      /* disable multicast loopback     */

    ip         = (struct ip *)send_buf;
    memset(ip, 0, sizeof(struct ip));
    /*
     * Fields zeroed that aren't filled in later:
     * - IP ID (let the kernel fill it in)
     * - Offset (we don't send fragments)
     * - Checksum (let the kernel fill it in)
     */
    ip->ip_v   = IPVERSION;
    ip->ip_hl  = (sizeof(struct ip) + 4) >> 2; /* +4 for Router Alert option */
    ip->ip_tos = 0xc0;      /* Internet Control */
    ip->ip_ttl = MAXTTL;    /* applies to unicasts only */
    ip->ip_p   = IPPROTO_IGMP;

    allhosts_group   = htonl(INADDR_ALLHOSTS_GROUP);
    allrouters_group = htonl(INADDR_ALLRTRS_GROUP);
    alligmp3_group   = htonl(INADDR_ALLIGMPV3_GROUP);
}
Пример #3
0
/*
 * Open and initialize the igmp socket, and fill in the non-changing
 * IP header fields in the output packet buffer.
 */
void init_igmp(void)
{
    struct ip *ip;

    recv_buf = malloc(RECV_BUF_SIZE);
    send_buf = malloc(RECV_BUF_SIZE);

    if ((igmp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0) 
	logit(LOG_ERR, errno, "IGMP socket");

    k_hdr_include(TRUE);	/* include IP header when sending */
    k_set_rcvbuf(256*1024,48*1024);	/* lots of input buffering        */
    k_set_ttl(1);		/* restrict multicasts to one hop */
    k_set_loop(FALSE);		/* disable multicast loopback     */

    ip         = (struct ip *)send_buf;
    memset(ip, 0, sizeof(struct ip));
    /*
     * Fields zeroed that aren't filled in later:
     * - IP ID (let the kernel fill it in)
     * - Offset (we don't send fragments)
     * - Checksum (let the kernel fill it in)
     */
    ip->ip_v   = IPVERSION;
    ip->ip_hl  = sizeof(struct ip) >> 2;
    ip->ip_tos = 0xc0;		/* Internet Control */
    ip->ip_ttl = MAXTTL;	/* applies to unicasts only */
    ip->ip_p   = IPPROTO_IGMP;

    allhosts_group = htonl(INADDR_ALLHOSTS_GROUP);
    dvmrp_group    = htonl(INADDR_DVMRP_GROUP);
    allrtrs_group  = htonl(INADDR_ALLRTRS_GROUP);
}
Пример #4
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));
}
Пример #5
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)));
}
Пример #6
0
Файл: igmp.c Проект: 42wim/pimd
/*
 * Open and initialize the igmp socket, and fill in the non-changing
 * IP header fields in the output packet buffer.
 */
void init_igmp(void)
{
    struct ip *ip;
    char *router_alert;

    igmp_recv_buf = calloc(1, RECV_BUF_SIZE);
    igmp_send_buf = calloc(1, SEND_BUF_SIZE);
    if (!igmp_recv_buf || !igmp_send_buf)
	logit(LOG_ERR, 0, "Ran out of memory in init_igmp()");

    if ((igmp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0)
	logit(LOG_ERR, errno, "Failed creating IGMP socket in init_igmp()");

    k_hdr_include(igmp_socket, TRUE);	/* include IP header when sending */
    k_set_sndbuf(igmp_socket, SO_SEND_BUF_SIZE_MAX,
		 SO_SEND_BUF_SIZE_MIN); /* lots of output buffering        */
    k_set_rcvbuf(igmp_socket, SO_RECV_BUF_SIZE_MAX,
		 SO_RECV_BUF_SIZE_MIN); /* lots of input buffering        */
    k_set_ttl(igmp_socket, MINTTL);	/* restrict multicasts to one hop */
    k_set_loop(igmp_socket, FALSE);	/* disable multicast loopback     */

    ip	       = (struct ip *)igmp_send_buf;
    memset(ip, 0, IP_IGMP_HEADER_LEN);
    ip->ip_v   = IPVERSION;
    ip->ip_hl  = IP_IGMP_HEADER_LEN >> 2;
    ip->ip_tos = 0xc0;			/* Internet Control   */
    ip->ip_id  = 0;			/* let kernel fill in */
    ip->ip_off = 0;
    ip->ip_ttl = MAXTTL;		/* applies to unicasts only */
    ip->ip_p   = IPPROTO_IGMP;
    ip->ip_sum = 0;			/* let kernel fill in */

    /* Enable RFC2113 IP Router Alert.  Per spec this is required to
     * force certain routers/switches to inspect this frame. */
    router_alert    = igmp_send_buf + sizeof(struct ip);
    router_alert[0] = IPOPT_RA;
    router_alert[1] = 4;
    router_alert[2] = 0;
    router_alert[3] = 0;

    /* Everywhere in the daemon we use network-byte-order */
    allhosts_group   = htonl(INADDR_ALLHOSTS_GROUP);
    allrouters_group = htonl(INADDR_ALLRTRS_GROUP);
    allreports_group = htonl(INADDR_ALLRPTS_GROUP);

    if (register_input_handler(igmp_socket, igmp_read) < 0)
	logit(LOG_ERR, 0, "Failed registering igmp_read() as an input handler in init_igmp()");
}
Пример #7
0
void init_pim()
{//初始化
	allpimrouters=htonl(INADDR_ALLPIM_ROUTERS_GROUP);
	pim_receive_buf=malloc(64*1024);
	pim_send_buf=malloc(64*1024);
	
	if((pimsocket=socket(AF_INET,SOCK_RAW,IPPROTO_PIM))<0)
		log(LOG_ERR,"igmp socket create failed!");

	k_hdr_include(pimsocket,1);//发送的时候包括IP头部
    	k_set_rcvbuf(pimsocket,256*1024,48*1024);
    	k_set_ttl(pimsocket,1);//设置IGMP报文的TTL为1
    	k_set_loop(pimsocket,0);//决定发送的多点广播包不应该被回送

	if(register_input_handler(pimsocket,pim_input)<0)
		log(LOG_ERR,"Couldn't register pim_input as an input handler");
}
Пример #8
0
Файл: pim.c Проект: 42wim/pimd
/*
 * Setup raw kernel socket for PIM protocol and send/receive buffers.
 */
void init_pim(void)
{
    struct ip *ip;

    /* Setup the PIM raw socket */
    if ((pim_socket = socket(AF_INET, SOCK_RAW, IPPROTO_PIM)) < 0)
	logit(LOG_ERR, errno, "Failed creating PIM socket");
    k_hdr_include(pim_socket, TRUE);      /* include IP header when sending */
    k_set_sndbuf(pim_socket, SO_SEND_BUF_SIZE_MAX,
		 SO_SEND_BUF_SIZE_MIN);   /* lots of output buffering        */
    k_set_rcvbuf(pim_socket, SO_RECV_BUF_SIZE_MAX,
		 SO_RECV_BUF_SIZE_MIN);   /* lots of input buffering        */
    k_set_ttl(pim_socket, MINTTL);	  /* restrict multicasts to one hop */
    k_set_loop(pim_socket, FALSE);	  /* disable multicast loopback	    */

    allpimrouters_group = htonl(INADDR_ALL_PIM_ROUTERS);

    pim_recv_buf = calloc(1, RECV_BUF_SIZE);
    pim_send_buf = calloc(1, SEND_BUF_SIZE);
    if (!pim_recv_buf || !pim_send_buf)
	logit(LOG_ERR, 0, "Ran out of memory in init_pim()");

    /* One time setup in the buffers */
    ip		 = (struct ip *)pim_send_buf;
    memset(ip, 0, sizeof(*ip));
    ip->ip_v     = IPVERSION;
    ip->ip_hl    = (sizeof(struct ip) >> 2);
    ip->ip_tos   = 0;    /* TODO: setup?? */
    ip->ip_id    = 0;    /* Make sure to update ID field, maybe fragmenting below */
    ip->ip_off   = 0;
    ip->ip_p     = IPPROTO_PIM;
    ip->ip_sum   = 0;	 /* let kernel fill in */

    if (register_input_handler(pim_socket, pim_read) < 0)
	logit(LOG_ERR, 0,  "Failed registering pim_read() as an input handler");

    /* Initialize the building Join/Prune messages working area */
    build_jp_message_pool = (build_jp_message_t *)NULL;
    build_jp_message_pool_counter = 0;
}