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

Linux Cross Reference
Linux/net/wanrouter/wanproc.c

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

  1 /*****************************************************************************
  2 * wanproc.c     WAN Router Module. /proc filesystem interface.
  3 *
  4 *               This module is completely hardware-independent and provides
  5 *               access to the router using Linux /proc filesystem.
  6 *
  7 * Author:       Gideon Hack     
  8 *
  9 * Copyright:    (c) 1995-1999 Sangoma Technologies Inc.
 10 *
 11 *               This program is free software; you can redistribute it and/or
 12 *               modify it under the terms of the GNU General Public License
 13 *               as published by the Free Software Foundation; either version
 14 *               2 of the License, or (at your option) any later version.
 15 * ============================================================================
 16 * Jun 02, 1999  Gideon Hack     Updates for Linux 2.2.X kernels.
 17 * Jun 29, 1997  Alan Cox        Merged with 1.0.3 vendor code
 18 * Jan 29, 1997  Gene Kozin      v1.0.1. Implemented /proc read routines
 19 * Jan 30, 1997  Alan Cox        Hacked around for 2.1
 20 * Dec 13, 1996  Gene Kozin      Initial version (based on Sangoma's WANPIPE)
 21 *****************************************************************************/
 22 
 23 #include <linux/version.h>
 24 #include <linux/config.h>
 25 #include <linux/stddef.h>       /* offsetof(), etc. */
 26 #include <linux/errno.h>        /* return codes */
 27 #include <linux/kernel.h>
 28 #include <linux/malloc.h>       /* kmalloc(), kfree() */
 29 #include <linux/mm.h>           /* verify_area(), etc. */
 30 #include <linux/string.h>       /* inline mem*, str* functions */
 31 #include <linux/init.h>         /* __init et al. */
 32 #include <asm/segment.h>        /* kernel <-> user copy */
 33 #include <asm/byteorder.h>      /* htons(), etc. */
 34 #include <asm/uaccess.h>        /* copy_to_user */
 35 #include <asm/io.h>
 36 #include <linux/wanrouter.h>    /* WAN router API definitions */
 37 
 38 
 39 /****** Defines and Macros **************************************************/
 40 
 41 #define PROC_STATS_FORMAT "%30s: %12lu\n"
 42 
 43 #ifndef min
 44 #define min(a,b) (((a)<(b))?(a):(b))
 45 #endif
 46 #ifndef max
 47 #define max(a,b) (((a)>(b))?(a):(b))
 48 #endif
 49 
 50 #define PROC_BUFSZ      4000    /* buffer size for printing proc info */
 51 
 52 
 53 /****** Data Types **********************************************************/
 54 
 55 typedef struct wan_stat_entry
 56 {
 57         struct wan_stat_entry *next;
 58         char *description;              /* description string */
 59         void *data;                     /* -> data */
 60         unsigned data_type;             /* data type */
 61 } wan_stat_entry_t;
 62 
 63 /****** Function Prototypes *************************************************/
 64 
 65 #ifdef CONFIG_PROC_FS
 66 
 67 /* Proc filesystem interface */
 68 static int router_proc_perms(struct inode *, int);
 69 static ssize_t router_proc_read(struct file* file, char* buf, size_t count,                                     loff_t *ppos);
 70 
 71 /* Methods for preparing data for reading proc entries */
 72 
 73 static int config_get_info(char* buf, char** start, off_t offs, int len);
 74 static int status_get_info(char* buf, char** start, off_t offs, int len);
 75 static int wandev_get_info(char* buf, char** start, off_t offs, int len);
 76 
 77 /* Miscellaneous */
 78 
 79 /*
 80  *      Structures for interfacing with the /proc filesystem.
 81  *      Router creates its own directory /proc/net/router with the folowing
 82  *      entries:
 83  *      config          device configuration
 84  *      status          global device statistics
 85  *      <device>        entry for each WAN device
 86  */
 87 
 88 /*
 89  *      Generic /proc/net/router/<file> file and inode operations 
 90  */
 91 static struct file_operations router_fops =
 92 {
 93         read:           router_proc_read,
 94 };
 95 
 96 static struct inode_operations router_inode =
 97 {
 98         permission:     router_proc_perms,
 99 };
100 
101 /*
102  *      /proc/net/router/<device> file operations
103  */
104 
105 static struct file_operations wandev_fops =
106 {
107         read:           router_proc_read,
108         ioctl:          wanrouter_ioctl,
109 };
110 
111 /*
112  *      /proc/net/router 
113  */
114 
115 static struct proc_dir_entry *proc_router;
116 
117 /* Strings */
118 static char conf_hdr[] =
119         "Device name    | port |IRQ|DMA| mem.addr |mem.size|"
120         "option1|option2|option3|option4\n";
121         
122 static char stat_hdr[] =
123         "Device name    |station|interface|clocking|baud rate| MTU |ndev"
124         "|link state\n";
125 
126 
127 /*
128  *      Interface functions
129  */
130 
131 /*
132  *      Initialize router proc interface.
133  */
134 
135 int __init wanrouter_proc_init (void)
136 {
137         struct proc_dir_entry *p;
138         proc_router = proc_mkdir(ROUTER_NAME, proc_net);
139         if (!proc_router)
140                 goto fail;
141 
142         p = create_proc_entry("config",0,proc_router);
143         if (!p)
144                 goto fail_config;
145         p->proc_fops = &router_fops;
146         p->proc_iops = &router_inode;
147         p->get_info = config_get_info;
148         p = create_proc_entry("status",0,proc_router);
149         if (!p)
150                 goto fail_stat;
151         p->proc_fops = &router_fops;
152         p->proc_iops = &router_inode;
153         p->get_info = status_get_info;
154         return 0;
155 fail_stat:
156         remove_proc_entry("config", proc_router);
157 fail_config:
158         remove_proc_entry(ROUTER_NAME, proc_net);
159 fail:
160         return -ENOMEM;
161 }
162 
163 /*
164  *      Clean up router proc interface.
165  */
166 
167 void wanrouter_proc_cleanup (void)
168 {
169         remove_proc_entry("config", proc_router);
170         remove_proc_entry("status", proc_router);
171         remove_proc_entry(ROUTER_NAME,proc_net);
172 }
173 
174 /*
175  *      Add directory entry for WAN device.
176  */
177 
178 int wanrouter_proc_add (wan_device_t* wandev)
179 {
180         if (wandev->magic != ROUTER_MAGIC)
181                 return -EINVAL;
182                 
183         wandev->dent = create_proc_entry(wandev->name, 0, proc_router);
184         if (!wandev->dent)
185                 return -ENOMEM;
186         wandev->dent->proc_fops = &wandev_fops;
187         wandev->dent->proc_iops = &router_inode;
188         wandev->dent->get_info  = wandev_get_info;
189         wandev->dent->data      = wandev;
190         return 0;
191 }
192 
193 /*
194  *      Delete directory entry for WAN device.
195  */
196  
197 int wanrouter_proc_delete(wan_device_t* wandev)
198 {
199         if (wandev->magic != ROUTER_MAGIC)
200                 return -EINVAL;
201         remove_proc_entry(wandev->name, proc_router);
202         return 0;
203 }
204 
205 /****** Proc filesystem entry points ****************************************/
206 
207 /*
208  *      Verify access rights.
209  */
210 
211 static int router_proc_perms (struct inode* inode, int op)
212 {
213         return 0;
214 }
215 
216 /*
217  *      Read router proc directory entry.
218  *      This is universal routine for reading all entries in /proc/net/wanrouter
219  *      directory.  Each directory entry contains a pointer to the 'method' for
220  *      preparing data for that entry.
221  *      o verify arguments
222  *      o allocate kernel buffer
223  *      o call get_info() to prepare data
224  *      o copy data to user space
225  *      o release kernel buffer
226  *
227  *      Return: number of bytes copied to user space (0, if no data)
228  *              <0      error
229  */
230 
231 static ssize_t router_proc_read(struct file* file, char* buf, size_t count,
232                                 loff_t *ppos)
233 {
234         struct inode *inode = file->f_dentry->d_inode;
235         struct proc_dir_entry* dent;
236         char* page;
237         int pos, offs, len;
238 
239         if (count <= 0)
240                 return 0;
241                 
242         dent = inode->u.generic_ip;
243         if ((dent == NULL) || (dent->get_info == NULL))
244                 return 0;
245                 
246         page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
247         if (page == NULL)
248                 return -ENOBUFS;
249                 
250         pos = dent->get_info(page, dent->data, 0, 0);
251         offs = file->f_pos;
252         if (offs < pos) {
253                 len = min(pos - offs, count);
254                 if(copy_to_user(buf, (page + offs), len))
255                         return -EFAULT;
256                 file->f_pos += len;
257         }
258         else
259                 len = 0;
260         kfree(page);
261         return len;
262 }
263 
264 /*
265  *      Prepare data for reading 'Config' entry.
266  *      Return length of data.
267  */
268 
269 static int config_get_info(char* buf, char** start, off_t offs, int len)
270 {
271         int cnt = sizeof(conf_hdr) - 1;
272         wan_device_t* wandev;
273         strcpy(buf, conf_hdr);
274         for (wandev = router_devlist;
275              wandev && (cnt < (PROC_BUFSZ - 120));
276              wandev = wandev->next) {
277                 if (wandev->state) cnt += sprintf(&buf[cnt],
278                         "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
279                         wandev->name,
280                         wandev->ioport,
281                         wandev->irq,
282                         wandev->dma,
283                         wandev->maddr,
284                         wandev->msize,
285                         wandev->hw_opt[0],
286                         wandev->hw_opt[1],
287                         wandev->hw_opt[2],
288                         wandev->hw_opt[3]);
289         }
290 
291         return cnt;
292 }
293 
294 /*
295  *      Prepare data for reading 'Status' entry.
296  *      Return length of data.
297  */
298 
299 static int status_get_info(char* buf, char** start, off_t offs, int len)
300 {
301         int cnt = 0;
302         wan_device_t* wandev;
303 
304         cnt += sprintf(&buf[cnt], "\nSTATUS FOR PORT 0\n\n");
305         strcpy(&buf[cnt], stat_hdr);
306         cnt += sizeof(stat_hdr) - 1;
307 
308         for (wandev = router_devlist;
309              wandev && (cnt < (PROC_BUFSZ - 80));
310              wandev = wandev->next) {
311                 if (!wandev->state) continue;
312                 cnt += sprintf(&buf[cnt],
313                         "%-15s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
314                         wandev->name,
315                         wandev->station ? " DCE" : " DTE",
316                         wandev->interface ? " V.35" : " RS-232",
317                         wandev->clocking ? "internal" : "external",
318                         wandev->bps,
319                         wandev->mtu,
320                         wandev->ndev);
321 
322                 switch (wandev->state) {
323 
324                 case WAN_UNCONFIGURED:
325                         cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
326                         break;
327 
328                 case WAN_DISCONNECTED:
329                         cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");
330                         break;
331 
332                 case WAN_CONNECTING:
333                         cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");
334                         break;
335 
336                 case WAN_CONNECTED:
337                         cnt += sprintf(&buf[cnt], "%-12s\n", "connected");
338                         break;
339 
340                 default:
341                         cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");
342                         break;
343                 }
344         }
345         return cnt;
346 }
347 
348 /*
349  *      Prepare data for reading <device> entry.
350  *      Return length of data.
351  *
352  *      On entry, the 'start' argument will contain a pointer to WAN device
353  *      data space.
354  */
355 
356 static int wandev_get_info(char* buf, char** start, off_t offs, int len)
357 {
358         wan_device_t* wandev = (void*)start;
359         int cnt = 0;
360         int rslt = 0;
361 
362         if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
363                 return 0;
364         if (!wandev->state)
365                 return sprintf(&buf[cnt], "device is not configured!\n");
366 
367         /* Update device statistics */
368         if (wandev->update) {
369 
370                 rslt = wandev->update(wandev);
371                 if(rslt) {
372                         switch (rslt) {
373                         case -EAGAIN:
374                                 return sprintf(&buf[cnt], "Device is busy!\n");
375 
376                         default:
377                                 return sprintf(&buf[cnt],
378                                         "Device is not configured!\n");
379                         }
380                 }
381         }
382 
383         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
384                 "total packets received", wandev->stats.rx_packets);
385         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
386                 "total packets transmitted", wandev->stats.tx_packets);
387         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
388                 "total bytes received", wandev->stats.rx_bytes);
389         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
390                 "total bytes transmitted", wandev->stats.tx_bytes);
391         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
392                 "bad packets received", wandev->stats.rx_errors);
393         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
394                 "packet transmit problems", wandev->stats.tx_errors);
395         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
396                 "received frames dropped", wandev->stats.rx_dropped);
397         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
398                 "transmit frames dropped", wandev->stats.tx_dropped);
399         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
400                 "multicast packets received", wandev->stats.multicast);
401         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
402                 "transmit collisions", wandev->stats.collisions);
403         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
404                 "receive length errors", wandev->stats.rx_length_errors);
405         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
406                 "receiver overrun errors", wandev->stats.rx_over_errors);
407         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
408                 "CRC errors", wandev->stats.rx_crc_errors);
409         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
410                 "frame format errors (aborts)", wandev->stats.rx_frame_errors);
411         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
412                 "receiver fifo overrun", wandev->stats.rx_fifo_errors);
413         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
414                 "receiver missed packet", wandev->stats.rx_missed_errors);
415         cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
416                 "aborted frames transmitted", wandev->stats.tx_aborted_errors);
417         return cnt;
418 }
419 
420 /*
421  *      End
422  */
423  
424 #else
425 
426 /*
427  *      No /proc - output stubs
428  */
429  
430 int __init wanrouter_proc_init(void)
431 {
432         return 0;
433 }
434 
435 void wanrouter_proc_cleanup(void)
436 {
437         return;
438 }
439 
440 int wanrouter_proc_add(wan_device_t *wandev)
441 {
442         return 0;
443 }
444 
445 int wanrouter_proc_delete(wan_device_t *wandev)
446 {
447         return 0;
448 }
449 
450 #endif
451 
452 /*
453  *      End
454  */
455  
456 

~ [ 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.