1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 3*1da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 4*1da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 5*1da177e4SLinus Torvalds * (at your option) any later version. 6*1da177e4SLinus Torvalds * 7*1da177e4SLinus Torvalds * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) 8*1da177e4SLinus Torvalds */ 9*1da177e4SLinus Torvalds #include <linux/config.h> 10*1da177e4SLinus Torvalds #include <linux/module.h> 11*1da177e4SLinus Torvalds #include <linux/proc_fs.h> 12*1da177e4SLinus Torvalds #include <linux/kernel.h> 13*1da177e4SLinus Torvalds #include <linux/sched.h> 14*1da177e4SLinus Torvalds #include <linux/interrupt.h> 15*1da177e4SLinus Torvalds #include <linux/fs.h> 16*1da177e4SLinus Torvalds #include <linux/types.h> 17*1da177e4SLinus Torvalds #include <linux/sysctl.h> 18*1da177e4SLinus Torvalds #include <linux/string.h> 19*1da177e4SLinus Torvalds #include <linux/socket.h> 20*1da177e4SLinus Torvalds #include <linux/errno.h> 21*1da177e4SLinus Torvalds #include <linux/fcntl.h> 22*1da177e4SLinus Torvalds #include <linux/in.h> 23*1da177e4SLinus Torvalds #include <linux/if_ether.h> 24*1da177e4SLinus Torvalds 25*1da177e4SLinus Torvalds #include <asm/system.h> 26*1da177e4SLinus Torvalds #include <asm/io.h> 27*1da177e4SLinus Torvalds 28*1da177e4SLinus Torvalds #include <linux/inet.h> 29*1da177e4SLinus Torvalds #include <linux/netdevice.h> 30*1da177e4SLinus Torvalds #include <linux/etherdevice.h> 31*1da177e4SLinus Torvalds #include <linux/if_arp.h> 32*1da177e4SLinus Torvalds #include <linux/skbuff.h> 33*1da177e4SLinus Torvalds 34*1da177e4SLinus Torvalds #include <net/ip.h> 35*1da177e4SLinus Torvalds #include <net/arp.h> 36*1da177e4SLinus Torvalds 37*1da177e4SLinus Torvalds #include <net/ax25.h> 38*1da177e4SLinus Torvalds #include <net/rose.h> 39*1da177e4SLinus Torvalds 40*1da177e4SLinus Torvalds static int rose_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, 41*1da177e4SLinus Torvalds void *daddr, void *saddr, unsigned len) 42*1da177e4SLinus Torvalds { 43*1da177e4SLinus Torvalds unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2); 44*1da177e4SLinus Torvalds 45*1da177e4SLinus Torvalds *buff++ = ROSE_GFI | ROSE_Q_BIT; 46*1da177e4SLinus Torvalds *buff++ = 0x00; 47*1da177e4SLinus Torvalds *buff++ = ROSE_DATA; 48*1da177e4SLinus Torvalds *buff++ = 0x7F; 49*1da177e4SLinus Torvalds *buff++ = AX25_P_IP; 50*1da177e4SLinus Torvalds 51*1da177e4SLinus Torvalds if (daddr != NULL) 52*1da177e4SLinus Torvalds return 37; 53*1da177e4SLinus Torvalds 54*1da177e4SLinus Torvalds return -37; 55*1da177e4SLinus Torvalds } 56*1da177e4SLinus Torvalds 57*1da177e4SLinus Torvalds static int rose_rebuild_header(struct sk_buff *skb) 58*1da177e4SLinus Torvalds { 59*1da177e4SLinus Torvalds struct net_device *dev = skb->dev; 60*1da177e4SLinus Torvalds struct net_device_stats *stats = netdev_priv(dev); 61*1da177e4SLinus Torvalds unsigned char *bp = (unsigned char *)skb->data; 62*1da177e4SLinus Torvalds struct sk_buff *skbn; 63*1da177e4SLinus Torvalds 64*1da177e4SLinus Torvalds #ifdef CONFIG_INET 65*1da177e4SLinus Torvalds if (arp_find(bp + 7, skb)) { 66*1da177e4SLinus Torvalds return 1; 67*1da177e4SLinus Torvalds } 68*1da177e4SLinus Torvalds 69*1da177e4SLinus Torvalds if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { 70*1da177e4SLinus Torvalds kfree_skb(skb); 71*1da177e4SLinus Torvalds return 1; 72*1da177e4SLinus Torvalds } 73*1da177e4SLinus Torvalds 74*1da177e4SLinus Torvalds if (skb->sk != NULL) 75*1da177e4SLinus Torvalds skb_set_owner_w(skbn, skb->sk); 76*1da177e4SLinus Torvalds 77*1da177e4SLinus Torvalds kfree_skb(skb); 78*1da177e4SLinus Torvalds 79*1da177e4SLinus Torvalds if (!rose_route_frame(skbn, NULL)) { 80*1da177e4SLinus Torvalds kfree_skb(skbn); 81*1da177e4SLinus Torvalds stats->tx_errors++; 82*1da177e4SLinus Torvalds return 1; 83*1da177e4SLinus Torvalds } 84*1da177e4SLinus Torvalds 85*1da177e4SLinus Torvalds stats->tx_packets++; 86*1da177e4SLinus Torvalds stats->tx_bytes += skbn->len; 87*1da177e4SLinus Torvalds #endif 88*1da177e4SLinus Torvalds return 1; 89*1da177e4SLinus Torvalds } 90*1da177e4SLinus Torvalds 91*1da177e4SLinus Torvalds static int rose_set_mac_address(struct net_device *dev, void *addr) 92*1da177e4SLinus Torvalds { 93*1da177e4SLinus Torvalds struct sockaddr *sa = addr; 94*1da177e4SLinus Torvalds 95*1da177e4SLinus Torvalds rose_del_loopback_node((rose_address *)dev->dev_addr); 96*1da177e4SLinus Torvalds 97*1da177e4SLinus Torvalds memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); 98*1da177e4SLinus Torvalds 99*1da177e4SLinus Torvalds rose_add_loopback_node((rose_address *)dev->dev_addr); 100*1da177e4SLinus Torvalds 101*1da177e4SLinus Torvalds return 0; 102*1da177e4SLinus Torvalds } 103*1da177e4SLinus Torvalds 104*1da177e4SLinus Torvalds static int rose_open(struct net_device *dev) 105*1da177e4SLinus Torvalds { 106*1da177e4SLinus Torvalds netif_start_queue(dev); 107*1da177e4SLinus Torvalds rose_add_loopback_node((rose_address *)dev->dev_addr); 108*1da177e4SLinus Torvalds return 0; 109*1da177e4SLinus Torvalds } 110*1da177e4SLinus Torvalds 111*1da177e4SLinus Torvalds static int rose_close(struct net_device *dev) 112*1da177e4SLinus Torvalds { 113*1da177e4SLinus Torvalds netif_stop_queue(dev); 114*1da177e4SLinus Torvalds rose_del_loopback_node((rose_address *)dev->dev_addr); 115*1da177e4SLinus Torvalds return 0; 116*1da177e4SLinus Torvalds } 117*1da177e4SLinus Torvalds 118*1da177e4SLinus Torvalds static int rose_xmit(struct sk_buff *skb, struct net_device *dev) 119*1da177e4SLinus Torvalds { 120*1da177e4SLinus Torvalds struct net_device_stats *stats = netdev_priv(dev); 121*1da177e4SLinus Torvalds 122*1da177e4SLinus Torvalds if (!netif_running(dev)) { 123*1da177e4SLinus Torvalds printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n"); 124*1da177e4SLinus Torvalds return 1; 125*1da177e4SLinus Torvalds } 126*1da177e4SLinus Torvalds dev_kfree_skb(skb); 127*1da177e4SLinus Torvalds stats->tx_errors++; 128*1da177e4SLinus Torvalds return 0; 129*1da177e4SLinus Torvalds } 130*1da177e4SLinus Torvalds 131*1da177e4SLinus Torvalds static struct net_device_stats *rose_get_stats(struct net_device *dev) 132*1da177e4SLinus Torvalds { 133*1da177e4SLinus Torvalds return netdev_priv(dev); 134*1da177e4SLinus Torvalds } 135*1da177e4SLinus Torvalds 136*1da177e4SLinus Torvalds void rose_setup(struct net_device *dev) 137*1da177e4SLinus Torvalds { 138*1da177e4SLinus Torvalds SET_MODULE_OWNER(dev); 139*1da177e4SLinus Torvalds dev->mtu = ROSE_MAX_PACKET_SIZE - 2; 140*1da177e4SLinus Torvalds dev->hard_start_xmit = rose_xmit; 141*1da177e4SLinus Torvalds dev->open = rose_open; 142*1da177e4SLinus Torvalds dev->stop = rose_close; 143*1da177e4SLinus Torvalds 144*1da177e4SLinus Torvalds dev->hard_header = rose_header; 145*1da177e4SLinus Torvalds dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN; 146*1da177e4SLinus Torvalds dev->addr_len = ROSE_ADDR_LEN; 147*1da177e4SLinus Torvalds dev->type = ARPHRD_ROSE; 148*1da177e4SLinus Torvalds dev->rebuild_header = rose_rebuild_header; 149*1da177e4SLinus Torvalds dev->set_mac_address = rose_set_mac_address; 150*1da177e4SLinus Torvalds 151*1da177e4SLinus Torvalds /* New-style flags. */ 152*1da177e4SLinus Torvalds dev->flags = 0; 153*1da177e4SLinus Torvalds dev->get_stats = rose_get_stats; 154*1da177e4SLinus Torvalds } 155