MavEtJu's Distorted View of the World - 2005-03

Asterisk Dialplan - Best practice
Interesting numbers
Kyocera KM-4035 network scanner
Cisco 7970 broken DNS resolver
OWNED!

Back to index

Asterisk Dialplan - Best practice

Posted on 2005-03-28 23:14:38, modified on 2006-01-09 16:29:23
Tags: Voice over IP, Asterisk

ASTERISK EXTENSIONS.CONF - BEST PRACTICE

This document describes a best practice approach to a structured and controllable design of the Asterisk extensions configuration file.

THE DESIGN

The design is as follows: There are input sources, there are dial groups and there are macros.

Input sources are places where calls are being made from. For example incoming SIP connections (authenticated or unauthenticated), calls from the PSTN and calls from the internal phone numbers.

Dial groups are destinations to be called. For example other SIP phones, calls to the PSTN, calls to internal phone numbers and calls to Asterisk applications like voicemail and conferences.

And as third, macros to reduce the amount of repetitive code.

INPUT SOURCES - part 1

The context of input sources are defined in sip.conf, iax2.conf and zapata.conf.

Sip.conf has three different contexts: The default context, to which everybody who isn't authenticated is assigned:

    [general]
    context=incoming-from-internet

People who are authenticated so they are trusted.

    [my-friend]
    context=incoming-from-friends

Iax2.conf has the same idea, but instead of putting it in the general section it's put in the guest section:

    [guest]
    context=incoming-from-internet

    [my-friend]
    context=incoming-from-friends

Zapata.conf has the definitions of ISDN channels to logical groups in it. For every group of ISDN channels you could have a different group and a different context:

    group = 1
    context = CUST1-PABX
    signalling = pri_net
    channel => 1-15,17-31

    group = 2
    context = CUST2-PABX
    signalling = pri_net
    channel => 32-46,48-62

    group = 3
    context = ME-TELCO
    signalling = pri_net
    channel => 63-77,79-93

DIAL GROUPS

Dial groups are the collections of different extension to dial. To start with, all PSTN numbers which are routed by your telco to your Asterisk server. Also all internal numbers for voicemail and conferences. And as last, a default entry for everything which is not local.

Our PSTN numbers for customers are +61 2 9210 0500 to +61 2 9210 0599 for customer 1 and +61 2 9210 0600 to +61 2 9210 0799 for customer 2. First we map the trunk to the customer onto the Zap interface, then we map the number ranges for the customers onto the customer trunks. In the dial plan we use the last mapping, so that any changes in hardware links only have to be modified in the general section. In the extensions definitions we use three versions of the number: The local number without the are code, the full national number with the area code and the international number with the country code.

    [general]
    TRUNK_CUST1= Zap/g1
    TRUNK_CUST2= Zap/g2

    TRUNK_612921005xx=${TRUNK_CUST1}
    TRUNK_612921006xx=${TRUNK_CUST2}
    TRUNK_612921007xx=${TRUNK_CUST2}

    [outgoing-customer1]
    exten => _612921005XX,1,Macro(call-int,${TRUNK_612921005xx},0${EXTEN:2})
    exten => _02921005XX,1,Macro(call-int,${TRUNK_612921005xx},${EXTEN})
    exten => _921005XX,1,Macro(call-int,${TRUNK_612921005xx},02${EXTEN})

    [outgoing-customer2]
    exten => _612921006XX,1,Macro(call-int,${TRUNK_612921006xx},0${EXTEN:2})
    exten => _02921006XX,1,Macro(call-int,${TRUNK_612921006xx},${EXTEN})
    exten => _921006XX,1,Macro(call-int,${TRUNK_612921006xx},02${EXTEN})
    exten => _612921007XX,1,Macro(call-int,${TRUNK_612921007xx},0${EXTEN:2})
    exten => _02921007XX,1,Macro(call-int,${TRUNK_612921007xx},${EXTEN})
    exten => _921007XX,1,Macro(call-int,${TRUNK_612921007xx},02${EXTEN})

The PSTN number ranges for VoIP users are +61 2 9210 081x for authenticated SIP users and +61 2 9210 080x towards a remote SIP server.

    [general]
    OTHERSIPSERVER= sip.foo.bar

    [outgoing-voip]
    exten => _6129210080X,1,Macro(call-sip-remote,${EXTEN:9}@${OTHERSIPSERVER}))
    exten => _029210080X,1,Macro(call-sip-remote,${EXTEN:8}@${OTHERSIPSERVER}))
    exten => _9210080X,1,Macro(call-sip-remote,${EXTEN:6}@${OTHERSIPSERVER}))

    exten => 61292100810,1,Macro(call-sip-local,foo,0${EXTEN:2})
    exten => 0292100810,1,Macro(call-sip-local,foo,${EXTEN})
    exten => 92100810,1,Macro(call-sip-local,foo,02${EXTEN})
    exten => 61292100811,1,Macro(call-sip-local,bar,0${EXTEN:2})
    exten => 0292100811,1,Macro(call-sip-local,bar,${EXTEN})
    exten => 92100811,1,Macro(call-sip-local,bar,02${EXTEN})

We don't want to specify all outgoing PSTN numbers, so we just use a catch-all for them:

    [general]
    TRUNK_TELCO= Zap/g3

    [outgoing-theworld]
    exten => _.,1,Macro(call-ext,${TRUNK_TELCO},${EXTEN})

And a number of tools for internal and external users on +61 2 9210 082x:

    [outgoing-tools]
    exten => 61292100820,1,MeetMe(1234|M)
    exten => 0292100820,1,MeetMe(1234|M)
    exten => 92100820,1,MeetMe(1234|M)

    exten => 61292100821,1,VoicemailMain
    exten => 61292100821,n,Hangup
    exten => 0292100821,1,VoicemailMain
    exten => 0292100821,n,Hangup
    exten => 92100821,1,VoicemailMain
    exten => 92100821,n,Hangup

    exten => *600,1,Playback(demo-echotest)
    exten => *600,n,Echo
    exten => *600,n,Playback(demo-echodone)
    exten => *600,n,Hangup

MACROS

Now we're in the section which actually does do the dialing. The following four macros are all we need: call-int, call-ext and call-sip-local and call-sip-remote.

The call-int macro calls on an internal trunk. Further call handling is done by these phone systems:

    [macro-call-int]
    exten => s,1,NoOp(Trunk:${ARG1})
    exten => s,n,NoOp(Number:${ARG2})
    exten => s,n,ChanIsAvail(${ARG1})
    exten => s,n,Cut(C=AVAILCHAN,,1)
    exten => s,n,Dial(${C}/${ARG2})
    exten => s,n,Hangup()

The call-ext macro calls on a trunk to the outside world. We need to check for dial responses like BUSY, CHANUNAVAIL and others.

    [macro-call-ext]
    exten => s,1,NoOp(Trunk:${ARG1})
    exten => s,n,NoOp(Number:${ARG2})
    exten => s,n,ChanIsAvail(${ARG1})
    exten => s,n,Cut(C=AVAILCHAN,,1)
    exten => s,n,Dial(${C}/${ARG1}) 
    exten => s,n,Goto(s-${DIALSTATUS},1)
    exten => s,n,Hangup()

    exten => s-BUSY,1,Busy()
    exten => s-BUSY,n,Hangup()
     
    exten => s-CHANUNAVAIL,1,PlayTones(congestion)
    exten => s-CHANUNAVAIL,n,Wait(5)
    exten => s-CHANUNAVAIL,n,StopPlayTones()
    exten => s-CHANUNAVAIL,n,Hangup
     
    exten => s-CONGESTION,1,PlayTones(congestion)
    exten => s-CONGESTION,n,Wait(5)
    exten => s-CONGESTION,n,StopPlayTones()
    exten => s-CONGESTION,n,Hangup
     
    exten => s-NOANSWER,1,Hangup

    exten => s-ANSWER,1,Hangup
    exten => s-CANCEL,1,Hangup

Call-sip-remote is just like call-int, but then for an SIP session:

    [macro-call-sip-remote]
    exten => s,1,Playback(pls-wait-connect-call)
    exten => s,n,Dial(SIP/${ARG1},45,r)
    exten => s,n,Hangup

And call-sip-local is like call-ext, but with better handling of failed dial attempts since we need to use voicemail there:

    [macro-call-sip-local]
    exten => s,1,NoOp(To user: ${ARG1})
    exten => s,n,NoOp(Voicemail: ${ARG2})
    exten => s,n,Dial(SIP/${ARG1},45,r)
    exten => s,n,NoOp(${DIALSTATUS})
    exten => s,n,Goto(s-${DIALSTATUS},1)
    exten => s,n,Hangup
     
    exten => s-BUSY,1,Playback(user)
    exten => s-BUSY,n,Playback(is-curntly-busy)
    exten => s-BUSY,n,Goto(s-VM,1)
     
    exten => s-NOANSWER,1,Playback(user)
    exten => s-NOANSWER,n,Playback(is-curntly-unavail)
    exten => s-NOANSWER,n,Goto(s-VM,1)
     
    exten => s-ANSWER,1,Playback(thank-you-for-calling)
    exten => s-ANSWER,n,Hangup
     
    exten => s-CHANUNAVAIL,1,Playback(is-curntly-unavail)
    exten => s-CHANUNAVAIL,n,Goto(s-VM,1)
     
    exten => s-CONGESTION,1,PlayTones(congestion)
    exten => s-CONGESTION,n,Wait(5)
    exten => s-CONGESTION,n,StopPlayTones()
    exten => s-CONGESTION,n,Goto(s-VM,1)

    exten => s-CANCEL,1,Hangup
     
    exten => s-VM,1,VoiceMail(${ARG2})
    exten => s-VM,n,Hangup

Pfioew! That's all the low level work.

INPUT SOURCES - part 2

Now it's time to glue the input source and the dial groups together. Every input source has its own definitions on which dial groups it is allowed to call.

The first group is the unauthenticated people on the internet which get routed to my Asterisk server. They are allowed to call my public PSTN numbers, but not to retrieve voicemail and do conferencing.

    [incoming-from-internet]
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2

The second group is the authenticated people on the internet which actually register at my Asterisk server. They are allowed as above, but also to retrieve voicemail and do conferencing.

    [incoming-from-friends]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2

All incoming called from the PSTN are allowed to call my public PSTN numbers and to retrieve voicemail and do conferencing.

    [ME-TELCO]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2

And the customers are allowed to call everything: public PSTN numbers, retrieve voicemail and do conferencing and make PSTN calls.

    [CUST1-PABX]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2
    include => outgoing-theworld

    [CUST2-PABX]
    include => outgoing-tools
    include => outgoing-voip
    include => outgoing-customer1
    include => outgoing-customer2
    include => outgoing-theworld

CONCLUSION

By properly defining what the input sources are, what the destination groups are and what the allowed destinations for an input source are, it is possible to have a structured, scalable and safe dial plan.


No comments | Share on Facebook | Share on Twitter

Interesting numbers

Posted on 2005-03-24 16:38:41, modified on 2006-01-09 16:29:23
Tags: Coding, Numbers

If you're coding, interesting numbers will show up sometimes!

This application stops running after 49 days

49 days = 49 days * 24 hours per day * 60 minutes per hour * 60 seconds per minute * 1000 ms = 4,233,600,000, or 0xFC579C00, or close to 0xFFFFFFFF. In other words, some unsigned 64 bit millisecond counter just overflowed.

This application stops running after 24 days

Same story here, except that is an signed 64 bit millisecond counter.

NumberSignificance
86400Number of seconds per day

No comments | Share on Facebook | Share on Twitter

Kyocera KM-4035 network scanner

Posted on 2005-03-24 10:41:11, modified on 2006-01-09 16:29:23
Tags: Networking, Printers, DNS

We have the Kyocera KM-4035 network printer/scanner. Beautiful machine, it can copy, print and scan. It accepts print jobs from the network, and it can send scanned pictures as PDF to your mailbox.

Well, most of the time. Sometimes it refuses to send emails. Why?

To scan, you need to press the scan button. And sometimes, it just says "SMTP server could not be found". Very annoying. And what was more annoying was that the problem was not easily reproducable, it was actually very hard to figure it out.

To make a long story short, the problem lies in the DNS request of the scanner:

12:54:30.879447 10.200.5.11.1024 > 10.200.5.1.53:  19311 A? smtp.banco.net.au. (47)
0x0000   4500 004b 0a59 0000 ff11 91ad 0ac8 050b    E..K.Y..........
0x0010   0ac8 0501 0400 0035 0037 28ad 4b6f 0000    .......5.7(.Ko..
0x0020   0001 0000 0000 0000 0473 6d74 7005 6261    .........smtp.ba
0x0030   6e63 6f03 6e65 7402 6175 0000 0100 0100    nco.net.au......
0x0040   0000 0000 0000 0000 0000 00                ...........

At offset 0x001c the DNS header starts: 0x4b6f (=19311) for the identification, 0x0000 for the flags, 0x0001/0x0000/0x0000/0x000 for the number of requests/answers/authority/additional resource records and the question: who knows the A record for smtp.banco.net.au.

The DNS server for that LAN, at 10.200.5.1, is a caching-only forwarding name server. It does know where to ask for others, but itself isn't authoritative for any domains. It will give answer to questions of which the answers are cached, or to questions which have the RD (Recursion Desired) flag set. The RD flag is normally set for DNS request from simple clients (PCs, network equipment etc). If the RD flag is not set, it indicates that the device (most likely a DNS server) asking the question is smart enough to know how to handle answers with referrals.

So the scanner sends a question without the RD flag.

  • If the name smtp.banco.net.au is known in the cache of the nameserver, it will return it (this is the "sometimes the scanner works"):
    12:54:30.879929 10.200.5.1.53 > 10.200.5.11.1024:  19311 3/2/2 CNAME smtp.barnet.com.au., CNAME mail2.barnet.com.au., A 202.83.176.13 (169)
  • If the name smtp.banco.net.au is not known in the cache of the nameserver, it will tell return a list of servers where it can get the information:
    12:51:51.747207 10.200.5.1.53 > 10.200.5.11.1024:  27028 0/13/13 (454)

How can it be resolved?

  • Long term solution: The scanner should set the RD flag in the question. It has shown it is not capable of finding out itself what to do with the referer answer, it should let this be done by the DNS server itself. Tell Kyocera about this problem and let them release new firmware.
  • Short term solution: We point the scanner to our main DNS servers, which are authoritative for these domains and thus always can answer the question or where smtp.banco.net.au lives.

The model of the printer/scanner is: KM-4035 Network Scanner
The scanner firmware is: KM-4035 Ver2.62.8
The network firmware is: NS-30 Ver1.3.00

Kyocera has been informed.


No comments | Share on Facebook | Share on Twitter

Cisco 7970 broken DNS resolver

Posted on 2005-03-12 22:53:41, modified on 2006-01-09 16:29:23
Tags: Voice over IP, Cisco, DNS

The Cisco 7970 phones have a nifty feature: IP Phone Services. With it, you can access services on the internet (for example the stock value of CSCO). I have been asked to make some nifty features, but up to now it's no luck for me! Read on...

An IP Phone Service is defined as an URL, which returns an XML file with the commands in it. All very simple stuff.

For example, http://1.2.3.4/test.xml would return an XML file. This works.

But, we're living in the 21st century and we use hostnames these days. So, I changed it to http://xml.example.org/test.xml. No fish. Not even an TCP session towards the webserver. Why?

15:43:25.727288 10.192.15.229.1177 > 10.192.0.2.53:  48+ Type1907 (Class 29802)?. (33) [tos 0x60]
0x0000   4560 003d 1186 0000 3e11 4564 0ac0 0fe5      E`.=....>.Ed....
0x0010   0ac0 0002 0499 0035 0029 0000 0030 0100      .......5.)...0..
0x0020   0001 0000 0000 0000 0007 7374 6a61 6d65      ..........stjame
0x0030   7303 6e65 7402 6175 0000 0100 01             s.net.au.....

This is why. Don't ask me why the phone asks for A record of stjames.net.au, but it is asking it wrong: At offset 0x0028, the value 00 is there by mistake, it shouldn't have been there in the first place.

My name server happily refuses the query, and the Cisco 7970 returns "Host not found". Let's hope that Cisco can do something about it :-/

Note: Please note that this problem has been fixed in version 6.0.3.


No comments | Share on Facebook | Share on Twitter

OWNED!

Posted on 2005-03-11 21:49:12, modified on 2006-01-09 16:29:23
Tags: Computers, Linux

Owned...

Sooner or later it was bound to happen, and for somebody who has a number of machines under his control it is a nightmare scenario.

Victim: a small box used for testing the OpenGroupware software suit. The box is running FC2 and in my childish innocense for the time being, the root password was.... root. Need to say more?

The next day while trying to figure out why OpenGroupware didn't like what I was trying to do (see http://bugzilla.opengroupware.org/bugzilla/show_bug.cgi?id=1270) and saw:

[ogo@boxter opengroupware.org]$ ps xuaw | grep 32755
Segmentation fault

Err... impressive. Why?

[root@boxter root]# dmesg
Segmentation fault

Euhm... this is tricky. Why?

[root@boxter root]# reboot

And the machine didn't come back. The next day I could come to the console and saw it was hanging in "INIT 2.65". Not really skilled in Linux and how to debug it *before* the kernel was fully loaded, I booted the box with a Knoppix CD in the hope I could just restore /boot from a different machine. The box didn't come back, but before I overwrote (instead of saving a copy of it.... don't ask) I realized that the md5 checksum of the initrd-2.6.5-1.358.img and vmlinuz-2.6.5-1.358 where different than the one of the different machine.

Another reboot, still no fish. Knoppix again, and wondering what went wrong. Hardware issue? If so, why has this box worked perfectly for months and now suddenly decided to throw up?

The Knoppix CD contains the chkrootkit command, and for some reason I ran it, just to be sure:

root@0[~]# chkrootkit -r /mnt/hda2
ROOTDIR is `/mnt/hda2/'
Checking `basename'... not infected
[...]
Checking `date'... /bin/sh
INFECTED
[...]

Oh. Euhm. Aha. That explains some things.

root@0[~]# ls -al /mnt/hda2/bin/date
-rwxr-xr-x  1 root root 49520 Mar  3 17:03 /mnt/hda2/bin/date

Yups. That's yesterday, while the box was installed the week before and the binaries on a different FC2 machine which were:

[~] root@tardis>ls -al `which date`
-rwxr-xr-x  1 root root 45424 May  5  2004 /bin/date

Let's check some basic facts first. Who has been logging in?

root@0[~]# last -f /mnt/hda2/var/log/wtmp -n 30
root     pts/32       edwin-3.int.barn Thu Mar  3 17:00 - down   (00:02)
root     pts/31       edwin-3.int.barn Thu Mar  3 16:42 - down   (00:20)
root     pts/30       edwin-3.int.barn Wed Mar  2 20:11 - 21:31  (01:20)
root     pts/29       203.85.90.88     Wed Mar  2 16:35 - 16:52  (00:16)
root     pts/28       edwin-3.int.barn Tue Mar  1 17:38 - 22:33  (04:54)
root     pts/27       147.46.244.31    Tue Mar  1 05:37 - 05:45  (00:08) 
root     pts/26       202.39.75.131    Tue Mar  1 05:17 - 05:17  (00:00)
root     pts/25       edwin-3.int.barn Tue Mar  1 00:30 - 22:33  (22:03)
root     pts/24       edwin-3.int.barn Mon Feb 28 18:24 - 00:03  (05:38)
root     pts/23       edwin-3.int.barn Mon Feb 28 18:16 - 22:33 (1+04:16)
root     pts/22       edwin-3.int.barn Mon Feb 28 17:40 - 22:33 (1+04:53)

Oh... Three people have been able to figure out that my root password was root.

Which files were changed?

According to an "ls -laR", the following files were changed:

-rw-r--r--   1 root root     0 Mar  3 17:02 /mnt/hda2/halt
/mnt/hda2/bin:
total 5260
drwxr-xr-x  21 root     root       4096 Mar  3 17:02 ..
-rwxr-xr-x   1 root     root      22468 Mar  3 12:02 cat
-rwxr-xr-x   1 root     root      40124 Mar  3 17:03 chown
-rwxr-xr-x   1 root     root      49520 Mar  3 17:03 date
-rwxr-xr-x   1 root     root      10268 Mar  3 17:03 dmesg
-rwxr-xr-x   1 root     root      58528 Mar  3 17:03 dumpkeys   
-rwxr-xr-x   1 root     root      17792 Mar  3 17:03 false
-rwxr-xr-x   1 root     root     260572 Mar  2 16:51 gawk
-rwxr-xr-x   1 root     root      81392 Mar  3 17:03 grep
-rwxr-xr-x   3 root     root      61360 Mar  3 17:03 gunzip
-rwxr-xr-x   3 root     root      61360 Mar  3 17:03 gzip
-rwxr-xr-x   1 root     root      14904 Mar  3 17:03 hostname
-rwxr-xr-x   1 root     root      32804 Mar  3 17:03 ipcalc
-rwxr-xr-x   1 root     root      27404 Mar  3 17:03 login
-rwxr-xr-x   1 root     root      84784 Mar  3 17:03 ls
-rwxr-xr-x   1 root     root      27932 Mar  3 17:03 mkdir
-rwsr-xr-x   1 root     root      33196 Mar  3 17:03 ping6
-rwxr-xr-x   1 root     root      19568 Mar  3 17:03 pwd
-rwxr-xr-x   1 root     root      19564 Mar  3 17:03 rmdir
-rwxr-xr-x   1 root     root      37556 Mar  3 17:03 setfont
-rwxr-xr-x   1 root     root      22712 Mar  3 17:03 setserial
-rwxr-xr-x   1 root     root      52656 Mar  3 17:03 sort
-rwxr-xr-x   1 root     root      42580 Mar  3 17:03 stty
-rwxr-xr-x   1 root     root      18368 Mar  3 17:03 sync
-rwxr-xr-x   1 root     root     157660 Mar  3 17:03 tar
-rwxr-xr-x   1 root     root      13820 Mar  3 17:03 tracepath
-rwsr-xr-x   1 root     root      57420 Mar  3 17:03 umount
-rwxr-xr-x   3 root     root      61360 Mar  3 17:03 zcat

(At this moment I lost interest, the machine got reinstalled and nothing is left of it)


No comments | Share on Facebook | Share on Twitter