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

📄 tundev.c

📁 tcp_ip协议栈的ucos代码
💻 C
字号:
/*
 * Copyright (c) 2001, Swedish Institute of Computer Science.
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 *
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. 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. 
 *
 * 3. Neither the name of the Institute nor the names of its contributors 
 *    may be used to endorse or promote products derived from this software 
 *    without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. 
 *
 * Author: Adam Dunkels <adam@sics.se>
 *
 * $Id: tundev.c,v 1.6 2001/11/23 05:59:41 adam Exp $
 */


#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/socket.h>

#ifndef linux
#include <net/if_tun.h>
#endif

#include "uip.h"

static int drop = 0;
static int fd;

struct tcpip_hdr {
  unsigned char vhl,
    tos,          
    len[2],       
    id[2],        
    ipoffset[2],  
    ttl,          
    proto;     
  unsigned short ipchksum;
  unsigned long srcipaddr, 
    destipaddr;
  unsigned char srcport[2],
    destport[2],
    seqno[4],  
    ackno[4],
    tcpoffset,
    flags,
    wnd[2],     
    tcpchksum[2],
    urgp[2]; 
  unsigned char data[0];

};
/*-----------------------------------------------------------------------------------*/
static unsigned short
chksum(void *data, int len)
{
  unsigned short *sdata = data;
  unsigned long acc;
  unsigned long sum;
    
  for(acc = 0; len > 1; len -= 2) {
    acc += *sdata++;
  }

  /* add up any odd byte */
  if(len == 1) {
    acc += (unsigned short)(*(unsigned char *)sdata);
  }

  sum = (acc & 0xffff) + (acc >> 16);
  sum += (sum >> 16);
  
  return ~(sum & 0xffff);
}
/*-----------------------------------------------------------------------------------*/
static unsigned short
chksum_pseudo(void *data, int len, unsigned long ipaddr1,
              unsigned long ipaddr2,
              unsigned char proto,
              unsigned short protolen)
{
  unsigned long sum;
  unsigned short *sdata = data;
  
  for(sum = 0; len > 1; len -= 2) {
    sum += *sdata++;
  }

  /* add up any odd byte */
  if(len == 1) {
    sum += (unsigned short)(*(unsigned char *)sdata);
  }

  sum += (ipaddr1 & 0xffff);
  sum += ((ipaddr1 >> 16) & 0xffff);
  sum += (ipaddr2 & 0xffff);
  sum += ((ipaddr2 >> 16) & 0xffff);
  sum += (unsigned short)htons((unsigned short)proto);
  sum += (unsigned short)htons(protolen);
  
  while(sum >> 16) {
    sum = (sum & 0xffff) + (sum >> 16);
  }
  
  return ~sum & 0xffff;
}
/*-----------------------------------------------------------------------------------*/
static void
check_checksum(void *data, int len)
{
  struct tcpip_hdr *hdr;
  unsigned short sum;
  
  hdr = data;

  sum = chksum(data, 20);  
  printf("IP header checksum check 0x%x\n", sum);
  
  sum = chksum_pseudo(&(hdr->srcport[0]), len - 20,
                      hdr->srcipaddr, hdr->destipaddr,
                      hdr->proto, len - 20);  
  printf("TCP checksum check 0x%x len %d protolen %d\n", sum, len,
         len - 20);
  
}
/*-----------------------------------------------------------------------------------*/
void
tundev_init(void)
{
  int val;
  fd = open("/dev/tun0", O_RDWR);
  if(fd == -1) {
    perror("tun_dev: tundev_init: open");
    exit(1);
  }
#ifdef linux
  system("ifconfig tun0 inet 192.168.0.2 192.168.0.1");
  system("route add -net 192.168.0.0 netmask 255.255.255.0 dev tun0");
#else
  system("ifconfig tun0 inet 192.168.0.1 192.168.0.2");
  val = 0;
  ioctl(fd, TUNSIFHEAD, &val);

#endif /* linux */
}
/*-----------------------------------------------------------------------------------*/
unsigned int
tundev_read(void)
{
  fd_set fdset;
  struct timeval tv;
  int ret;

  tv.tv_sec = 0;
  tv.tv_usec = 500000;
  FD_ZERO(&fdset);
  FD_SET(fd, &fdset);
  
  ret = select(fd + 1, &fdset, NULL, NULL, &tv);
  if(ret == 0) {
    return 0;
  } 
  ret = read(fd, uip_buf, UIP_BUFSIZE);
  if(ret == -1) {
    perror("tun_dev: tundev_read: read");
  }
    /*printf("--- tun_dev: tundev_read: read %d bytes\n", ret);*/
  /*  {
    int i;
    for(i = 0; i < 20; i++) {
      printf("%x ", uip_buf[i]);
    }
    printf("\n");
    }*/
  /*  check_checksum(uip_buf, ret);*/
  return ret;
}
/*-----------------------------------------------------------------------------------*/
void
tundev_send(void)
{
  int ret;
  int i;
  char tmpbuf[UIP_BUFSIZE];
  /*  printf("tundev_send: sending %d bytes\n", uip_len);*/
  /*  check_checksum(uip_buf, size);*/

  /*  drop++;
  if(drop % 8 == 7) {
    printf("Dropped a packet!\n");
    return;
  }*/
  /*  {
    int i;
    for(i = 0; i < 20; i++) {
      printf("%x ", uip_buf[i]);
    }
    printf("\n");
    }*/
  for(i = 0; i < 40; i++) {
    tmpbuf[i] = uip_buf[i];
  }
  
  for(i = 40; i < uip_len; i++) {
    tmpbuf[i] = uip_appdata[i - 40];
  }
  
  ret = write(fd, tmpbuf, uip_len);
  if(ret == -1) {
    perror("tun_dev: tundev_done: write");
    exit(1);
  }
}  
/*-----------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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