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

📄 serial_tun.c

📁 tinyos2.0版本驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2007 Matus Harvan * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * *     * Redistributions of source code must retain the above copyright *       notice, this list of conditions and the following disclaimer. *     * Redistributions in binary form must reproduce the above *       copyright notice, this list of conditions and the following *       disclaimer in the documentation and/or other materials provided *       with the distribution. *     * The name of the author may not be used to endorse or promote *       products derived from this software without specific prior *       written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <string.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <arpa/inet.h>#include <netdb.h>#include <stdarg.h>#include "tun_dev.h"#include "serialsource.h"#include "serialpacket.h"#include "6lowpan.h"#define min(a,b) ( (a>b) ? b : a )#define max(a,b) ( (a>b) ? a : b )static char *msgs[] = {  "unknown_packet_type",  "ack_timeout"	,  "sync"	,  "too_long"	,  "too_short"	,  "bad_sync"	,  "bad_crc"	,  "closed"	,  "no_memory"	,  "unix_error"};/* global variables */lowpan_pkt_t *fragments = NULL; /* fragment reassembly of received frames *///lowpan_pkt_t *send_queue = NULL;int g_send_pending = 0;hw_addr_t hw_addr;serial_source ser_src;int tun_fd = 0; /* tunnel device *///int ser_fd = 0; /* serial device */uint16_t g_dgram_tag = 0; /* datagram_tag for sending fragmented packets *//* ------------------------------------------------------------------------- *//* function pre-declarations */int serial_output_am_payload(uint8_t *buf, int len,			     const hw_addr_t *hw_src_addr,			     const hw_addr_t *hw_dst_addr);int serial_input_layer3(uint8_t *buf, int len,			const hw_addr_t *hw_src_addr,			const hw_addr_t *hw_dst_addr);int serial_input_ipv6_uncompressed(uint8_t *buf, int len,				   const hw_addr_t *hw_src_addr,				   const hw_addr_t *hw_dst_addr);int serial_input_ipv6_compressed(uint8_t *buf, int len,				 const hw_addr_t *hw_src_addr,				 const hw_addr_t *hw_dst_addr);/* ------------------------------------------------------------------------- *//* utility functions */int get_ser_fd(){    return serial_source_fd(ser_src);}void increment_g_dgram_tag(){    uint16_t tmp = ntohs(g_dgram_tag);    if (tmp == 0xFFFF) {	tmp = 0;    } else {	tmp++;    }    g_dgram_tag = htons(tmp);}void stderr_msg(serial_source_msg problem){  fprintf(stderr, "Note: %s\n", msgs[problem]);}intdebug(const char *fmt, ...){    int result;    va_list ap;    va_start(ap, fmt);    result = vfprintf(stderr, fmt, ap);    va_end(ap);    return result;}/* from contiki-2.x/tools/tunslip.c */intssystem(const char *fmt, ...){  char cmd[128];  va_list ap;  va_start(ap, fmt);  vsnprintf(cmd, sizeof(cmd), fmt, ap);  va_end(ap);  printf("%s\n", cmd);  fflush(stdout);  return system(cmd);}/* print char* in hex format */void dump_serial_packet(const unsigned char *packet, const int len) {    int i;    printf("len: %d\n", len);    if (!packet)	return;    for (i = 0; i < len; i++) {	printf("%02x ", packet[i]);	//printf("%02x(%c) ", packet[i], packet[i]);	//printf("%c", packet[i]);    }    putchar('\n');/*     printf("---\n"); *//*     for (i = 0; i < len; i++) { *//* 	printf("%c", packet[i]); *//*     } *//*     putchar('\n'); *//*     printf("---\n"); */}/* ------------------------------------------------------------------------- *//* ip6_addr_t and hw_addr_t utility functions */int ipv6_addr_is_zero(const ip6_addr_t *addr){    int i;    for (i=0;i<16;i++) {	if (addr->addr[i]) {	    return 0;	}    }    return 1;}int ipv6_addr_is_linklocal_unicast(const ip6_addr_t *addr){    if (   addr->addr[0] == 0xFE	   && addr->addr[1] == 0x80	   && addr->addr[2] == 0	   && addr->addr[3] == 0	   && addr->addr[4] == 0	   && addr->addr[5] == 0	   && addr->addr[6] == 0	   && addr->addr[7] == 0	   )	return 1;    else	return 0;}int cmp_ipv6_addr(const ip6_addr_t *addr1, const ip6_addr_t *addr2){    return memcmp(addr1, addr2, sizeof(ip6_addr_t));}int cmp_hw_addr(const hw_addr_t *addr1, const hw_addr_t *addr2){    // for short addresses compare only the first two bytes    if (addr1->type == HW_ADDR_SHORT && addr2->type == HW_ADDR_SHORT) {	return memcmp(addr1->addr_short, addr2->addr_short,		      sizeof(addr1->addr_short));    } else {	return memcmp(addr1, addr2, sizeof(hw_addr_t));    }}int hw_addr_is_broadcat(const hw_addr_t *hw_addr){    if (hw_addr->type == HW_ADDR_SHORT	&& hw_addr->addr_short[0] == 0xFF  && hw_addr->addr_short[1] == 0xFF)	return 1;    // TODO: long address    else return 0;}/* ------------------------------------------------------------------------- *//* more utility functions */void clear_pkt(lowpan_pkt_t *pkt){    memset(pkt, 0, sizeof(*pkt));    pkt->buf_begin = pkt->buf + LOWPAN_OVERHEAD;}void free_frag_list(frag_info_t *p){    frag_info_t *q;    while (p) {	q = p->next;	free(p);	p = q;    }}void free_lowpan_pkt(lowpan_pkt_t *pkt){    lowpan_pkt_t *p;    lowpan_pkt_t **q;    if (!fragments) return;    for(q=&fragments; *q; q=&(*q)->next) {	if (*q == pkt) {	    p = *q;	    *q = p->next;	    free_frag_list(p->frag_list);	    free(p);	    return;	}    }}lowpan_pkt_t * find_fragment(hw_addr_t *hw_src_addr, hw_addr_t *hw_dst_addr,			     uint16_t dgram_size, uint16_t dgram_tag){    lowpan_pkt_t *p;    for(p=fragments; p; p=p->next) {	if ((p->dgram_tag == dgram_tag)	    && (p->dgram_size == dgram_size)	    && cmp_hw_addr(&p->hw_src_addr, hw_src_addr) == 0	    && cmp_hw_addr(&p->hw_dst_addr, hw_dst_addr) == 0	    ) {	    return p;	}    }    return NULL;}/* ------------------------------------------------------------------------- *//* HC1 and HC2 compression and decompresstion functions *//* the caller has to free() new_buf */int lowpan_decompress(uint8_t *buf, int len,		       const hw_addr_t *hw_src_addr,		       const hw_addr_t *hw_dst_addr,		       uint8_t **new_buf, int *new_len){    uint8_t hc1_enc;    uint8_t hc2_enc;    struct ip6_hdr *ip_hdr = NULL;    struct udp_hdr *udp_hdr = NULL;        *new_buf = malloc(len + sizeof(*ip_hdr) + sizeof(*udp_hdr));    if (!*new_buf) {	fprintf(stderr, "%s: out of memory\n", __func__);	*new_len = 0;	return 1;    }    hc1_enc = *buf;    buf += sizeof(hc1_enc);    len -= sizeof(hc1_enc);    /* HC2 encoding follows HC1 encoding */    if ((hc1_enc & HC1_HC2_MASK) == HC1_HC2_PRESENT) {	hc2_enc = *buf;	buf += sizeof(hc2_enc);	len -= sizeof(hc2_enc);    }    /* IP header fields */    ip_hdr = (struct ip6_hdr *) *new_buf;    memset(ip_hdr, 0, sizeof(struct ip6_hdr));    ip_hdr->vtc |= IPV6_VERSION;    ip_hdr->hlim = *buf;    buf += sizeof(ip_hdr->hlim);    len -= sizeof(ip_hdr->hlim);    /* source IP address */    if ((hc1_enc & HC1_SRC_PREFIX_MASK) == HC1_SRC_PREFIX_INLINE) {	memcpy(&ip_hdr->src_addr, buf, sizeof(ip_hdr->src_addr)/2);	buf += sizeof(ip_hdr->src_addr)/2;	len -= sizeof(ip_hdr->src_addr)/2;    } else {	ip_hdr->src_addr.addr[0] = 0xFE;	ip_hdr->src_addr.addr[1] = 0x80;    }         if ((hc1_enc & HC1_SRC_IFACEID_MASK) == HC1_SRC_IFACEID_INLINE) {	memcpy(((void*)&ip_hdr->src_addr) + sizeof(ip_hdr->src_addr)/2,	       buf, sizeof(ip_hdr->src_addr)/2);	buf += sizeof(ip_hdr->src_addr)/2;	len -= sizeof(ip_hdr->src_addr)/2;    }    /* destination IP address */    if ((hc1_enc & HC1_DST_PREFIX_MASK) == HC1_DST_PREFIX_INLINE) {	memcpy(&ip_hdr->dst_addr, buf, sizeof(ip_hdr->dst_addr)/2);	buf += sizeof(ip_hdr->dst_addr)/2;	len -= sizeof(ip_hdr->dst_addr)/2;    } else {	ip_hdr->dst_addr.addr[0] = 0xFE;	ip_hdr->dst_addr.addr[1] = 0x80;    }         if ((hc1_enc & HC1_DST_IFACEID_MASK) == HC1_DST_IFACEID_INLINE) {	memcpy(((void*)&ip_hdr->dst_addr) + sizeof(ip_hdr->dst_addr)/2,	       buf, sizeof(ip_hdr->dst_addr)/2);	buf += sizeof(ip_hdr->dst_addr)/2;	len -= sizeof(ip_hdr->dst_addr)/2;    }    /* Traffic Class and Flow Label */    if ((hc1_enc & HC1_TCFL_MASK) == HC1_TCFL_INLINE) {	//TODO    }    /* Next Header */    switch (hc1_enc & HC1_NEXTHDR_MASK) {    case HC1_NEXTHDR_INLINE:	ip_hdr->nxt_hdr = *buf;	buf += sizeof(ip_hdr->nxt_hdr);	len -= sizeof(ip_hdr->nxt_hdr);	break;    case HC1_NEXTHDR_UDP:	ip_hdr->nxt_hdr = NEXT_HEADER_UDP;	break;    case HC1_NEXTHDR_ICMP:	ip_hdr->nxt_hdr = NEXT_HEADER_ICMP6;	break;    case HC1_NEXTHDR_TCP:	ip_hdr->nxt_hdr = NEXT_HEADER_TCP;	break;    default:	fprintf(stderr, "unknown next header HC1 encoding\n");	break;    }        /* HC_UDP compression */    if ((hc1_enc & HC1_HC2_MASK) == HC1_HC2_PRESENT	&& (hc1_enc & HC1_NEXTHDR_MASK) == HC1_NEXTHDR_UDP) {		udp_hdr = (struct udp_hdr *) ((*new_buf) + sizeof(struct ip6_hdr));	//udp_hdr = (struct udp_hdr *) (ip_hdr + 1);	memset(udp_hdr, 0, sizeof(struct udp_hdr));	/* UDP Source Port */	if ((hc2_enc & HC2_UDP_SRC_PORT_MASK) == HC2_UDP_SRC_PORT_INLINE) {	    memcpy(&udp_hdr->src_port, buf, sizeof(udp_hdr->src_port));	    buf += sizeof(udp_hdr->src_port);	    len -= sizeof(udp_hdr->src_port);	} else {	    //TODO	}	/* UDP Destination Port */	if ((hc2_enc & HC2_UDP_DST_PORT_MASK) == HC2_UDP_DST_PORT_INLINE) {	    memcpy(&udp_hdr->dst_port, buf, sizeof(udp_hdr->dst_port));	    buf += sizeof(udp_hdr->dst_port);	    len -= sizeof(udp_hdr->dst_port);	} else {	    //TODO	}	/* UDP Length */	if ((hc2_enc & HC2_UDP_LEN_MASK) == HC2_UDP_LEN_INLINE) {	    memcpy(&udp_hdr->len, buf, sizeof(udp_hdr->len));	    buf += sizeof(udp_hdr->len);	    len -= sizeof(udp_hdr->len);	} else {	    udp_hdr->len = len - sizeof(udp_hdr->chksum)		+ sizeof(struct udp_hdr);	}		/* Checksum */	memcpy(&udp_hdr->chksum, buf, sizeof(udp_hdr->chksum));	buf += sizeof(udp_hdr->chksum);	len -= sizeof(udp_hdr->chksum);		/* IPv6 Payload Length */	ip_hdr->plen = htons(len + sizeof(struct udp_hdr));		memcpy((*new_buf) + sizeof(struct ip6_hdr) + sizeof(struct udp_hdr),

⌨️ 快捷键说明

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