This source file includes following definitions.
- netlink_err
- netlink_donothing
- netlink_write
- netlink_read
- netlink_lseek
- netlink_open
- netlink_release
- netlink_ioctl
- netlink_attach
- netlink_detach
- netlink_post
- init_module
- cleanup_module
- init_netlink
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/config.h>
15
16 #if defined(CONFIG_NETLINK) || defined(MODULE)
17 #ifdef MODULE
18 #include <linux/module.h>
19 #include <linux/version.h>
20 #else
21 #define MOD_INC_USE_COUNT
22 #define MOD_DEC_USE_COUNT
23 #endif
24
25 #include <linux/errno.h>
26 #include <linux/kernel.h>
27 #include <linux/major.h>
28 #include <linux/sched.h>
29 #include <linux/lp.h>
30 #include <linux/malloc.h>
31 #include <linux/ioport.h>
32 #include <linux/fcntl.h>
33 #include <linux/delay.h>
34 #include <linux/skbuff.h>
35
36 #include <net/netlink.h>
37
38 #include <asm/io.h>
39 #include <asm/segment.h>
40 #include <asm/system.h>
41
42 static int (*netlink_handler[MAX_LINKS])(struct sk_buff *skb);
43 static struct sk_buff_head skb_queue_rd[MAX_LINKS];
44 static int rdq_size[MAX_LINKS];
45 static struct wait_queue *read_space_wait[MAX_LINKS];
46
47 static int active_map = 0;
48 static int open_map = 0;
49
50
51
52
53
54
55
56
57
58 static int netlink_err(struct sk_buff *skb)
59 {
60 kfree_skb(skb, FREE_READ);
61 return -EUNATCH;
62 }
63
64
65
66
67
68
69 int netlink_donothing(struct sk_buff *skb)
70 {
71 kfree_skb(skb, FREE_READ);
72 return -EINVAL;
73 }
74
75
76
77
78
79 static int netlink_write(struct inode * inode, struct file * file, const char * buf, int count)
80 {
81 unsigned int minor = MINOR(inode->i_rdev);
82 struct sk_buff *skb;
83 skb=alloc_skb(count, GFP_KERNEL);
84 memcpy_fromfs(skb_put(skb,count),buf, count);
85 return (netlink_handler[minor])(skb);
86 }
87
88
89
90
91
92 static int netlink_read(struct inode * inode, struct file * file, char * buf, int count)
93 {
94 unsigned int minor = MINOR(inode->i_rdev);
95 struct sk_buff *skb;
96 cli();
97 while((skb=skb_dequeue(&skb_queue_rd[minor]))==NULL)
98 {
99 if(file->f_flags&O_NONBLOCK)
100 {
101 sti();
102 return -EWOULDBLOCK;
103 }
104 interruptible_sleep_on(&read_space_wait[minor]);
105 if(current->signal & ~current->blocked)
106 {
107 sti();
108 return -ERESTARTSYS;
109 }
110 }
111 rdq_size[minor]-=skb->len;
112 sti();
113 if(skb->len<count)
114 count=skb->len;
115 memcpy_tofs(buf,skb->data,count);
116 kfree_skb(skb, FREE_READ);
117 return count;
118 }
119
120 static int netlink_lseek(struct inode * inode, struct file * file,
121 off_t offset, int origin)
122 {
123 return -ESPIPE;
124 }
125
126 static int netlink_open(struct inode * inode, struct file * file)
127 {
128 unsigned int minor = MINOR(inode->i_rdev);
129
130 if(minor>=MAX_LINKS)
131 return -ENODEV;
132 if(open_map&(1<<minor))
133 return -EBUSY;
134 if(active_map&(1<<minor))
135 {
136 open_map|=(1<<minor);
137 return 0;
138 }
139 return -EUNATCH;
140 }
141
142 static void netlink_release(struct inode * inode, struct file * file)
143 {
144 unsigned int minor = MINOR(inode->i_rdev);
145 open_map&=~(1<<minor);
146 MOD_DEC_USE_COUNT;
147 }
148
149
150 static int netlink_ioctl(struct inode *inode, struct file *file,
151 unsigned int cmd, unsigned long arg)
152 {
153 unsigned int minor = MINOR(inode->i_rdev);
154 int retval = 0;
155
156 if (minor >= MAX_LINKS)
157 return -ENODEV;
158 switch ( cmd ) {
159 default:
160 retval = -EINVAL;
161 }
162 return retval;
163 }
164
165
166 static struct file_operations netlink_fops = {
167 netlink_lseek,
168 netlink_read,
169 netlink_write,
170 NULL,
171 NULL,
172 netlink_ioctl,
173 NULL,
174 netlink_open,
175 netlink_release
176 };
177
178
179
180
181
182
183
184 int netlink_attach(int unit, int (*function)(struct sk_buff *skb))
185 {
186 if(unit>=MAX_LINKS)
187 return -ENODEV;
188 if(active_map&(1<<unit))
189 return -EBUSY;
190 active_map|=(1<<unit);
191 netlink_handler[unit]=function;
192 return 0;
193 }
194
195 void netlink_detach(int unit)
196 {
197 active_map&=~(1<<unit);
198 netlink_handler[unit]=netlink_err;
199 }
200
201 int netlink_post(int unit, struct sk_buff *skb)
202 {
203 unsigned long flags;
204 int ret=0;
205 if(open_map&(1<<unit))
206 {
207 save_flags(flags);
208 cli();
209 if(rdq_size[unit]+skb->len>MAX_QBYTES)
210 ret=-EWOULDBLOCK;
211 else
212 {
213 skb_queue_tail(&skb_queue_rd[unit], skb);
214 rdq_size[unit]+=skb->len;
215 ret=0;
216 wake_up_interruptible(&read_space_wait[unit]);
217 }
218 restore_flags(flags);
219 }
220 return ret;
221 }
222
223
224 #ifdef MODULE
225 char kernel_version[]=UTS_RELEASE;
226
227 int init_module(void)
228 {
229 int ct;
230 printk("Network Kernel/User communications module 0.03\n");
231 if (register_chrdev(NET_MAJOR,"netlink",&netlink_fops)) {
232 printk("netlink: unable to get major %d\n", NET_MAJOR);
233 return -EIO;
234 }
235 for(ct=0;ct<MAX_LINKS;ct++)
236 {
237 skb_queue_head_init(&skb_queue_rd[ct]);
238 netlink_handler[ct]=netlink_err;
239 }
240 return 0;
241 }
242
243 void cleanup_module(void)
244 {
245 unregister_chrdev(NET_MAJOR,"netlink");
246 }
247
248 #else
249
250 void init_netlink(void)
251 {
252 int ct;
253
254 if(register_chrdev(NET_MAJOR,"netlink", &netlink_fops))
255 printk("netlink: unable to get major %d\n", NET_MAJOR);
256 for(ct=0;ct<MAX_LINKS;ct++)
257 {
258 skb_queue_head_init(&skb_queue_rd[ct]);
259 netlink_handler[ct]=netlink_err;
260 }
261 }
262
263 #endif
264 #endif