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 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> /* For the statistics structure. */ 24*1da177e4SLinus Torvalds 25*1da177e4SLinus Torvalds #include <asm/system.h> 26*1da177e4SLinus Torvalds #include <asm/uaccess.h> 27*1da177e4SLinus Torvalds #include <asm/io.h> 28*1da177e4SLinus Torvalds 29*1da177e4SLinus Torvalds #include <linux/inet.h> 30*1da177e4SLinus Torvalds #include <linux/netdevice.h> 31*1da177e4SLinus Torvalds #include <linux/etherdevice.h> 32*1da177e4SLinus Torvalds #include <linux/if_arp.h> 33*1da177e4SLinus Torvalds #include <linux/skbuff.h> 34*1da177e4SLinus Torvalds 35*1da177e4SLinus Torvalds #include <net/ip.h> 36*1da177e4SLinus Torvalds #include <net/arp.h> 37*1da177e4SLinus Torvalds 38*1da177e4SLinus Torvalds #include <net/ax25.h> 39*1da177e4SLinus Torvalds #include <net/netrom.h> 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds #ifdef CONFIG_INET 42*1da177e4SLinus Torvalds 43*1da177e4SLinus Torvalds /* 44*1da177e4SLinus Torvalds * Only allow IP over NET/ROM frames through if the netrom device is up. 45*1da177e4SLinus Torvalds */ 46*1da177e4SLinus Torvalds 47*1da177e4SLinus Torvalds int nr_rx_ip(struct sk_buff *skb, struct net_device *dev) 48*1da177e4SLinus Torvalds { 49*1da177e4SLinus Torvalds struct net_device_stats *stats = netdev_priv(dev); 50*1da177e4SLinus Torvalds 51*1da177e4SLinus Torvalds if (!netif_running(dev)) { 52*1da177e4SLinus Torvalds stats->rx_errors++; 53*1da177e4SLinus Torvalds return 0; 54*1da177e4SLinus Torvalds } 55*1da177e4SLinus Torvalds 56*1da177e4SLinus Torvalds stats->rx_packets++; 57*1da177e4SLinus Torvalds stats->rx_bytes += skb->len; 58*1da177e4SLinus Torvalds 59*1da177e4SLinus Torvalds skb->protocol = htons(ETH_P_IP); 60*1da177e4SLinus Torvalds 61*1da177e4SLinus Torvalds /* Spoof incoming device */ 62*1da177e4SLinus Torvalds skb->dev = dev; 63*1da177e4SLinus Torvalds skb->h.raw = skb->data; 64*1da177e4SLinus Torvalds skb->nh.raw = skb->data; 65*1da177e4SLinus Torvalds skb->pkt_type = PACKET_HOST; 66*1da177e4SLinus Torvalds 67*1da177e4SLinus Torvalds ip_rcv(skb, skb->dev, NULL); 68*1da177e4SLinus Torvalds 69*1da177e4SLinus Torvalds return 1; 70*1da177e4SLinus Torvalds } 71*1da177e4SLinus Torvalds 72*1da177e4SLinus Torvalds 73*1da177e4SLinus Torvalds static int nr_rebuild_header(struct sk_buff *skb) 74*1da177e4SLinus Torvalds { 75*1da177e4SLinus Torvalds struct net_device *dev = skb->dev; 76*1da177e4SLinus Torvalds struct net_device_stats *stats = netdev_priv(dev); 77*1da177e4SLinus Torvalds struct sk_buff *skbn; 78*1da177e4SLinus Torvalds unsigned char *bp = skb->data; 79*1da177e4SLinus Torvalds int len; 80*1da177e4SLinus Torvalds 81*1da177e4SLinus Torvalds if (arp_find(bp + 7, skb)) { 82*1da177e4SLinus Torvalds return 1; 83*1da177e4SLinus Torvalds } 84*1da177e4SLinus Torvalds 85*1da177e4SLinus Torvalds bp[6] &= ~AX25_CBIT; 86*1da177e4SLinus Torvalds bp[6] &= ~AX25_EBIT; 87*1da177e4SLinus Torvalds bp[6] |= AX25_SSSID_SPARE; 88*1da177e4SLinus Torvalds bp += AX25_ADDR_LEN; 89*1da177e4SLinus Torvalds 90*1da177e4SLinus Torvalds bp[6] &= ~AX25_CBIT; 91*1da177e4SLinus Torvalds bp[6] |= AX25_EBIT; 92*1da177e4SLinus Torvalds bp[6] |= AX25_SSSID_SPARE; 93*1da177e4SLinus Torvalds 94*1da177e4SLinus Torvalds if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { 95*1da177e4SLinus Torvalds kfree_skb(skb); 96*1da177e4SLinus Torvalds return 1; 97*1da177e4SLinus Torvalds } 98*1da177e4SLinus Torvalds 99*1da177e4SLinus Torvalds if (skb->sk != NULL) 100*1da177e4SLinus Torvalds skb_set_owner_w(skbn, skb->sk); 101*1da177e4SLinus Torvalds 102*1da177e4SLinus Torvalds kfree_skb(skb); 103*1da177e4SLinus Torvalds 104*1da177e4SLinus Torvalds len = skbn->len; 105*1da177e4SLinus Torvalds 106*1da177e4SLinus Torvalds if (!nr_route_frame(skbn, NULL)) { 107*1da177e4SLinus Torvalds kfree_skb(skbn); 108*1da177e4SLinus Torvalds stats->tx_errors++; 109*1da177e4SLinus Torvalds } 110*1da177e4SLinus Torvalds 111*1da177e4SLinus Torvalds stats->tx_packets++; 112*1da177e4SLinus Torvalds stats->tx_bytes += len; 113*1da177e4SLinus Torvalds 114*1da177e4SLinus Torvalds return 1; 115*1da177e4SLinus Torvalds } 116*1da177e4SLinus Torvalds 117*1da177e4SLinus Torvalds #else 118*1da177e4SLinus Torvalds 119*1da177e4SLinus Torvalds static int nr_rebuild_header(struct sk_buff *skb) 120*1da177e4SLinus Torvalds { 121*1da177e4SLinus Torvalds return 1; 122*1da177e4SLinus Torvalds } 123*1da177e4SLinus Torvalds 124*1da177e4SLinus Torvalds #endif 125*1da177e4SLinus Torvalds 126*1da177e4SLinus Torvalds static int nr_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, 127*1da177e4SLinus Torvalds void *daddr, void *saddr, unsigned len) 128*1da177e4SLinus Torvalds { 129*1da177e4SLinus Torvalds unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN); 130*1da177e4SLinus Torvalds 131*1da177e4SLinus Torvalds memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len); 132*1da177e4SLinus Torvalds buff[6] &= ~AX25_CBIT; 133*1da177e4SLinus Torvalds buff[6] &= ~AX25_EBIT; 134*1da177e4SLinus Torvalds buff[6] |= AX25_SSSID_SPARE; 135*1da177e4SLinus Torvalds buff += AX25_ADDR_LEN; 136*1da177e4SLinus Torvalds 137*1da177e4SLinus Torvalds if (daddr != NULL) 138*1da177e4SLinus Torvalds memcpy(buff, daddr, dev->addr_len); 139*1da177e4SLinus Torvalds buff[6] &= ~AX25_CBIT; 140*1da177e4SLinus Torvalds buff[6] |= AX25_EBIT; 141*1da177e4SLinus Torvalds buff[6] |= AX25_SSSID_SPARE; 142*1da177e4SLinus Torvalds buff += AX25_ADDR_LEN; 143*1da177e4SLinus Torvalds 144*1da177e4SLinus Torvalds *buff++ = sysctl_netrom_network_ttl_initialiser; 145*1da177e4SLinus Torvalds 146*1da177e4SLinus Torvalds *buff++ = NR_PROTO_IP; 147*1da177e4SLinus Torvalds *buff++ = NR_PROTO_IP; 148*1da177e4SLinus Torvalds *buff++ = 0; 149*1da177e4SLinus Torvalds *buff++ = 0; 150*1da177e4SLinus Torvalds *buff++ = NR_PROTOEXT; 151*1da177e4SLinus Torvalds 152*1da177e4SLinus Torvalds if (daddr != NULL) 153*1da177e4SLinus Torvalds return 37; 154*1da177e4SLinus Torvalds 155*1da177e4SLinus Torvalds return -37; 156*1da177e4SLinus Torvalds } 157*1da177e4SLinus Torvalds 158*1da177e4SLinus Torvalds static int nr_set_mac_address(struct net_device *dev, void *addr) 159*1da177e4SLinus Torvalds { 160*1da177e4SLinus Torvalds struct sockaddr *sa = addr; 161*1da177e4SLinus Torvalds 162*1da177e4SLinus Torvalds if (dev->flags & IFF_UP) 163*1da177e4SLinus Torvalds ax25_listen_release((ax25_address *)dev->dev_addr, NULL); 164*1da177e4SLinus Torvalds 165*1da177e4SLinus Torvalds memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); 166*1da177e4SLinus Torvalds 167*1da177e4SLinus Torvalds if (dev->flags & IFF_UP) 168*1da177e4SLinus Torvalds ax25_listen_register((ax25_address *)dev->dev_addr, NULL); 169*1da177e4SLinus Torvalds 170*1da177e4SLinus Torvalds return 0; 171*1da177e4SLinus Torvalds } 172*1da177e4SLinus Torvalds 173*1da177e4SLinus Torvalds static int nr_open(struct net_device *dev) 174*1da177e4SLinus Torvalds { 175*1da177e4SLinus Torvalds netif_start_queue(dev); 176*1da177e4SLinus Torvalds ax25_listen_register((ax25_address *)dev->dev_addr, NULL); 177*1da177e4SLinus Torvalds return 0; 178*1da177e4SLinus Torvalds } 179*1da177e4SLinus Torvalds 180*1da177e4SLinus Torvalds static int nr_close(struct net_device *dev) 181*1da177e4SLinus Torvalds { 182*1da177e4SLinus Torvalds ax25_listen_release((ax25_address *)dev->dev_addr, NULL); 183*1da177e4SLinus Torvalds netif_stop_queue(dev); 184*1da177e4SLinus Torvalds return 0; 185*1da177e4SLinus Torvalds } 186*1da177e4SLinus Torvalds 187*1da177e4SLinus Torvalds static int nr_xmit(struct sk_buff *skb, struct net_device *dev) 188*1da177e4SLinus Torvalds { 189*1da177e4SLinus Torvalds struct net_device_stats *stats = netdev_priv(dev); 190*1da177e4SLinus Torvalds dev_kfree_skb(skb); 191*1da177e4SLinus Torvalds stats->tx_errors++; 192*1da177e4SLinus Torvalds return 0; 193*1da177e4SLinus Torvalds } 194*1da177e4SLinus Torvalds 195*1da177e4SLinus Torvalds static struct net_device_stats *nr_get_stats(struct net_device *dev) 196*1da177e4SLinus Torvalds { 197*1da177e4SLinus Torvalds return netdev_priv(dev); 198*1da177e4SLinus Torvalds } 199*1da177e4SLinus Torvalds 200*1da177e4SLinus Torvalds void nr_setup(struct net_device *dev) 201*1da177e4SLinus Torvalds { 202*1da177e4SLinus Torvalds SET_MODULE_OWNER(dev); 203*1da177e4SLinus Torvalds dev->mtu = NR_MAX_PACKET_SIZE; 204*1da177e4SLinus Torvalds dev->hard_start_xmit = nr_xmit; 205*1da177e4SLinus Torvalds dev->open = nr_open; 206*1da177e4SLinus Torvalds dev->stop = nr_close; 207*1da177e4SLinus Torvalds 208*1da177e4SLinus Torvalds dev->hard_header = nr_header; 209*1da177e4SLinus Torvalds dev->hard_header_len = NR_NETWORK_LEN + NR_TRANSPORT_LEN; 210*1da177e4SLinus Torvalds dev->addr_len = AX25_ADDR_LEN; 211*1da177e4SLinus Torvalds dev->type = ARPHRD_NETROM; 212*1da177e4SLinus Torvalds dev->tx_queue_len = 40; 213*1da177e4SLinus Torvalds dev->rebuild_header = nr_rebuild_header; 214*1da177e4SLinus Torvalds dev->set_mac_address = nr_set_mac_address; 215*1da177e4SLinus Torvalds 216*1da177e4SLinus Torvalds /* New-style flags. */ 217*1da177e4SLinus Torvalds dev->flags = 0; 218*1da177e4SLinus Torvalds 219*1da177e4SLinus Torvalds dev->get_stats = nr_get_stats; 220*1da177e4SLinus Torvalds } 221