⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipp.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 5 页
字号:
	len += 8;

    return len;
}

void ipv6_compressed_output(lowpan_pkt_t *pkt, const uint8_t next_header,
			    uint8_t hc2_enc, bool hc2_present)
{
    lowpan_pkt_t *p;
    uint8_t hc1_enc = 0;

    /* HC2 compression */
    if (hc2_present) {
	hc1_enc |= HC1_HC2_PRESENT;
    } else {    
	hc1_enc |= HC1_HC2_NONE;
    }

    /* next header */
    switch (next_header) {
    case NEXT_HEADER_UDP:
	hc1_enc |= HC1_NEXTHDR_UDP;
	break;
    case NEXT_HEADER_ICMP6:
	hc1_enc |= HC1_NEXTHDR_ICMP;
	break;
    case NEXT_HEADER_TCP:
	hc1_enc |= HC1_NEXTHDR_TCP;
	break;
    default:
	hc1_enc |= HC1_NEXTHDR_INLINE;

	pkt->header_begin -= sizeof(next_header);
	pkt->header_len += sizeof(next_header);
	*(pkt->header_begin) = next_header;
	break;
    }

    /* we're always sending packets with TC anf FL zero */
    hc1_enc |= HC1_TCFL_ZERO;
    
    /* destination address interface identifier */
    hc1_enc |= HC1_DST_IFACEID_INLINE;
    
    pkt->header_begin -= 8;
    pkt->header_len += 8;
    memcpy(pkt->header_begin, ((void*)&(pkt->ip_dst_addr)) + 8, 8);

    /* destination address prefix */
    if (ipv6_addr_is_linklocal_unicast(&pkt->ip_dst_addr)) {
	hc1_enc |= HC1_DST_PREFIX_LINKLOCAL;
    } else {
	hc1_enc |= HC1_DST_PREFIX_INLINE;

	pkt->header_begin -= 8;
	pkt->header_len += 8;
	memcpy(pkt->header_begin, &(pkt->ip_dst_addr), 8);
    }

    /* source address interface identifier */
    hc1_enc |= HC1_SRC_IFACEID_INLINE;
    
    pkt->header_begin -= 8;
    pkt->header_len += 8;
    memcpy(pkt->header_begin, ((void*)&(pkt->ip_src_addr)) + 8, 8);

    /* source address prefix */
    if (ipv6_addr_is_linklocal_unicast(&pkt->ip_src_addr)) {
	hc1_enc |= HC1_SRC_PREFIX_LINKLOCAL;
    } else {
	hc1_enc |= HC1_SRC_PREFIX_INLINE;

	pkt->header_begin -= 8;
	pkt->header_len += 8;
	memcpy(pkt->header_begin, &(pkt->ip_src_addr), 8);
    }

    /* Hop Limit */
    pkt->header_begin -= sizeof(uint8_t);
    pkt->header_len += sizeof(uint8_t);
    *pkt->header_begin = IP_HOP_LIMIT;
    
    /* HC2 encoding field */
    if (hc2_present) {
	pkt->header_begin -= sizeof(uint8_t);
	pkt->header_len += sizeof(uint8_t);
	*(pkt->header_begin) = hc2_enc;
    }

    /* HC1 encoding field */
    pkt->header_begin -= sizeof(uint8_t);
    pkt->header_len += sizeof(uint8_t);
    *(pkt->header_begin) = hc1_enc;

    /* set 6lowpan dispatch value */
    pkt->header_begin -= sizeof(uint8_t);
    pkt->header_len += sizeof(uint8_t);
    *(pkt->header_begin) = DISPATCH_COMPRESSED_IPV6;

    /* append pkt to send queue */
    if(!send_queue) {
	send_queue = pkt;
    } else {
	for(p=send_queue; p->next; p=p->next);
	p->next = pkt;
    }

    /* schedule sendTask */
    post sendTask();
}

void icmpv6_output(lowpan_pkt_t *pkt,
		   uint8_t type, uint8_t code)
{
    struct icmp6_hdr *hdr;
    uint16_t cksum = 0;
    /* fill in the source address if not set */
    if (ipv6_addr_is_zero(&pkt->ip_src_addr)) {
	memcpy(&pkt->ip_src_addr,
	       determine_src_ipv6_addr(&pkt->ip_dst_addr),
	       sizeof(pkt->ip_src_addr));
    }

    /* fill in the ICMPv6 header */
    pkt->header_begin -= sizeof(struct icmp6_hdr);
    pkt->header_len += sizeof(struct icmp6_hdr);
    hdr = (struct icmp6_hdr *) pkt->header_begin;

    hdr->type = type;
    hdr->code = code;

    /* calculate the  checksum */
    set_16t(&hdr->cksum, 0);
    cksum = ipv6_chksum(&pkt->ip_src_addr, &pkt->ip_dst_addr,
			NEXT_HEADER_ICMP6,
			pkt->header_len + pkt->app_data_len, cksum);
    cksum = ip_chksum((void*)hdr, sizeof(struct icmp6_hdr), cksum);
    cksum = ip_chksum(pkt->app_data_begin, pkt->app_data_len,
			   cksum);
    cksum = ~cksum;
    set_16t(&hdr->cksum, cksum);
    
    ipv6_compressed_output(pkt, NEXT_HEADER_ICMP6, 0, FALSE);
}

error_t udp_uncompressed_output(void* buf, uint16_t len,
				const ip6_addr_t *src_addr,
				const ip6_addr_t *dst_addr,
				uint16_t src_port,
				uint16_t dst_port,
				uint8_t udp_client_num)
{
    struct udp_hdr *hdr;
    lowpan_pkt_t *pkt;
    uint16_t cksum = 0;

    if (!dst_addr) return FAIL;

    pkt = call SendPktPool.get();
    if (!pkt) return FAIL;

    lowpan_pkt_clear(pkt);
    
    /* set the UDPCliemt number to allow for signalling sendDone */
    pkt->notify_num = udp_client_num;

    /* set application data */
    pkt->app_data = buf;
    pkt->app_data_begin = buf;
    pkt->app_data_len = len;
    
    /* set IP addresses */
    memcpy(&pkt->ip_dst_addr, dst_addr, sizeof(pkt->ip_dst_addr));
    if (src_addr) {
	memcpy(&pkt->ip_src_addr, src_addr, sizeof(pkt->ip_src_addr));
    } else {
	memcpy(&pkt->ip_src_addr,
	       determine_src_ipv6_addr(dst_addr),
	       sizeof(pkt->ip_src_addr));
    }

    /* fill in the UDP header */
    pkt->header_begin -= sizeof(struct udp_hdr);
    pkt->header_len += sizeof(struct udp_hdr);
    hdr = (struct udp_hdr *) pkt->header_begin;
    /* src port */
    set_16t(&hdr->srcport, src_port);
    /* dst port */
    set_16t(&hdr->dstport, dst_port);
    /* length */
    set_16t(&hdr->len,htons(len + sizeof(struct udp_hdr)));
    /* checksum */
    set_16t(&hdr->chksum, 0);
    cksum = ip_chksum((uint8_t*) hdr, sizeof(struct udp_hdr), cksum);
    cksum = ipv6_chksum(&pkt->ip_dst_addr,
			&pkt->ip_src_addr,
			NEXT_HEADER_UDP,
			sizeof(struct udp_hdr) + len, cksum);
    cksum = ip_chksum(buf, len, cksum);
    if (cksum != 0xFFFF) {
	cksum = ~cksum;
    }
    set_16t(&hdr->chksum, cksum);

    ipv6_compressed_output(pkt, NEXT_HEADER_UDP, 0, FALSE);

    return SUCCESS;
}

error_t udp_compressed_output(void* buf, uint16_t len,
			      const ip6_addr_t *src_addr,
			      const ip6_addr_t *dst_addr,
			      uint16_t src_port,
			      uint16_t dst_port,
			      uint8_t udp_client_num)
{
    lowpan_pkt_t *pkt;
    uint16_t cksum = 0;
    uint16_t hc2_enc = 0;
    uint16_t udp_len = htons(len + sizeof(struct udp_hdr));

    if (!dst_addr) return FAIL;

    pkt = call SendPktPool.get();
    if (!pkt) return FAIL;

    lowpan_pkt_clear(pkt);
    
    /* set the UDPCliemt number to allow for signalling sendDone */
    pkt->notify_num = udp_client_num;

    /* set application data */
    pkt->app_data = buf;
    pkt->app_data_begin = buf;
    pkt->app_data_len = len;
    
    /* set IP addresses */
    memcpy(&pkt->ip_dst_addr, dst_addr, sizeof(pkt->ip_dst_addr));
    if (src_addr) {
	memcpy(&pkt->ip_src_addr, src_addr, sizeof(pkt->ip_src_addr));
    } else {
	memcpy(&pkt->ip_src_addr,
	       determine_src_ipv6_addr(dst_addr),
	       sizeof(pkt->ip_src_addr));
    }

    /* Checksum */
    cksum = 0;
    cksum = ip_chksum((void*) &src_port, sizeof(src_port), cksum);
    cksum = ip_chksum((void*) &dst_port, sizeof(src_port), cksum);
    cksum = ip_chksum((void*) &udp_len, sizeof(udp_len), cksum);
    cksum = ipv6_chksum(&pkt->ip_dst_addr,
			&pkt->ip_src_addr,
			NEXT_HEADER_UDP,
			sizeof(struct udp_hdr) + len, cksum);
    cksum = ip_chksum(buf, len, cksum);
    if (cksum != 0xFFFF) {
	cksum = ~cksum;
    }

    /* HC_UDP encoding */
    /* Checksum */
    pkt->header_begin -= sizeof(cksum);
    pkt->header_len += sizeof(cksum);
    set_16t(pkt->header_begin, cksum);

    /* Length */
    //hc2_enc |= HC2_UDP_LEN_COMPR;
    hc2_enc |= HC2_UDP_LEN_INLINE;
    pkt->header_begin -= sizeof(udp_len);
    pkt->header_len += sizeof(udp_len);
    set_16t(pkt->header_begin, udp_len);

    /* Destination Port */
    hc2_enc |= HC2_UDP_DST_PORT_INLINE;
    pkt->header_begin -= sizeof(dst_port);
    pkt->header_len += sizeof(dst_port);
    set_16t(pkt->header_begin, dst_port);

    /* Source Port */
    hc2_enc |= HC2_UDP_SRC_PORT_INLINE;
    pkt->header_begin -= sizeof(src_port);
    pkt->header_len += sizeof(src_port);
    set_16t(pkt->header_begin, src_port);
    
    ipv6_compressed_output(pkt, NEXT_HEADER_UDP, hc2_enc, TRUE);

    return SUCCESS;
}
/* ========================== IPv6 - input ================================= */
void icmpv6_input(uint8_t* buf, uint16_t len)
{
    lowpan_pkt_t *pkt;
    struct icmp6_hdr *hdr = (struct icmp6_hdr *)buf;

    /* Compute and check the IP header checksum. */
    if (ipv6_chksum_data(&rx_pkt.ip_src_addr, &rx_pkt.ip_dst_addr,
		    NEXT_HEADER_ICMP6, buf, len, 0)
	!= 0xffff) {
#ifdef ENABLE_PRINTF_DEBUG
	printf("icmpv6_input(): checksum failed\n");
	call PrintfFlush.flush();
#endif /* ENABLE_PRINTF_DEBUG */
	call Leds.led0Toggle();
	return;
    }

    buf += sizeof(struct icmp6_hdr);
    len -= sizeof(struct icmp6_hdr);
    
    switch (hdr->type) {
    case ICMP_TYPE_ECHO_REQUEST:
	/* ICMP code has to be 0 */
	if (hdr->code != 0) {
	    return;
	}
	
	call Leds.led2Toggle();
 	/* send back an ICMP ECHO REPLY */

	/* allocate a packet for the reply */
	pkt = call SendPktPool.get();
	if (!pkt) {
#ifdef ENABLE_PRINTF_DEBUG
	    printf("icmpv6_input() - failed to alloc pkt\n");
	    call PrintfFlush.flush();
#endif /* ENABLE_PRINTF_DEBUG */
	    return;
	}
	lowpan_pkt_clear(pkt);
	
	/* copy/set ICMP data */
	if (rx_pkt.app_data) {
	    /* fragment reassembly took place - ICMP data is in app_data buf */
	    pkt->app_data = rx_pkt.app_data;
	    pkt->app_data_begin = buf;
	    pkt->app_data_len = len;
	    pkt->app_data_dealloc = rx_pkt.app_data_dealloc;

	    rx_pkt.app_data_dealloc = APP_DATA_DEALLOC_FALSE;
	    rx_pkt.app_data = NULL;
	} else {
	    /* there is no app_data buf, everything fits into the header buf */
	    pkt->header_begin -= len;
	    my_memcpy(pkt->header_begin, buf, len);
	    pkt->app_data_begin = pkt->header_begin;
	    pkt->app_data_len = len;
	}
	
	/* set destination address */
	memcpy(&pkt->ip_dst_addr, &rx_pkt.ip_src_addr,
	       sizeof(pkt->ip_dst_addr));
	// source address determined automatically

	icmpv6_output(pkt, ICMP_TYPE_ECHO_REPLY, 0);
	break;
    case ICMP_TYPE_ECHO_REPLY:
	break;
	
    }
}

/* UDP input processing. */
void udp_input(uint8_t* buf, uint16_t len)
{
    struct udp_conn *conn;
    int c;
    struct udp_hdr *hdr = (struct udp_hdr *)buf;
    
    /* Compute and check the IP header checksum. */
    if (ipv6_chksum_data(&rx_pkt.ip_src_addr, &rx_pkt.ip_dst_addr,
		    NEXT_HEADER_UDP, buf, len, 0)
	!= 0xffff) {
#ifdef ENABLE_PRINTF_DEBUG
	printf("udp_input(): checksum failed\n");
	call PrintfFlush.flush();
#endif /* ENABLE_PRINTF_DEBUG */
	call Leds.led0Toggle();
	return;
    }

    if (htons(len) != hdr->len) {
#ifdef ENABLE_PRINTF_DEBUG
	printf("length check failed\n");
	printf("reported length: %d\n", len);
	printf("UDP header len: %d\n", ntohs(hdr->len));
	call PrintfFlush.flush();
#endif /* ENABLE_PRINTF_DEBUG */
	return;
    }
    /* Scan the list of UDP sockets and look for one that is accepting
       this port */
    for (c = 0, conn = udp_conns; c < COUNT_UDP_CONNS; c++, conn++) {
	/*
	printf("lport: 0x%X\n", conn->lport);
	printf("rport: 0x%X\n", conn->rport);
	printf("conn->ripaddr: ");
	dump_serial_packet(&(conn->ripaddr), sizeof(ip6_addr_t));
	printf("src_addr: ");
	dump_serial_packet(src_addr, sizeof(ip6_addr_t));
	*/
	if ( (conn->lport != 0 && conn->lport == hdr->dstport) &&
	     (conn->rport == 0 || conn->rport == hdr->srcport) &&
	     (ipv6_addr_is_zero(&(conn->ripaddr)) ||
	      (cmp_ipv6_addr(&conn->ripaddr, &rx_pkt.ip_src_addr) == 0))
	     )
	    goto udp_match_found;
    }
#ifdef ENABLE_PRINTF_DEBUG
    printf("udp_input(): no connection matched - dropping UDP packet\n");
    call PrintfFlush.flush();
#endif /* ENABLE_PRINTF_DEBUG */
    return;
    
 udp_match_found:
    len -= sizeof(struct udp_hdr);
    if (len > 0) {
	signal UDPClient.receive[c](&rx_pkt.ip_src_addr, ntohs(hdr->srcport),
				    buf+sizeof(struct udp_hdr), len);
    }
}

void udp_input_compressed(uint8_t* buf, uint16_t len, uint8_t hc2_enc)
{
    struct udp_conn *conn;
    int c;
    uint16_t src_port;
    uint16_t dst_port;
    uint16_t chksum;
    uint16_t tmp_chksum;
    uint16_t tmp_len;
    
    /* UDP Source Port */
    if ((hc2_enc & HC2_UDP_SRC_PORT_MASK) == HC2_UDP_SRC_PORT_INLINE) {
	src_port = get_16t(buf);
	buf += sizeof(src_port);
	len -= sizeof(src_port);
    } else {
	//TODO

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -