~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/netrom/nr_dev.c

Version: ~ [ linux-5.17-rc1 ] ~ [ linux-5.16.2 ] ~ [ linux-5.15.16 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.93 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.173 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.225 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.262 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.297 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.299 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This program is free software; you can redistribute it and/or modify
  3  * it under the terms of the GNU General Public License as published by
  4  * the Free Software Foundation; either version 2 of the License, or
  5  * (at your option) any later version.
  6  *
  7  * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
  8  */
  9 #include <linux/module.h>
 10 #include <linux/proc_fs.h>
 11 #include <linux/kernel.h>
 12 #include <linux/interrupt.h>
 13 #include <linux/fs.h>
 14 #include <linux/types.h>
 15 #include <linux/sysctl.h>
 16 #include <linux/string.h>
 17 #include <linux/socket.h>
 18 #include <linux/errno.h>
 19 #include <linux/fcntl.h>
 20 #include <linux/in.h>
 21 #include <linux/if_ether.h>     /* For the statistics structure. */
 22 #include <linux/slab.h>
 23 
 24 #include <asm/uaccess.h>
 25 #include <asm/io.h>
 26 
 27 #include <linux/inet.h>
 28 #include <linux/netdevice.h>
 29 #include <linux/etherdevice.h>
 30 #include <linux/if_arp.h>
 31 #include <linux/skbuff.h>
 32 
 33 #include <net/ip.h>
 34 #include <net/arp.h>
 35 
 36 #include <net/ax25.h>
 37 #include <net/netrom.h>
 38 
 39 /*
 40  *      Only allow IP over NET/ROM frames through if the netrom device is up.
 41  */
 42 
 43 int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
 44 {
 45         struct net_device_stats *stats = &dev->stats;
 46 
 47         if (!netif_running(dev)) {
 48                 stats->rx_dropped++;
 49                 return 0;
 50         }
 51 
 52         stats->rx_packets++;
 53         stats->rx_bytes += skb->len;
 54 
 55         skb->protocol = htons(ETH_P_IP);
 56 
 57         /* Spoof incoming device */
 58         skb->dev      = dev;
 59         skb->mac_header = skb->network_header;
 60         skb_reset_network_header(skb);
 61         skb->pkt_type = PACKET_HOST;
 62 
 63         netif_rx(skb);
 64 
 65         return 1;
 66 }
 67 
 68 #ifdef CONFIG_INET
 69 
 70 static int nr_rebuild_header(struct sk_buff *skb)
 71 {
 72         unsigned char *bp = skb->data;
 73 
 74         if (arp_find(bp + 7, skb))
 75                 return 1;
 76 
 77         bp[6] &= ~AX25_CBIT;
 78         bp[6] &= ~AX25_EBIT;
 79         bp[6] |= AX25_SSSID_SPARE;
 80         bp    += AX25_ADDR_LEN;
 81 
 82         bp[6] &= ~AX25_CBIT;
 83         bp[6] |= AX25_EBIT;
 84         bp[6] |= AX25_SSSID_SPARE;
 85 
 86         return 0;
 87 }
 88 
 89 #else
 90 
 91 static int nr_rebuild_header(struct sk_buff *skb)
 92 {
 93         return 1;
 94 }
 95 
 96 #endif
 97 
 98 static int nr_header(struct sk_buff *skb, struct net_device *dev,
 99                      unsigned short type,
100                      const void *daddr, const void *saddr, unsigned int len)
101 {
102         unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
103 
104         memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
105         buff[6] &= ~AX25_CBIT;
106         buff[6] &= ~AX25_EBIT;
107         buff[6] |= AX25_SSSID_SPARE;
108         buff    += AX25_ADDR_LEN;
109 
110         if (daddr != NULL)
111                 memcpy(buff, daddr, dev->addr_len);
112         buff[6] &= ~AX25_CBIT;
113         buff[6] |= AX25_EBIT;
114         buff[6] |= AX25_SSSID_SPARE;
115         buff    += AX25_ADDR_LEN;
116 
117         *buff++ = sysctl_netrom_network_ttl_initialiser;
118 
119         *buff++ = NR_PROTO_IP;
120         *buff++ = NR_PROTO_IP;
121         *buff++ = 0;
122         *buff++ = 0;
123         *buff++ = NR_PROTOEXT;
124 
125         if (daddr != NULL)
126                 return 37;
127 
128         return -37;
129 }
130 
131 static int __must_check nr_set_mac_address(struct net_device *dev, void *addr)
132 {
133         struct sockaddr *sa = addr;
134         int err;
135 
136         if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
137                 return 0;
138 
139         if (dev->flags & IFF_UP) {
140                 err = ax25_listen_register((ax25_address *)sa->sa_data, NULL);
141                 if (err)
142                         return err;
143 
144                 ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
145         }
146 
147         memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
148 
149         return 0;
150 }
151 
152 static int nr_open(struct net_device *dev)
153 {
154         int err;
155 
156         err = ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
157         if (err)
158                 return err;
159 
160         netif_start_queue(dev);
161 
162         return 0;
163 }
164 
165 static int nr_close(struct net_device *dev)
166 {
167         ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
168         netif_stop_queue(dev);
169         return 0;
170 }
171 
172 static netdev_tx_t nr_xmit(struct sk_buff *skb, struct net_device *dev)
173 {
174         struct net_device_stats *stats = &dev->stats;
175         unsigned int len = skb->len;
176 
177         if (!nr_route_frame(skb, NULL)) {
178                 kfree_skb(skb);
179                 stats->tx_errors++;
180                 return NETDEV_TX_OK;
181         }
182 
183         stats->tx_packets++;
184         stats->tx_bytes += len;
185 
186         return NETDEV_TX_OK;
187 }
188 
189 static const struct header_ops nr_header_ops = {
190         .create = nr_header,
191         .rebuild= nr_rebuild_header,
192 };
193 
194 static const struct net_device_ops nr_netdev_ops = {
195         .ndo_open               = nr_open,
196         .ndo_stop               = nr_close,
197         .ndo_start_xmit         = nr_xmit,
198         .ndo_set_mac_address    = nr_set_mac_address,
199 };
200 
201 void nr_setup(struct net_device *dev)
202 {
203         dev->mtu                = NR_MAX_PACKET_SIZE;
204         dev->netdev_ops         = &nr_netdev_ops;
205         dev->header_ops         = &nr_header_ops;
206         dev->hard_header_len    = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
207         dev->addr_len           = AX25_ADDR_LEN;
208         dev->type               = ARPHRD_NETROM;
209 
210         /* New-style flags. */
211         dev->flags              = IFF_NOARP;
212 }
213 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp