13 #include <linux/slab.h>
48 static ulong next_id = 1;
51 static unsigned char extern_wait_max = 4;
58 static void deflect_timer_expire(
ulong arg)
65 spin_unlock_irqrestore(&divert_lock, flags);
75 spin_unlock_irqrestore(&divert_lock, flags);
87 spin_unlock_irqrestore(&divert_lock, flags);
96 divert_head = cs->
next;
99 spin_unlock_irqrestore(&divert_lock, flags);
114 {
unsigned long flags;
117 char *
p, *ielenp,
tmp[60];
121 if ((proc & 0x7F) > 2)
return (-
EINVAL);
134 {
if (!*fwd_nr)
return (-
EINVAL);
154 *ielenp = p - ielenp - 1;
161 cs->
timer.function = deflect_timer_expire;
166 cs->
ics.
parm.dss1_io.proc = (mode == 1) ? 7 : (mode == 2) ? 11 : 8;
167 cs->
ics.
parm.dss1_io.timeout = 4000;
172 cs->
ics.
parm.dss1_io.ll_id = next_id++;
173 spin_unlock_irqrestore(&divert_lock, flags);
174 *procid = cs->
ics.
parm.dss1_io.ll_id;
176 sprintf(cs->
info,
"%d 0x%lx %s%s 0 %s %02x %d%s%s\n",
179 (mode != 2) ?
"" :
"0 ",
184 (mode != 1) ?
"" :
" 0 ",
185 (mode != 1) ?
"" : fwd_nr);
192 cs->
next = divert_head;
194 spin_unlock_irqrestore(&divert_lock, flags);
211 if ((cmd & 0x7F) > 2)
return (-
EINVAL);
217 if (!cs)
return (-
EINVAL);
232 spin_unlock_irqrestore(&divert_lock, flags);
246 spin_unlock_irqrestore(&divert_lock, flags);
263 spin_unlock_irqrestore(&divert_lock, flags);
290 while ((ds1) && (idx > 0))
298 { ds->
prev = table_tail;
314 spin_unlock_irqrestore(&divert_lock, flags);
330 spin_unlock_irqrestore(&divert_lock, flags);
342 while ((ds) && (idx > 0))
349 spin_unlock_irqrestore(&divert_lock, flags);
356 table_tail = ds->
prev;
361 table_head = ds->
next;
363 spin_unlock_irqrestore(&divert_lock, flags);
374 if (idx < 0)
return (
NULL);
375 while ((ds) && (idx >= 0))
377 {
return (&ds->
rule);
388 static int isdn_divert_icall(
isdn_ctrl *ic)
397 for (dv = table_head; dv; dv = dv->
next)
423 if (!accept)
continue;
440 if (!accept)
continue;
459 cs->
timer.function = deflect_timer_expire;
472 cs->
timer.expires = 0;
476 spin_unlock_irqrestore(&divert_lock, flags);
480 if (!cs->
timer.expires)
495 sprintf(cs->
info,
"%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
525 cs->
next = divert_head;
528 spin_unlock_irqrestore(&divert_lock, flags);
551 spin_unlock_irqrestore(&divert_lock, flags);
557 static int put_address(
char *
st,
u_char *p,
int len)
561 if (len < 2)
return (retval);
563 { retval = *(++
p) + 2;
564 if (retval > len)
return (0);
566 if (len < 3)
return (0);
567 if ((*(++p) != 0x0A) || (*(++
p) != 1))
return (0);
571 if (len < 2)
return (0);
572 if (*p++ != 0x12)
return (0);
573 if (*p > len)
return (0);
578 { retval = *(++
p) + 2;
579 if (retval > len)
return (0);
601 {
char *
src = ic->
parm.dss1_io.data;
602 int restlen = ic->
parm.dss1_io.datalen;
605 char st[90], *
p, *stp;
607 if (restlen < 2)
return (-100);
608 if (*src++ != 0x30)
return (-101);
609 if ((n = *src++) > 0x81)
return (-102);
612 {
if (restlen < 2)
return (-103);
613 if ((*(src + restlen - 1)) || (*(src + restlen - 2)))
return (-104);
620 if (n > restlen)
return (-105);
624 if (n > restlen)
return (-106);
627 if (restlen < 3)
return (-107);
628 if ((*src++ != 2) || (*src++ != 1) || (*src++ != 0x0B))
return (-108);
630 if (restlen < 2)
return (-109);
633 if ((n = *src++) > 0x81)
return (-110);
636 {
if (restlen < 2)
return (-111);
637 if ((*(src + restlen - 1)) || (*(src + restlen - 2)))
return (-112);
644 if (n > restlen)
return (-113);
648 if (n > restlen)
return (-114);
658 if (*src++ != 0x30)
return (-115);
661 if (n > restlen)
return (-116);
665 if (!(n1 = put_address(stp, p, n & 0xFF)))
continue;
670 if ((*p++ != 0x0A) || (*p++ != 1))
continue;
671 sprintf(stp,
" 0x%02x ", (*p++) & 0xFF);
673 if ((*p++ != 0x0A) || (*p++ != 1))
continue;
674 sprintf(stp,
"%d ", (*p++) & 0xFF);
678 {
if (*p++ != 0x30)
continue;
679 if (*p > (n - 2))
continue;
681 if (!(n1 = put_address(stp, p, n & 0xFF)))
continue;
687 if (restlen)
return (-117);
694 static int prot_stat_callback(
isdn_ctrl *ic)
705 if ((cs->
ics.
parm.dss1_io.ll_id == ic->
parm.dss1_io.ll_id) &&
706 (cs->
ics.
parm.dss1_io.hl_id == ic->
parm.dss1_io.hl_id))
710 ic->
parm.dss1_io.ll_id,
711 ic->
parm.dss1_io.timeout);
716 switch (cs->
ics.
parm.dss1_io.proc)
723 i = interrogate_success(ic, cs);
726 ic->
parm.dss1_io.ll_id, i);
772 divert_head = cs1->
next;
775 spin_unlock_irqrestore(&divert_lock, flags);
786 static int isdn_divert_stat_callback(
isdn_ctrl *ic)
827 divert_head = cs1->
next;
830 spin_unlock_irqrestore(&divert_lock, flags);
846 return (isdn_divert_icall(ic));
852 return (prot_stat_callback(ic));
860 return (isdn_divert_stat_callback(ic));