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

Linux Cross Reference
Linux/net/decnet/sysctl_net_decnet.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * DECnet       An implementation of the DECnet protocol suite for the LINUX
  3  *              operating system.  DECnet is implemented using the  BSD Socket
  4  *              interface as the means of communication with the user level.
  5  *
  6  *              DECnet sysctl support functions
  7  *
  8  * Author:      Steve Whitehouse <SteveW@ACM.org>
  9  *
 10  *
 11  * Changes:
 12  *
 13  */
 14 #include <linux/config.h>
 15 #include <linux/mm.h>
 16 #include <linux/sysctl.h>
 17 #include <linux/fs.h>
 18 #include <linux/netdevice.h>
 19 #include <linux/string.h>
 20 #include <net/neighbour.h>
 21 #include <net/dst.h>
 22 
 23 #include <asm/uaccess.h>
 24 
 25 #include <net/dn.h>
 26 #include <net/dn_dev.h>
 27 #include <net/dn_route.h>
 28 
 29 
 30 int decnet_debug_level = 0;
 31 int decnet_time_wait = 30;
 32 int decnet_dn_count = 1;
 33 int decnet_di_count = 3;
 34 int decnet_dr_count = 3;
 35 int decnet_log_martians = 1;
 36 
 37 #ifdef CONFIG_SYSCTL
 38 extern int decnet_dst_gc_interval;
 39 static int min_decnet_time_wait[] = { 5 };
 40 static int max_decnet_time_wait[] = { 600 };
 41 static int min_state_count[] = { 1 };
 42 static int max_state_count[] = { NSP_MAXRXTSHIFT };
 43 static int min_decnet_dst_gc_interval[] = { 1 };
 44 static int max_decnet_dst_gc_interval[] = { 60 };
 45 static char node_name[7] = "???";
 46 
 47 static struct ctl_table_header *dn_table_header = NULL;
 48 
 49 /*
 50  * ctype.h :-)
 51  */
 52 #define ISNUM(x) (((x) >= '') && ((x) <= '9'))
 53 #define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z'))
 54 #define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z'))
 55 #define ISALPHA(x) (ISLOWER(x) || ISUPPER(x))
 56 #define INVALID_END_CHAR(x) (ISNUM(x) || ISALPHA(x))
 57 
 58 static void strip_it(char *str)
 59 {
 60         for(;;) {
 61                 switch(*str) {
 62                         case ' ':
 63                         case '\n':
 64                         case '\r':
 65                         case ':':
 66                                 *str = 0;
 67                         case 0:
 68                                 return;
 69                 }
 70                 str++;
 71         }
 72 }
 73 
 74 /*
 75  * Simple routine to parse an ascii DECnet address
 76  * into a network order address.
 77  */
 78 static int parse_addr(dn_address *addr, char *str)
 79 {
 80         dn_address area, node;
 81 
 82         while(*str && !ISNUM(*str)) str++;
 83 
 84         if (*str == 0)
 85                 return -1;
 86 
 87         area = (*str++ - '');
 88         if (ISNUM(*str)) {
 89                 area *= 10;
 90                 area += (*str++ - '');
 91         }
 92 
 93         if (*str++ != '.')
 94                 return -1;
 95 
 96         if (!ISNUM(*str))
 97                 return -1;
 98 
 99         node = *str++ - '';
100         if (ISNUM(*str)) {
101                 node *= 10;
102                 node += (*str++ - '');
103         }
104         if (ISNUM(*str)) {
105                 node *= 10;
106                 node += (*str++ - '');
107         }
108         if (ISNUM(*str)) {
109                 node *= 10;
110                 node += (*str++ - '');
111         }
112 
113         if ((node > 1023) || (area > 63))
114                 return -1;
115 
116         if (INVALID_END_CHAR(*str))
117                 return -1;
118 
119         *addr = dn_htons((area << 10) | node);
120 
121         return 0;
122 }
123 
124 
125 static int dn_node_address_strategy(ctl_table *table, int *name, int nlen,
126                                 void *oldval, size_t *oldlenp,
127                                 void *newval, size_t newlen,
128                                 void **context)
129 {
130         int len;
131         dn_address addr;
132 
133         if (oldval && oldlenp) {
134                 if (get_user(len, oldlenp))
135                         return -EFAULT;
136                 if (len) {
137                         if (len != sizeof(unsigned short))
138                                 return -EINVAL;
139                         if (put_user(decnet_address, (unsigned short *)oldval))
140                                 return -EFAULT;
141                 }
142         }
143         if (newval && newlen) {
144                 if (newlen != sizeof(unsigned short))
145                         return -EINVAL;
146                 if (get_user(addr, (unsigned short *)newval))
147                         return -EFAULT;
148 
149                 dn_dev_devices_off();
150 
151                 decnet_address = addr;
152                 dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address));
153 
154                 dn_dev_devices_on();
155         }
156         return 0;
157 }
158 
159 static int dn_node_address_handler(ctl_table *table, int write, 
160                                 struct file *filp,
161                                 void *buffer, size_t *lenp)
162 {
163         char addr[DN_ASCBUF_LEN];
164         int len;
165         dn_address dnaddr;
166 
167         if (!*lenp || (filp->f_pos && !write)) {
168                 *lenp = 0;
169                 return 0;
170         }
171 
172         if (write) {
173                 int len = (*lenp < DN_ASCBUF_LEN) ? *lenp : (DN_ASCBUF_LEN-1);
174 
175                 if (copy_from_user(addr, buffer, len))
176                         return -EFAULT;
177 
178                 addr[len] = 0;
179                 strip_it(addr);
180 
181                 if (parse_addr(&dnaddr, addr))
182                         return -EINVAL;
183 
184                 dn_dev_devices_off();
185 
186                 decnet_address = dnaddr;
187                 dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address));
188 
189                 dn_dev_devices_on();
190 
191                 filp->f_pos += len;
192 
193                 return 0;
194         }
195 
196         dn_addr2asc(dn_ntohs(decnet_address), addr);
197         len = strlen(addr);
198         addr[len++] = '\n';
199 
200         if (len > *lenp) len = *lenp;
201 
202         if (copy_to_user(buffer, addr, len))
203                 return -EFAULT;
204 
205         *lenp = len;
206         filp->f_pos += len;
207 
208         return 0;
209 }
210 
211 
212 static int dn_def_dev_strategy(ctl_table *table, int *name, int nlen,
213                                 void *oldval, size_t *oldlenp,
214                                 void *newval, size_t newlen,
215                                 void **context)
216 {
217         size_t len;
218         struct net_device *dev = decnet_default_device;
219         char devname[17];
220         size_t namel;
221 
222         devname[0] = 0;
223 
224         if (oldval && oldlenp) {
225                 if (get_user(len, oldlenp))
226                         return -EFAULT;
227                 if (len) {
228                         if (dev)
229                                 strcpy(devname, dev->name);
230 
231                         namel = strlen(devname) + 1;
232                         if (len > namel) len = namel;   
233 
234                         if (copy_to_user(oldval, devname, len))
235                                 return -EFAULT;
236 
237                         if (put_user(len, oldlenp))
238                                 return -EFAULT;
239                 }
240         }
241 
242         if (newval && newlen) {
243                 if (newlen > 16)
244                         return -E2BIG;
245 
246                 if (copy_from_user(devname, newval, newlen))
247                         return -EFAULT;
248 
249                 devname[newlen] = 0;
250 
251                 if ((dev = __dev_get_by_name(devname)) == NULL)
252                         return -ENODEV;
253 
254                 if (dev->dn_ptr == NULL)
255                         return -ENODEV;
256 
257                 decnet_default_device = dev;
258         }
259 
260         return 0;
261 }
262 
263 
264 static int dn_def_dev_handler(ctl_table *table, int write, 
265                                 struct file * filp,
266                                 void *buffer, size_t *lenp)
267 {
268         int len;
269         struct net_device *dev = decnet_default_device;
270         char devname[17];
271 
272         if (!*lenp || (filp->f_pos && !write)) {
273                 *lenp = 0;
274                 return 0;
275         }
276 
277         if (write) {
278                 if (*lenp > 16)
279                         return -E2BIG;
280 
281                 if (copy_from_user(devname, buffer, *lenp))
282                         return -EFAULT;
283 
284                 devname[*lenp] = 0;
285                 strip_it(devname);
286 
287                 if ((dev = __dev_get_by_name(devname)) == NULL)
288                         return -ENODEV;
289 
290                 if (dev->dn_ptr == NULL)
291                         return -ENODEV;
292 
293                 decnet_default_device = dev;
294                 filp->f_pos += *lenp;
295 
296                 return 0;
297         }
298 
299         if (dev == NULL) {
300                 *lenp = 0;
301                 return 0;
302         }
303 
304         strcpy(devname, dev->name);
305         len = strlen(devname);
306         devname[len++] = '\n';
307 
308         if (len > *lenp) len = *lenp;
309 
310         if (copy_to_user(buffer, devname, len))
311                 return -EFAULT;
312 
313         *lenp = len;
314         filp->f_pos += len;
315 
316         return 0;
317 }
318 
319 static ctl_table dn_table[] = {
320         {NET_DECNET_NODE_ADDRESS, "node_address", NULL, 7, 0644, NULL,
321         dn_node_address_handler, dn_node_address_strategy, NULL,
322         NULL, NULL},
323         {NET_DECNET_NODE_NAME, "node_name", node_name, 7, 0644, NULL,
324         &proc_dostring, &sysctl_string, NULL, NULL, NULL},
325         {NET_DECNET_DEFAULT_DEVICE, "default_device", NULL, 16, 0644, NULL,
326         dn_def_dev_handler, dn_def_dev_strategy, NULL, NULL, NULL},
327         {NET_DECNET_TIME_WAIT, "time_wait", &decnet_time_wait,
328         sizeof(int), 0644,
329         NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
330         &min_decnet_time_wait, &max_decnet_time_wait},
331         {NET_DECNET_DN_COUNT, "dn_count", &decnet_dn_count,
332         sizeof(int), 0644,
333         NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
334         &min_state_count, &max_state_count},
335         {NET_DECNET_DI_COUNT, "di_count", &decnet_di_count,
336         sizeof(int), 0644,
337         NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
338         &min_state_count, &max_state_count},
339         {NET_DECNET_DR_COUNT, "dr_count", &decnet_dr_count,
340         sizeof(int), 0644,
341         NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
342         &min_state_count, &max_state_count},
343         {NET_DECNET_DST_GC_INTERVAL, "dst_gc_interval", &decnet_dst_gc_interval,
344         sizeof(int), 0644,
345         NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
346         &min_decnet_dst_gc_interval, &max_decnet_dst_gc_interval},
347         {NET_DECNET_DEBUG_LEVEL, "debug", &decnet_debug_level, 
348         sizeof(int), 0644, 
349         NULL, &proc_dointvec, &sysctl_intvec, NULL,
350         NULL, NULL},
351         {0}
352 };
353 
354 static ctl_table dn_dir_table[] = {
355         {NET_DECNET, "decnet", NULL, 0, 0555, dn_table},
356         {0}
357 };
358 
359 static ctl_table dn_root_table[] = {
360         {CTL_NET, "net", NULL, 0, 0555, dn_dir_table},
361         {0}
362 };
363 
364 void dn_register_sysctl(void)
365 {
366         dn_table_header = register_sysctl_table(dn_root_table, 1);
367 }
368 
369 void dn_unregister_sysctl(void)
370 {
371         unregister_sysctl_table(dn_table_header);
372 }
373 
374 #else  /* CONFIG_SYSCTL */
375 void dn_unregister_sysctl(void)
376 {
377 }
378 void dn_register_sysctl(void)
379 {
380 }
381 
382 #endif
383 

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

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.