]>
git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/ibod/ibod.c
1 /* Customised version of ibod - GUI code removed by Mark Wormgoor
2 * Buffer overflow fixes by Robert Kerr
4 * ibod originally by Bjoern Smith
7 static char *rcsId
= "$Id: ibod.c,v 1.1.1.1.8.1 2005/05/07 12:46:16 rkerr Exp $";
8 static char *rcsSymbol
= "$Symbol$";
15 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <linux/isdn.h>
26 static void reread(int sig
);
27 static void pipehndl(int sig
);
28 static void setinterval();
29 static void get_if_state();
30 static int bring_up_slave();
31 static int bring_down_slave();
33 static struct timeval timeout
, tv_last
, tv_up
;
34 static int usageflags
[ISDN_MAX_CHANNELS
];
35 static char phone
[ISDN_MAX_CHANNELS
][20];
36 static Siobytes iobytes
[ISDN_MAX_CHANNELS
];
37 static unsigned long in_bytes_last
, out_bytes_last
;
38 static unsigned long in_bytes_per_sec
, out_bytes_per_sec
;
39 static unsigned long channels_last
;
40 static int channels_now
;
42 main(int argc
, char *argv
[])
44 openlog("ibod", LOG_PID
, LOG_DAEMON
);
48 /* Setup initial attributes */
49 if (setattr() == -1) {
56 /* Setup handlig of signal SIGHUP and SIGPIPE */
57 signal(SIGHUP
, reread
);
58 signal(SIGPIPE
, pipehndl
);
63 usleep(timeout
.tv_usec
);
65 /* Gate state of interface */
75 char config_filename
[MAX_STR_LEN
] = IBOD_DEFAULT_DIR
"/ibod.cf";
76 char linebuf
[MAX_STR_LEN
];
80 strcpy(cf
.dev
, DEVICE
);
82 cf
.interval
= INTERVAL
;
86 cf
.stayup_time
= STAYUP_TIME
;
88 /* Open config file */
89 if ((fd
= fopen(config_filename
, "r")) == NULL
) {
90 syslog(LOG_ERR
, "%s: %s\n", config_filename
, strerror(errno
));
94 /* Loop over the config file to setup attributes */
95 while (fgets(linebuf
, MAX_STR_LEN
, fd
) != NULL
) {
97 if (*linebuf
== '#') /* Ignore comments */
100 key
= strtok(linebuf
, " \t");
101 value
= strtok(NULL
, " \t\n");
103 if (strcmp(key
, "DEVICE") == 0) {
104 if (strcmp(cf
.dev
, value
) != 0)
106 "Parameter DEVICE reconfigured to %s\n", value
);
107 snprintf(cf
.dev
, 32,"%s", value
);
110 if (strcmp(key
, "ENABLE") == 0) {
112 if (cf
.enable
!= val
)
114 "Parameter ENABLE reconfigured to %d\n", val
);
118 if (strcmp(key
, "INTERVAL") == 0) {
120 if (cf
.interval
!= val
)
122 "Parameter INTERVAL reconfigured to %d\n", val
);
123 cf
.interval
= atoi(value
);
126 if (strcmp(key
, "FILTER") == 0) {
128 if (cf
.filter
!= val
)
130 "Parameter FILTER reconfigured to %d\n", val
);
131 cf
.filter
= atoi(value
);
134 if (strcmp(key
, "LIMIT") == 0) {
138 "Parameter LIMIT reconfigured to %d\n", val
);
139 cf
.limit
= atoi(value
);
142 if (strcmp(key
, "STAYUP") == 0) {
144 if (cf
.stayup
!= val
)
146 "Parameter STAYUP reconfigured to %d\n", val
);
147 cf
.stayup
= atoi(value
);
150 if (strcmp(key
, "STAYUP_TIME") == 0) {
152 if (cf
.stayup_time
!= val
)
154 "Parameter STAYUP_TIME reconfigured to %d\n", val
);
155 cf
.stayup_time
= atoi(value
);
165 static void setinterval()
167 timeout
.tv_sec
= cf
.interval
/ 1000;
168 timeout
.tv_usec
= (cf
.interval
% 1000) * 1000;
172 static void reread(int sig
)
178 signal(SIGHUP
, reread
);
182 static void pipehndl(int sig
)
184 syslog(LOG_ERR
, "caught SIGPIPE: %s\n", sys_errlist
[errno
]);
186 signal(SIGPIPE
, pipehndl
);
190 static void get_if_state()
192 static char buf
[4096];
193 struct timeval tv_now
;
195 int in_bytes_now
, out_bytes_now
;
199 /* Open the info device */
200 if ((fd
= open(ISDN_INFO_DEV
, O_RDONLY
| O_NDELAY
)) < 0) {
201 syslog(LOG_ERR
, "%s: %s\n", ISDN_INFO_DEV
, sys_errlist
[errno
]);
206 /* Whats the time now */
207 gettimeofday(&tv_now
, NULL
);
208 ms_delta
= (tv_now
.tv_sec
* 1000 + tv_now
.tv_usec
/ 1000) -
209 (tv_last
.tv_sec
* 1000 + tv_last
.tv_usec
/ 1000);
212 /* Get info from interface */
213 if (read(fd
, buf
, sizeof(buf
))> 0) {
214 sscanf(strstr(buf
, "usage:"),
215 "usage: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
216 &usageflags
[0], &usageflags
[1], &usageflags
[2], &usageflags
[3],
217 &usageflags
[4], &usageflags
[5], &usageflags
[6], &usageflags
[7],
218 &usageflags
[8], &usageflags
[9], &usageflags
[10], &usageflags
[11],
219 &usageflags
[12], &usageflags
[13], &usageflags
[14], &usageflags
[15]);
220 sscanf(strstr(buf
, "phone:"),
221 "phone: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
222 phone
[0], phone
[1], phone
[2], phone
[3],
223 phone
[4], phone
[5], phone
[6], phone
[7],
224 phone
[8], phone
[8], phone
[10], phone
[11],
225 phone
[12], phone
[13], phone
[14], phone
[15]);
232 /* Get byte in/out for all channels */
233 if (ioctl(fd
, IIOCGETCPS
, &iobytes
)) {
234 syslog(LOG_ERR
, "%s: %s\n", IIOCGETCPS
, sys_errlist
[errno
]);
240 /* Count number of open channes and total in/out bytes */
241 for (i
= 0; i
< ISDN_MAX_CHANNELS
; i
++) {
244 in_bytes_now
+= iobytes
[i
].ibytes
;
245 out_bytes_now
+= iobytes
[i
].obytes
;
249 if (channels_last
== -1 || channels_now
< channels_last
) {
250 channels_last
= channels_now
;
251 in_bytes_last
= in_bytes_now
;
252 out_bytes_last
= out_bytes_now
;
256 /* Calculate the total through put in bytes/sec */
259 (in_bytes_now
- in_bytes_last
) * 1000 / ms_delta
;
261 (out_bytes_now
- out_bytes_last
) * 1000 / ms_delta
;
264 in_bytes_per_sec
= (in_bytes_per_sec
* (cf
.filter
- 1) +
265 (in_bytes_now
- in_bytes_last
) * 1000 / ms_delta
) / cf
.filter
;
266 out_bytes_per_sec
= (out_bytes_per_sec
* (cf
.filter
- 1) +
267 (out_bytes_now
- out_bytes_last
) * 1000 / ms_delta
) / cf
.filter
;
270 in_bytes_last
= in_bytes_now
;
271 out_bytes_last
= out_bytes_now
;
273 if (channels_now
== 0) {
274 channels_last
= channels_now
;
278 /* Take up or down slave channel */
280 if (cf
.enable
== 0) {
281 channels_last
= channels_now
;
285 if (channels_now
== 1 &&
286 (in_bytes_per_sec
> cf
.limit
|| out_bytes_per_sec
> cf
.limit
)) {
288 /* Bring up slave interface */
289 if (bring_up_slave() == -1)
292 /* Start stay up timer */
293 gettimeofday(&tv_up
, NULL
);
296 if ((channels_now
> 1) &&
297 (in_bytes_per_sec
<= cf
.limit
) &&
298 (out_bytes_per_sec
<= cf
.limit
) &&
301 /* Check that the min stay up timer has expired */
302 gettimeofday(&tv_now
, NULL
);
303 if (tv_now
.tv_sec
- tv_up
.tv_sec
> cf
.stayup_time
) {
305 /* Bring down slave interface */
306 if (bring_down_slave() == -1)
311 channels_last
= channels_now
;
315 static int bring_up_slave()
319 if ((fd
= open(ISDN_CTLR_DEV
, O_RDWR
)) < 0) {
320 syslog(LOG_ERR
, "%s: %s\n", ISDN_CTLR_DEV
, sys_errlist
[errno
]);
325 if ((rc
= ioctl(fd
, IIOCNETALN
, cf
.dev
)) < 0) {
326 syslog(LOG_ERR
, "%s: %s\n", cf
.dev
, sys_errlist
[errno
]);
334 syslog(LOG_NOTICE
, "added new link\n");
342 static int bring_down_slave()
346 if ((fd
= open(ISDN_CTLR_DEV
, O_RDWR
)) < 0) {
347 syslog(LOG_ERR
, "%s: %s\n", ISDN_CTLR_DEV
, sys_errlist
[errno
]);
352 if ((rc
= ioctl(fd
, IIOCNETDLN
, cf
.dev
)) < 0) {
353 syslog(LOG_ERR
, "%s: %s\n", cf
.dev
, sys_errlist
[errno
]);
361 syslog(LOG_ERR
, "unable to remove additional link: %d\n", rc
);
363 syslog(LOG_NOTICE
, "removed link\n");