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

📄 net.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
字号:
/*************************************************************************** *    function_name.c  - Software Radio template module *                           ------------------- *   begin                :  2003 *   authors              :  Linus Gasser *   emails               :  linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** *                                Changes *                                ------- * date - name - description * 03/05/02 - ineiti - make new sending-algorithm * 03/05/19 - ineiti - start over with snull * **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//* ------------------------------------------------------------------------ * -----------------------------------------------------------------------*/#ifndef USER_SPACE#include <linux/netdevice.h>   /* struct device, and other headers */#include <linux/etherdevice.h>#include <linux/ip.h>          /* struct iphdr */#include <linux/tcp.h>         /* struct tcphdr */#include <linux/in6.h>#include <asm/uaccess.h>#include <asm/checksum.h>#endif#include "spc.h"#include "tcpip.h"#include "net.h"#include "buf.h"#include "std.h"#define DBG_LVL 4/** * Some network-related functions for the tcpip-device */#ifndef USER_SPACEint net_k_eth;extern struct net_device net_k_devs[];/* * Open and close */int net_k_open(struct net_device *dev) {  char str[16];  MOD_INC_USE_COUNT;  /*   * Assign the hardware address of the board: use "\0SNULx", where   * x is 0 or 1. The first byte is '\0' to avoid being a multicast   * address (the first byte of multicast addrs is odd).   */  memcpy(dev->dev_addr, "\0SNUL0", ETH_ALEN);  dev->dev_addr[ETH_ALEN-1] += (dev == net_k_devs); /* the number */  memcpy( str, dev->dev_addr, ETH_ALEN );  str[ ETH_ALEN ] = 0;  PR_DBG( 4, "Mac-adress is: %s\n", str + 1 );  netif_start_queue(dev);  return 0;}int net_k_release(struct net_device *dev) {  /* release ports, irq and such -- like fops->close */  netif_stop_queue(dev); /* can't transmit any more */  MOD_DEC_USE_COUNT;  /* if irq2dev_map was used (2.0 kernel), zero the entry here */  return 0;}/* * Configuration changes (passed on by ifconfig) */int net_k_config(struct net_device *dev, struct ifmap *map) {  if (dev->flags & IFF_UP) /* can't act on a running interface */    return -EBUSY;  /* Don't allow changing the I/O address */  if (map->base_addr != dev->base_addr) {    PR_DBG( 0, "snull: Can't change I/O address\n");    return -EOPNOTSUPP;  }  /* Allow changing the IRQ */  if (map->irq != dev->irq) {    dev->irq = map->irq;    /* request_irq() is delayed to open-time */  }  /* ignore other fields */  return 0;}/* * Receive a packet: retrieve, encapsulate and pass over to upper levels */void net_k_rx(struct net_device *dev, int len, unsigned char *buf) {  struct sk_buff *skb;  struct net_priv *priv = (struct net_priv *) dev->priv;  /*   * The packet has been retrieved from the transmission   * medium. Build an skb around it, so upper layers can handle it   */  skb = dev_alloc_skb(len+2);  if (!skb) {    PR_DBG( 0,"snull rx: low on mem - packet dropped\n");    priv->stats.rx_dropped++;    return;  }  skb_reserve(skb, 2); /* align IP on 16B boundary */  memcpy(skb_put(skb, len), buf, len);  /* Write metadata, and then pass to the receive level */  skb->dev = dev;  skb->protocol = eth_type_trans(skb, dev);  skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */  priv->stats.rx_packets++;  priv->stats.rx_bytes += len;  netif_rx(skb);  return;}/* * Transmit a packet (low level interface) */void net_k_hw_tx(char *buf, int len, struct net_device *dev) {  /*   * This function deals with hw details. This interface loops   * back the packet to the other snull interface (if any).   * In other words, this function implements the snull behaviour,   * while all other procedures are rather device-independent   */  struct iphdr *ih;  struct net_device *dest;  struct net_priv *priv;  u32 *saddr, *daddr;  /* I am paranoid. Ain't I? */  if (len < sizeof(struct ethhdr) + sizeof(struct iphdr)) {    PR_DBG( 0,"snull: Hmm... packet too short (%i octets)\n",            len);    return;  }  if (0) { /* enable this conditional to look at the data */    int i;    PR_DBG( 0, "len is %i\ndata:",len);    for (i=14 ; i<len; i++)      PR_DBG( 0," %02x",buf[i]&0xff);    PR_DBG( 0, "\n");  }  /*   * Ethhdr is 14 bytes, but the kernel arranges for iphdr   * to be aligned (i.e., ethhdr is unaligned)   */  ih = (struct iphdr *)(buf+sizeof(struct ethhdr));  saddr = &ih->saddr;  daddr = &ih->daddr;  ((u8 *)saddr)[2] ^= 1; /* change the third octet (class C) */  ((u8 *)daddr)[2] ^= 1;  ih->check = 0;         /* and rebuild the checksum (ip needs it) */  ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);  if (dev == net_k_devs) {    PR_DBG( 0, "%08x:%05i --> %08x:%05i\n",            ntohl(ih->saddr),ntohs(((struct tcphdr *)(ih+1))->source),            ntohl(ih->daddr),ntohs(((struct tcphdr *)(ih+1))->dest));  } else {    PR_DBG( 0, "%08x:%05i <-- %08x:%05i\n",            ntohl(ih->daddr),ntohs(((struct tcphdr *)(ih+1))->dest),            ntohl(ih->saddr),ntohs(((struct tcphdr *)(ih+1))->source));  }  /*   * Ok, now the packet is ready for transmission: first simulate a   * receive interrupt on the twin device, then  a   * transmission-done on the transmitting device   */  dest = net_k_devs + ( dev==net_k_devs ? 1 : 0 );  priv = (struct net_priv *) dest->priv;  priv->status = NET_RX_INTR;  priv->rx_packetlen = len;  priv->rx_packetdata = buf;  spin_lock(&priv->lock)  ;  net_k_rx(dest, priv->rx_packetlen, priv->rx_packetdata);  spin_unlock(&priv->lock)  ;  priv = (struct net_priv *) dev->priv;  priv->status = NET_TX_INTR;  priv->tx_packetlen = len;  priv->tx_packetdata = buf;  spin_lock(&priv->lock)  ;  priv->stats.tx_packets++;  priv->stats.tx_bytes += priv->tx_packetlen;  dev_kfree_skb(priv->skb);  spin_unlock(&priv->lock)  ;}/* * Transmit a packet (called by the kernel) */int net_k_tx(struct sk_buff *skb, struct net_device *dev) {  int len;  char *data;  struct net_priv *priv = (struct net_priv *) dev->priv;  len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;  data = skb->data;  dev->trans_start = jiffies; /* save the timestamp */  /* Remember the skb, so we can free it at interrupt time */  priv->skb = skb;  /* actual deliver of data is device-specific, and not shown here */  net_k_hw_tx(data, len, dev);  return 0; /* Our simple device can not fail */}/* * Return statistics to the caller */struct net_device_stats *net_k_stats(struct net_device *dev) {  struct net_priv *priv = (struct net_priv *) dev->priv;  return &priv->stats;}/* * This function is called to fill up an eth header, since arp is not * available on the interface */int net_k_rebuild_header(struct sk_buff *skb) {  struct ethhdr *eth = (struct ethhdr *) skb->data;  struct net_device *dev = skb->dev;  PR_DBG( 0, "Rebuild\n" );  memcpy(eth->h_source, dev->dev_addr, dev->addr_len);  memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);  eth->h_dest[ETH_ALEN-1]   ^= 0x01;   /* dest is us xor 1 */  return 0;}int net_k_header(struct sk_buff *skb, struct net_device *dev,                 unsigned short type, void *daddr, void *saddr,                 unsigned int len) {  struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN);  PR_DBG( 0, "hard header\n" );  eth->h_proto = htons(type);  memcpy(eth->h_source, saddr ? saddr : dev->dev_addr, dev->addr_len);  memcpy(eth->h_dest,   daddr ? daddr : dev->dev_addr, dev->addr_len);  eth->h_dest[ETH_ALEN-1]   ^= 0x01;   /* dest is us xor 1 */  return (dev->hard_header_len);}/* * The init function (sometimes called probe). * It is invoked by register_netdev() */int net_k_init(struct net_device *dev) {  /*   * Then, assign other fields in dev, using ether_setup() and some   * hand assignments   */  ether_setup(dev); /* assign some of the fields */  dev->open            = net_k_open;  dev->stop            = net_k_release;  dev->set_config      = net_k_config;  dev->hard_start_xmit = net_k_tx;  dev->get_stats       = net_k_stats;  dev->rebuild_header  = net_k_rebuild_header;  dev->hard_header     = net_k_header;  /* keep the default flags, just add NOARP */  dev->flags           |= IFF_NOARP;  dev->hard_header_cache = NULL;      /* Disable caching */  SET_MODULE_OWNER(dev);  return 0;}/* * The devices */struct net_device net_k_devs[MAX_RF_PORTS];/* * Finally, the module stuff */int net_k_init_module( void ) {  int result, device_present = 0, d;  struct net_device *dev;  for ( d = 0; d < MAX_RF_PORTS; d++ ) {    dev = net_k_devs + d;    dev->init = net_k_init;    /*     * Then, allocate the priv field. This encloses the statistics     * and a few private fields.     */    dev->priv = swr_malloc(sizeof(struct net_priv));    if (dev->priv == NULL) {      return -ENOMEM;    }    memset(dev->priv, 0, sizeof(struct net_priv));    spin_lock_init(& ((struct net_priv *) dev->priv)->lock)    ;    strcpy( dev->name, "msr%d" );    if ( (result = register_netdev(dev)) ) {      PR_DBG( 0,"snull: error %i registering device \"%s\"\n",              result, dev->name);    } else {      device_present++;    }  }  return ( device_present == MAX_RF_PORTS ) ? 0 : -ENODEV;}void net_k_cleanup( void ) {  int d;  for ( d=0; d<MAX_RF_PORTS; d++ ) {    swr_free( net_k_devs[d].priv);    unregister_netdev( net_k_devs + d );  }  return;}#endif/* * Generate a packet */int net_tx( struct buffer_t *buf ) {  char *data;#define USER_LEN 2048  data = swr_malloc( USER_LEN + 2 );  *((u16*)data) = USER_LEN;  *((U32*)(data + 2)) = swr_crc32_struct( data + 2, USER_LEN );  PR_DBG( 4, "Crc calculated: %x\n", *((U32*)(data + 2) ) );  buf_net_to_rf( buf, data, USER_LEN + 2 );  swr_free( data );  return 0;}/** * @short sends a packet to the kernel * * Takes a packet, makes a nice envelope and sends it to * the kernel. * * @param block the packet * @param len the length in bytes */void net_send_to_kernel( struct net_device *dev, char *buf, int len ) {  U32 crc, crc_rcvd;  crc_rcvd = *((U32*)buf);  crc = swr_crc32_struct( buf, len );  PR_DBG( 4, "Crc rcvd: %x, calculated: %x\n", crc_rcvd, crc );  if ( crc != crc_rcvd ) {    PR_DBG( 0, "Fatal: wrongly received packet!\n" );  } else {#ifndef USER_SPACE    net_k_rx( dev, len, buf + 4 );#endif  }}/** * The initialisation function called by an insmod tcpip */int net_init( ) {#ifndef USER_SPACE  return net_k_init_module( );#else  //  dev->priv = swr_malloc( sizeof( struct net_priv ) );  return 0;#endif}/** * The cleanup function called when rmmod tcpip */void net_cleanup( ) {#ifndef USER_SPACE  net_k_cleanup( );#else  //  swr_free( dev->priv );#endif}

⌨️ 快捷键说明

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