Version:
~ [ 0.6-2.3.46 ] ~
Architecture:
~ [ um ] ~
** Warning: Cannot open xref database.
1 #include "linux/init.h"
2 #include "linux/netdevice.h"
3 #include "linux/skbuff.h"
4 #include "linux/if_arp.h"
5 #include "linux/init.h"
6 #include "umn.h"
7 #include "user_util.h"
8 #include "kern_util.h"
9
10 struct umn {
11 int used;
12 int tty_fd;
13 int slave;
14 int orig_disc;
15 int slipno;
16 int rcount;
17 int esc;
18 char rbuff[3000];
19 int buffsize;
20 struct net_device dev;
21 };
22
23 struct umn umn = { 0, -1, -1, -1 };
24
25 static int xmit(struct sk_buff *skb, struct net_device *dev)
26 {
27 return(umn_send_packet(umn.tty_fd, skb->data, skb->len));
28 }
29
30 void umn_rcv(char *data, int len)
31 {
32 struct sk_buff *skb;
33
34 skb = dev_alloc_skb(len);
35 memcpy(skb_put(skb, len), data, len);
36 skb->mac.raw = skb->data;
37 skb->dev = &umn.dev;
38 skb->protocol = htons(ETH_P_IP);
39 netif_rx(skb);
40 }
41
42 /* SLIP protocol characters. */
43 #define END 0300 /* indicates end of frame */
44 #define ESC 0333 /* indicates byte stuffing */
45 #define ESC_END 0334 /* ESC ESC_END means END 'data' */
46 #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
47
48 void slip_unesc(unsigned char s)
49 {
50
51 switch(s) {
52 case END:
53 if (umn.rcount > 2) {
54 umn_rcv(umn.rbuff, umn.rcount);
55 }
56 umn.esc = 0;
57 umn.rcount = 0;
58 return;
59
60 case ESC:
61 umn.esc = 1;
62 return;
63 case ESC_ESC:
64 if(umn.esc){
65 umn.esc = 0;
66 s = ESC;
67 }
68 break;
69 case ESC_END:
70 if(umn.esc){
71 umn.esc = 0;
72 s = END;
73 }
74 break;
75 }
76 if (umn.rcount < umn.buffsize) {
77 umn.rbuff[umn.rcount++] = s;
78 return;
79 }
80 printk("umn receive overflow\n");
81 }
82
83 spinlock_t umn_lock = SPIN_LOCK_UNLOCKED;
84
85 static int open(struct net_device *dev)
86 {
87 spin_lock(&umn_lock);
88 if(umn.used){
89 spin_unlock(&umn_lock);
90 return(-ENXIO);
91 }
92 umn.used = 1;
93 spin_unlock(&umn_lock);
94 umn.tty_fd = open_umn_tty(&umn.orig_disc, &umn.slave, &umn.slipno);
95 umn.rcount = 0;
96 umn.esc = 0;
97 umn.buffsize = sizeof(umn.rbuff)/sizeof(umn.rbuff[0]);
98 if(umn.tty_fd == -1) return(-1);
99 else return(0);
100 }
101
102 static int close (struct net_device *dev)
103 {
104 spin_lock(&umn_lock);
105 if(!umn.used){
106 spin_unlock(&umn_lock);
107 return(-ENXIO);
108 }
109 umn.used = 0;
110 spin_unlock(&umn_lock);
111 close_umn_tty(umn.tty_fd, umn.slave, umn.orig_disc);
112 return(0);
113 }
114
115 static int ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
116 {
117 printk("umn ioctl = %d\n", cmd);
118 if((cmd >= SIOCDEVPRIVATE) && (cmd <= SIOCDEVPRIVATE + 15))
119 return(-EOPNOTSUPP);
120 KERN_UNTESTED();
121 return(-EOPNOTSUPP);
122 }
123
124 static int set_addr(struct net_device *dev, void *addr)
125 {
126 struct sockaddr *sa;
127 char in_addr[sizeof("255.255.255.255")];
128 unsigned char *eth_addr;
129
130 sa = addr;
131 eth_addr = (unsigned char *) sa->sa_data;
132 sprintf(in_addr, "%d.%d.%d.%d", eth_addr[0], eth_addr[1], eth_addr[2],
133 eth_addr[3]);
134 return(set_umn_addr(umn.slipno, in_addr));
135 }
136
137 static int init_dev(struct net_device *dev)
138 {
139 dev->mtu = 1500;
140 dev->hard_start_xmit = xmit;
141 dev->open = open;
142 dev->stop = close;
143 dev->get_stats = NULL;
144 dev->do_ioctl = ioctl;
145 dev->hard_header_len = 0;
146 dev->addr_len = 4;
147 dev->type = ARPHRD_ETHER;
148 dev->tx_queue_len = 256;
149 dev->set_mac_address = set_addr;
150 dev_init_buffers(dev);
151 dev->flags = IFF_NOARP;
152 return 0;
153 }
154
155 int __init umn_init(void)
156 {
157 struct net_device *d;
158
159 d = &umn.dev;
160 d->name = "umn";
161 d->init = init_dev;
162 if(register_netdev(d))
163 printk("Couldn't initialize umn\n");
164 return(0);
165 }
166 __initcall(umn_init);
167
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.