Ejemplo n.º 1
0
const char * Nes_File_Reader::begin( Auto_File_Reader dr )
{
	RETURN_ERR( dr.open() );
	in = dr;
	RETURN_ERR( read_header() );
	if ( block_type() != group_begin )
		return "File is wrong type";
	return enter_group();
}
Ejemplo n.º 2
0
Archivo: igmp.c Proyecto: hchunhui/pop
void process_igmp(struct map *group_table, uint32_t src_ip, const uint8_t *buffer, int len)
{
	if( checksum(buffer, len) != 0)
		return;
	if(len == IGMP_HEADER_LEN){ 	//igmp v1, v2`
		const struct igmphdr *igmp = (const struct igmphdr *) buffer;
		uint32_t groupid = igmp->groupid;

		switch( igmp->type ){
			case QUERY_REPORT:
				/*controller cannot receive query report packet*/
				break;
			case V1_MEMBERSHIP_REPORT:
				/*same as V2_MEMBERSHIP_REPORT...*/
			case V2_MEMBERSHIP_REPORT:
				enter_group(group_table, groupid, src_ip);
				break;
			case V2_LEAVE_GROUP:
				exit_group(group_table, groupid, src_ip);
				break;
			default:
				/*error*/
				break;
		}
	}else if(len >= IGMP_V3_REPORT_HEADER_LEN){ //igmp v3
		const struct igmpv3_report *igmpv3_pkt = (const struct igmpv3_report *) buffer;
		/*only deal with membership report*/
		if(igmpv3_pkt->type != V3_MEMBERSHIP_REPORT)
			return;
		uint16_t ngrecord = ntohs(igmpv3_pkt->ngrecord);
		const uint8_t *grecord = (const uint8_t *) igmpv3_pkt->grec;
		int i;

		/*deal with each record*/
		for(i = 0; i < ngrecord; i++){
			uint8_t grec_type = *grecord++;
			uint8_t grec_auxdlen = *grecord++; //一般为0,不为0,则要跳过末尾的grec_auxdlen个字节
			uint16_t grec_nsrc = ntohs(*((const uint16_t *)grecord));
			grecord += sizeof(uint16_t);
			uint32_t grec_mcaddr = ntohl(*((const uint32_t *)grecord));
			grecord += sizeof(uint32_t);

			switch( grec_type ){
				case V3_MODE_IS_INCLUDE: 	//接收来自源,如果源为空则, 为退出报告,否则加入组
					if( grec_nsrc == 0){ //INCLUDE{}, 表示退出报告
						exit_group(group_table, grec_mcaddr, src_ip);
					}else{ //不为0,表示对源进行控制,现在不对源进行控制,只进行插入
						enter_group(group_table, grec_mcaddr, src_ip);
					}
					break;
				case V3_MODE_IS_EXCLUDE:
					if( grec_nsrc == 0){ //EXCLUDE{}, 表示组加入报告
						enter_group(group_table, grec_mcaddr, src_ip);
					}else{ //不为0,表示对源进行控制,现在不对源进行控制,只进行插入
						enter_group(group_table, grec_mcaddr, src_ip);
					}
					break;
				case V3_CHANGE_TO_INCLUDE: //源地址不为空,则当做插入,否则当做退出操作
					if( grec_nsrc == 0){
						exit_group(group_table, grec_mcaddr, src_ip);
					}else{
						enter_group(group_table, grec_mcaddr, src_ip);
					}
					break;
				case V3_CHANGE_TO_EXCLUDE: //暂时当做插入处理
					enter_group(group_table, grec_mcaddr, src_ip);
					break;
				case V3_ALLOW_NEW_SOURCE: //不处理
					break;
				case V3_BLOCK_OLD_SOURCE: //不处理
					break;
				default:
					/*error*/
					break;
			}
			grecord += sizeof(uint32_t) * grec_nsrc + grec_auxdlen; //step to next record
		}
	}else{
		/*error, drop */
		return;
	}
	return;
}