mirror of https://github.com/asterisk/asterisk
Add DUNDi.... (http://www.dundi.com)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4033 65c4cc65-6c06-0410-ace0-fbb531ad65f31.2-netsec
parent
8405193cff
commit
06dfca5d24
@ -0,0 +1,172 @@
|
||||
;
|
||||
; DUNDi configuration file
|
||||
;
|
||||
;
|
||||
[general]
|
||||
;
|
||||
; The "general" section contains general parameters relating
|
||||
; to the operation of the dundi client and server.
|
||||
;
|
||||
; The first part should be your complete contact information
|
||||
; should someone else in your peer group need to contact you.
|
||||
;
|
||||
;department=Your Department
|
||||
;organization=Your Company, Inc.
|
||||
;locality=Your City
|
||||
;stateprov=ST
|
||||
;country=US
|
||||
;email=your@email.com
|
||||
;phone=+12565551212
|
||||
;
|
||||
;
|
||||
; Specify bind address and port number. Default is
|
||||
; 4520
|
||||
;
|
||||
;bindaddr=0.0.0.0
|
||||
;port=4520
|
||||
;
|
||||
; Our entity identifier (Should generally be the MAC address of the
|
||||
; machine it's running on. Defaults to the first eth address, but you
|
||||
; can override it here, as long as you set it to the MAC of *something*
|
||||
; you own!)
|
||||
;
|
||||
;entityid=00:07:E9:3B:76:60
|
||||
;
|
||||
; Define the max depth in which to search the DUNDi system (also max # of
|
||||
; seconds to wait for a reply)
|
||||
;
|
||||
ttl=32
|
||||
;
|
||||
; If we don't get ACK to our DPREQUEST within 2000ms, and autokill is set
|
||||
; to yes, then we cancel the whole thing (that's enough time for one
|
||||
; retransmission only). This is used to keep things from stalling for a long
|
||||
; time for a host that is not available, but would be ill advised for bad
|
||||
; connections. In addition to 'yes' or 'no' you can also specify a number
|
||||
; of milliseconds. See 'qualify' for individual peers to turn on for just
|
||||
; a specific peer.
|
||||
;
|
||||
autokill=yes
|
||||
;
|
||||
; pbx_dundi creates a rotating key called "secret", under the family
|
||||
; 'secretpath'. The default family is dundi (resulting in
|
||||
; the key being held at dundi/secret).
|
||||
;
|
||||
;secretpath=dundi
|
||||
|
||||
[mappings]
|
||||
;
|
||||
; The "mappings" section maps DUNDi contexts
|
||||
; to contexts on the local asterisk system. Remember
|
||||
; that numbers that are made available under the e164
|
||||
; DUNDi context are regulated by the DUNDi General Peering
|
||||
; Agreement (GPA) if you are a member of the DUNDi E.164
|
||||
; Peering System.
|
||||
;
|
||||
; dundi_context => local_context,weight,tech,dest[,options]]
|
||||
;
|
||||
; dundi_context is the name of the context being requested
|
||||
; within the DUNDi request
|
||||
;
|
||||
; local_context is the name of the context on the local system
|
||||
; in which numbers can be looked up for which responses shall be given.
|
||||
;
|
||||
; tech is the technology to use (IAX, SIP, H323)
|
||||
;
|
||||
; dest is the destination to supply for reaching that number. Note
|
||||
; that the variable ${NUMBER} shall be replaced by the number being
|
||||
; requested.
|
||||
;
|
||||
; Further options may include:
|
||||
;
|
||||
; nounsolicited: No unsolicited calls of any type permitted via this
|
||||
; route
|
||||
; nocomunsolicit: No commercial unsolicited calls permitted via
|
||||
; this route
|
||||
; residential: This number is known to be a residence
|
||||
; commercial: This number is known to be a business
|
||||
; mobile: This number is known to be a mobile phone
|
||||
; nocomunsolicit: No commercial unsolicited calls permitted via
|
||||
; this route
|
||||
; nopartial: Do not search for partial matches
|
||||
;
|
||||
; There *must* exist an entry in mappings for DUNDi to respond
|
||||
; to any request, although it may be empty.
|
||||
;
|
||||
;e164 => dundi-e164-canonical,0,IAX2,dundi:${SECRET}@${IPADDR}/${NUMBER},nounsolicited,nocomunsolicit,nopartial
|
||||
;e164 => dundi-e164-customers,100,IAX2,dundi:${SECRET}@${IPADDR}/${NUMBER},nounsolicited,nocomunsolicit,nopartial
|
||||
;e164 => dundi-e164-via-pstn,400,IAX2,dundi:${SECRET}@${IPADDR}/${NUMBER},nounsolicited,nocomunsolicit,nopartial
|
||||
|
||||
;digexten => default,0,IAX2,guest@lappy/${NUMBER}
|
||||
;asdf =>
|
||||
|
||||
|
||||
;
|
||||
;
|
||||
; The remaining sections represent the peers
|
||||
; that we fundamentally trust. The section name
|
||||
; represents the name and optionally at a specific
|
||||
; DUNDi context if you want the trust to be established
|
||||
; for only a specific DUNDi context.
|
||||
;
|
||||
; inkey - What key they will be authenticating to us with
|
||||
;
|
||||
; outkey - What key we use to authenticate to them
|
||||
;
|
||||
; host - What their host is
|
||||
;
|
||||
; order - What search order to use. May be 'primary', 'secondary',
|
||||
; 'tertiary' or 'quartiary'. In large systems, it is beneficial
|
||||
; to only query one up-stream host in order to maximize caching
|
||||
; value. Adding one with primary and one with secondary gives you
|
||||
; redundancy without sacraficing performance.
|
||||
;
|
||||
; include - Includes this peer when searching a particular context
|
||||
; for lookup (set "all" to perform all lookups with that
|
||||
; host.
|
||||
;
|
||||
; noinclude - Disincludes this peer when searching a particular context
|
||||
; for lookup (set "all" to perform no lookups with that
|
||||
; host.
|
||||
;
|
||||
; permit - Permits this peer to search a given DUNDi context on
|
||||
; the local system. Set "all" to permit this host to
|
||||
; lookup all contexts.
|
||||
;
|
||||
; deny - Denies this peer to search a given DUNDi context on
|
||||
; the local system. Set "all" to deny this host to
|
||||
; lookup all contexts.
|
||||
;
|
||||
; model - inbound, outbound, or symmetric for whether we receive
|
||||
; requests only, transmit requests only, or do both.
|
||||
;
|
||||
; The '*' peer is special and matches an unspecified entity
|
||||
;
|
||||
|
||||
;
|
||||
; Sample Primary e164 DUNDi peer
|
||||
;
|
||||
[00:50:8B:F3:75:BB]
|
||||
model = symmetric
|
||||
host = 64.215.96.114
|
||||
inkey = digium
|
||||
outkey = misery
|
||||
include = e164
|
||||
permit = e164
|
||||
qualify = yes
|
||||
|
||||
;
|
||||
; Sample Secondary e164 DUNDi peer
|
||||
;
|
||||
;[00:A0:C9:96:92:84]
|
||||
;model = symmetric
|
||||
;host = misery.digium.com
|
||||
;inkey = misery
|
||||
;outkey = ourkey
|
||||
;include = e164
|
||||
;permit = e164
|
||||
;qualify = yes
|
||||
;order = secondary
|
||||
|
||||
|
||||
;[*]
|
||||
;
|
@ -0,0 +1,499 @@
|
||||
DIGIUM GENERAL PEERING AGREEMENT (TM)
|
||||
Version 1.0.0, September 2004
|
||||
Copyright (C) 2004 Digium, Inc.
|
||||
150 West Park Loop Suite 100, Huntsville, AL 35806 USA
|
||||
|
||||
Everyone is permitted to copy and distribute complete verbatim copies
|
||||
of this General Peering Agreement provided it is not modified in any
|
||||
manner.
|
||||
|
||||
------------------------------------------------------
|
||||
|
||||
DIGIUM GENERAL PEERING AGREEMENT
|
||||
|
||||
PREAMBLE
|
||||
|
||||
For most of the history of telecommunications, the power of being able
|
||||
to locate and communicate with another person in a system, be it across
|
||||
a hall or around the world, has always centered around a centralized
|
||||
authority -- from a local PBX administrator to regional and national
|
||||
RBOCs, generally requiring fees, taxes or regulation. By contrast,
|
||||
DUNDi is a technology developed to provide users the freedom to
|
||||
communicate with each other without the necessity of any centralized
|
||||
authority. This General Peering Agreement ("GPA") is used by individual
|
||||
parties (each, a "Participant") to allow them to build the E164 trust
|
||||
group for the DUNDi protocol.
|
||||
|
||||
To protect the usefulness of the E164 trust group for those who use
|
||||
it, while keeping the system wholly decentralized, it is necessary to
|
||||
replace many of the responsibilities generally afforded to a company or
|
||||
government agency, with a set of responsibilities implemented by the
|
||||
parties who use the system, themselves. It is the goal of this document
|
||||
to provide all the protections necessary to keep the DUNDi E164 trust
|
||||
group useful and reliable.
|
||||
|
||||
The Participants wish to protect competition, promote innovation and
|
||||
value added services and make this service valuable both commercially
|
||||
and non-commercially. To that end, this GPA provides special terms and
|
||||
conditions outlining some permissible and non-permissible revenue
|
||||
sources.
|
||||
|
||||
This GPA is independent of any software license or other license
|
||||
agreement for a program or technology employing the DUNDi protocol. For
|
||||
example, the implementation of DUNDi used by Asterisk is covered under a
|
||||
separate license. Each Participant is responsible for compliance with
|
||||
any licenses or other agreements governing use of such program or
|
||||
technology that they use to peer.
|
||||
|
||||
You do not have to execute this GPA to use a program or technology
|
||||
employing the DUNDi protocol, however if you do not execute this GPA,
|
||||
you will not be able to peer using DUNDi and the E164 context with
|
||||
anyone who is a member of the trust group by virtue of their having
|
||||
executed this GPA with another member.
|
||||
|
||||
The parties to this GPA agree as follows:
|
||||
|
||||
0. DEFINITIONS. As used herein, certain terms shall be defined as
|
||||
follows:
|
||||
|
||||
(a) The term "DUNDi" means the DUNDi protocol as published by
|
||||
Digium, Inc. or its successor in interest with respect to the
|
||||
DUNDi protocol specification.
|
||||
|
||||
(b) The terms "E.164" and "E164" mean ITU-T specification E.164 as
|
||||
published by the International Telecommunications Union (ITU) in
|
||||
May, 1997.
|
||||
|
||||
(c) The term "Service" refers to any communication facility (e.g.,
|
||||
telephone, fax, modem, etc.), identified by an E.164-compatible
|
||||
number, and assigned by the appropriate authority in that
|
||||
jurisdiction.
|
||||
|
||||
(d) The term "Egress Gateway" refers an Internet facility that
|
||||
provides a communications path to a Service or Services that may
|
||||
not be directly addressable via the Internet.
|
||||
|
||||
(e) The term "Route" refers to an Internet address, policies, and
|
||||
other characteristics defined by the DUNDi protocol and
|
||||
associated with the Service, or the Egress Gateway which
|
||||
provides access to the specified Service.
|
||||
|
||||
(f) The term "Propagate" means to accept or transmit Service and/or
|
||||
Egress Gateway Routes only using the DUNDi protocol and the
|
||||
DUNDi context "e164" without regard to case, and does not apply
|
||||
to the exchange of information using any other protocol or
|
||||
context.
|
||||
|
||||
(g) The term "Peering System" means the network of systems that
|
||||
Propagate Routes.
|
||||
|
||||
(h) The term "Subscriber" means the owner of, or someone who
|
||||
contracts to receive, the services identified by an E.164
|
||||
number.
|
||||
|
||||
(i) The term "Authorizing Individual" means the Subscriber to a
|
||||
number who has authorized a Participant to provide Routes
|
||||
regarding their services via this Peering System.
|
||||
|
||||
(j) The term "Route Authority" refers to a Participant that provides
|
||||
an original source of said Route within the Peering System.
|
||||
Routes are propagated from the Route Authorities through the
|
||||
Peering System and may be cached at intermediate points. There
|
||||
may be multiple Route Authorities for any Service.
|
||||
|
||||
(k) The term "Participant" (introduced above) refers to any member
|
||||
of the Peering System.
|
||||
|
||||
(l) The term "Service Provider" refers to the carrier (e.g.,
|
||||
exchange carrier, Internet Telephony Service Provider, or other
|
||||
reseller) that provides communication facilities for a
|
||||
particular Service to a Subscriber, Customer or other End User.
|
||||
|
||||
(m) The term "Weight" refers to a numeric quality assigned to a
|
||||
Route as per the DUNDi protocol specification. The current
|
||||
Weight definitions are shown in Exhibit A.
|
||||
|
||||
1. PEERING. The undersigned Participants agree to Propagate Routes
|
||||
with each other and any other member of the Peering System and further
|
||||
agree not to Propagate DUNDi Routes with a third party unless they have
|
||||
first have executed this GPA (in its unmodified form) with such third
|
||||
party. The Participants further agree only to Propagate Routes with
|
||||
Participants whom they reasonably believe to be honoring the terms of
|
||||
the GPA. Participants may not insert, remove, amend, or otherwise
|
||||
modify any of the terms of the GPA.
|
||||
|
||||
2. ACCEPTABLE USE POLICY. The DUNDi protocol contains information
|
||||
that reflect a Subscriber's or Egress Gateway's decisions to receive
|
||||
calls. In addition to the terms and conditions set forth in this GPA,
|
||||
the Participants agree to honor the intent of restrictions encoded in
|
||||
the DUNDi protocol. To that end, Participants agree to the following:
|
||||
|
||||
(a) A Participant may not utilize or permit the utilization of
|
||||
Routes for which the Subscriber or Egress Gateway provider has
|
||||
indicated that they do not wish to receive "Unsolicited Calls"
|
||||
for the purpose of making an unsolicited phone call on behalf of
|
||||
any party or organization.
|
||||
|
||||
(b) A Participant may not utilize or permit the utilization of
|
||||
Routes which have indicated that they do not wish to receive
|
||||
"Unsolicited Commercial Calls" for the purpose of making an
|
||||
unsolicited phone call on behalf of a commercial organization.
|
||||
|
||||
(c) A Participant may never utilize or permit the utilization of any
|
||||
DUNDi route for the purpose of making harassing phone calls.
|
||||
|
||||
(d) A Party may not utilize or permit the utilization of DUNDi
|
||||
provided Routes for any systematic or random calling of numbers
|
||||
(e.g., for the purpose of locating facsimile, modem services, or
|
||||
systematic telemarketing).
|
||||
|
||||
(e) Initial control signaling for all communication sessions that
|
||||
utilize Routes obtained from the Peering System must be sent
|
||||
from a member of the Peering System to the Service or Egress
|
||||
Gateway identified in the selected Route. For example, 'SIP
|
||||
INVITES' and IAX2 "NEW" commands must be sent from the
|
||||
requesting DUNDi node to the terminating Service.
|
||||
|
||||
(f) A Participant may not disclose any specific Route, Service or
|
||||
Participant contact information obtained from the Peering System
|
||||
to any party outside of the Peering System except as a
|
||||
by-product of facilitating communication in accordance with
|
||||
section 2e (e.g., phone books or other databases may not be
|
||||
published, but the Internet addresses of the Egress Gateway or
|
||||
Service does not need to be obfuscated.)
|
||||
|
||||
(g) The DUNDi Protocol requires that each Participant include valid
|
||||
contact information about itself (including information about
|
||||
nodes connected to each Participant). Participants may use or
|
||||
disclose the contact information only to ensure enforcement of
|
||||
legal furtherance of this Agreement.
|
||||
|
||||
3. ROUTES. The Participants shall only propagate valid Routes, as
|
||||
defined herein, through the Peering System, regardless of the original
|
||||
source. The Participants may only provide Routes as set forth below,
|
||||
and then only if such Participant has no good faith reason to believe
|
||||
such Route to be invalid or unauthorized.
|
||||
|
||||
(a) A Participant may provide Routes if each Route has as its
|
||||
original source another member of the Peering System who has
|
||||
duly executed the GPA and such Routes are provided in accordance
|
||||
with this Agreement; provided that the Routes are not modified
|
||||
(e.g., with regards to existence, destination, technology or
|
||||
Weight); or
|
||||
|
||||
(b) A Participant may provide Routes for Services with any Weight
|
||||
for which it is the Subscriber; or
|
||||
|
||||
(c) A Participant may provide Routes for those Services whose
|
||||
Subscriber has authorized the Participant to do so, provided
|
||||
that the Participant is able to confirm that the Authorizing
|
||||
Individual is the Subscriber through:
|
||||
|
||||
i. a written statement of ownership from the Authorizing
|
||||
Individual, which the Participant believes in good faith
|
||||
to be accurate (e.g., a phone bill with the name of the
|
||||
Authorizing Individual and the number in question); or
|
||||
|
||||
ii. the Participant's own direct personal knowledge that the
|
||||
Authorizing Individual is the Subscriber.
|
||||
|
||||
(d) A Participant may provide Routes for Services, with Weight in
|
||||
accordance with the Current DUNDi Specification, if it can in
|
||||
good faith provide an Egress Gateway to that Service on the
|
||||
traditional telephone network without cost to the calling party.
|
||||
|
||||
4. REVOCATION. A Participant must provide a free, easily accessible
|
||||
mechanism by which a Subscriber may revoke permission to act as a Route
|
||||
Authority for his Service. A Participant must stop acting as a Route
|
||||
Authority for that Service within 7 days after:
|
||||
|
||||
(a) receipt of a revocation request;
|
||||
|
||||
(b) receiving other notice that the Service is no longer valid; or
|
||||
|
||||
(c) determination that the Subscriber's information is no longer
|
||||
accurate (including that the Subscriber is no longer the service
|
||||
owner or the service owner's authorized delegate).
|
||||
|
||||
5. SERVICE FEES. A Participant may charge a fee to act as a Route
|
||||
Authority for a Service, with any Weight, provided that no Participant
|
||||
may charge a fee to propagate the Route received through the Peering
|
||||
System.
|
||||
|
||||
6. TOLL SERVICES. No Participant may provide Routes for any Services
|
||||
that require payment from the calling party or their customer for
|
||||
communication with the Service. Nothing in this section shall prohibit
|
||||
a Participant from providing routes for Services where the calling party
|
||||
may later enter into a financial transaction with the called party
|
||||
(e.g., a Participant may provide Routes for calling cards services).
|
||||
|
||||
7. QUALITY. A Participant may not intentionally impair communication
|
||||
using a Route provided to the Peering System (e.g. by adding delay,
|
||||
advertisements, reduced quality). If for any reason a Participant is
|
||||
unable to deliver a call via a Route provided to the Peering System,
|
||||
that Participant shall return out-of-band Network Congestion
|
||||
notification (e.g. "503 Service Unavailable" with SIP protocol or
|
||||
"CONGESTION" with IAX protocol).
|
||||
|
||||
8. PROTOCOL COMPLIANCE. Participants agree to Propagate Routes in
|
||||
strict compliance with current DUNDi protocol specifications.
|
||||
|
||||
9. ADMINISTRATIVE FEES. A Participant may charge (but is not required
|
||||
to charge) another Participant a reasonable fee to cover administrative
|
||||
expenses incurred in the execution of this Agreement. A Participant may
|
||||
not charge any fee to continue the relationship or to provide Routes to
|
||||
another Participant in the Peering System.
|
||||
|
||||
10. CALLER IDENTIFICATION. A Participant will make a good faith effort
|
||||
to ensure the accuracy and appropriate nature of any caller
|
||||
identification that it transmits via any Route obtained from the Peering
|
||||
System. Caller identification shall at least be provided as a valid
|
||||
E.164 number.
|
||||
|
||||
11. COMPLIANCE WITH LAWS. The Participants are solely responsible for
|
||||
determining to what extent, if any, the obligations set forth in this
|
||||
GPA conflict with any laws or regulations their region. A Participant
|
||||
may not provide any service or otherwise use DUNDi under this GPA if
|
||||
doing so is prohibited by law or regulation, or if any law or regulation
|
||||
imposes requirements on the Participant that are inconsistent with the
|
||||
terms of this GPA or the Acceptable Use Policy.
|
||||
|
||||
12. WARRANTY. EACH PARTICIPANT WARRANTS TO THE OTHER PARTICIPANTS THAT
|
||||
IT MADE, AND WILL CONTINUE TO MAKE, A GOOD FAITH EFFORT TO AUTHENTICATE
|
||||
OTHERS IN THE PEERING SYSTEM AND TO PROVIDE ACCURATE INFORMATION IN
|
||||
ACCORDANCE WITH THE TERMS OF THIS GPA. THIS WARRANTY IS MADE BETWEEN
|
||||
THE PARTICIPANTS, AND THE PARTICIPANTS MAY NOT EXTEND THIS WARRANTY TO
|
||||
ANY NON-PARTICIPANT INCLUDING END-USERS.
|
||||
|
||||
13. DISCLAIMER OF WARRANTIES. THE PARTICIPANTS UNDERSTAND AND AGREE
|
||||
THAT ANY SERVICE PROVIDED AS A RESULT OF THIS GPA IS "AS IS." EXCEPT FOR
|
||||
THOSE WARRANTIES OTHERWISE EXPRESSLY SET FORTH HEREIN, THE PARTICIPANTS
|
||||
DISCLAIM ANY REPRESENTATIONS OR WARRANTIES OF ANY KIND OR NATURE,
|
||||
EXPRESS OR IMPLIED, AS TO THE CONDITION, VALUE OR QUALITIES OF THE
|
||||
SERVICES PROVIDED HEREUNDER, AND SPECIFICALLY DISCLAIM ANY
|
||||
REPRESENTATION OR WARRANTY OF MERCHANTABILITY, SUITABILITY OR FITNESS
|
||||
FOR A PARTICULAR PURPOSE OR AS TO THE CONDITION OR WORKMANSHIP THEREOF,
|
||||
OR THE ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT,
|
||||
INCLUDING ANY WARRANTIES ARISING FROM A COURSE OF DEALING, USAGE OR
|
||||
TRADE PRACTICE. EXCEPT AS EXPRESSLY PROVIDED HEREIN, THE PARTICIPANTS
|
||||
EXPRESSLY DISCLAIM ANY REPRESENTATIONS OR WARRANTIES THAT THE PEERING
|
||||
SERVICE WILL BE CONTINUOUS, UNINTERRUPTED OR ERROR-FREE, THAT ANY DATA
|
||||
SHARED OR OTHERWISE MADE AVAILABLE WILL BE ACCURATE OR COMPLETE OR
|
||||
OTHERWISE COMPLETELY SECURE FROM UNAUTHORIZED ACCESS.
|
||||
|
||||
14. LIMITATION OF LIABILITIES. NO PARTICIPANT SHALL BE LIABLE TO ANY
|
||||
OTHER PARTICIPANT FOR INCIDENTAL, INDIRECT, CONSEQUENTIAL, SPECIAL,
|
||||
PUNITIVE OR EXEMPLARY DAMAGES OF ANY KIND (INCLUDING LOST REVENUES OR
|
||||
PROFITS, LOSS OF BUSINESS OR LOSS OF DATA) IN ANY WAY RELATED TO THIS
|
||||
GPA, WHETHER IN CONTRACT OR IN TORT, REGARDLESS OF WHETHER SUCH
|
||||
PARTICIPANT WAS ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
15. END-USER AGREEMENTS. The Participants may independently enter
|
||||
into agreements with end-users to provide certain services (e.g., fees
|
||||
to a Subscriber to originate Routes for that Service). To the extent
|
||||
that provision of these services employs the Peering System, the Parties
|
||||
will include in their agreements with their end-users terms and
|
||||
conditions consistent with the terms of this GPA with respect to the
|
||||
exclusion of warranties, limitation of liability and Acceptable Use
|
||||
Policy. In no event may a Participant extend the warranty described in
|
||||
Section 12 in this GPA to any end-users.
|
||||
|
||||
16. INDEMNIFICATION. Each Participant agrees to defend, indemnify and
|
||||
hold harmless the other Participant or third-party beneficiaries to this
|
||||
GPA (including their affiliates, successors, assigns, agents and
|
||||
representatives and their respective officers, directors and employees)
|
||||
from and against any and all actions, suits, proceedings,
|
||||
investigations, demands, claims, judgments, liabilities, obligations,
|
||||
liens, losses, damages, expenses (including, without limitation,
|
||||
attorneys' fees) and any other fees arising out of or relating to (i)
|
||||
personal injury or property damage caused by that Participant, its
|
||||
employees, agents, servants, or other representatives; (ii) any act or
|
||||
omission by the Participant, its employees, agents, servants or other
|
||||
representatives, including, but not limited to, unauthorized
|
||||
representations or warranties made by the Participant; or (iii) any
|
||||
breach by the Participant of any of the terms or conditions of this GPA.
|
||||
|
||||
17. THIRD PARTY BENEFICIARIES. This GPA is intended to benefit those
|
||||
Participants who have executed the GPA and who are in the Peering
|
||||
System. It is the intent of the Parties to this GPA to give to those
|
||||
Participants who are in the Peering System standing to bring any
|
||||
necessary legal action to enforce the terms of this GPA.
|
||||
|
||||
18. TERMINATION. Any Participant may terminate this GPA at any time,
|
||||
with or without cause. A Participant that terminates must immediately
|
||||
cease to Propagate.
|
||||
|
||||
19. CHOICE OF LAW. This GPA and the rights and duties of the Parties
|
||||
hereto shall be construed and determined in accordance with the internal
|
||||
laws of the State of New York, United States of America, without regard
|
||||
to its conflict of laws principles and without application of the United
|
||||
Nations Convention on Contracts for the International Sale of Goods.
|
||||
|
||||
20. DISPUTE RESOLUTION. Unless otherwise agreed in writing, the
|
||||
exclusive procedure for handling disputes shall be as set forth herein.
|
||||
Notwithstanding such procedures, any Participant may, at any time, seek
|
||||
injunctive relief in addition to the process described below.
|
||||
|
||||
(a) Prior to mediation or arbitration the disputing Participants
|
||||
shall seek informal resolution of disputes. The process shall be
|
||||
initiated with written notice of one Participant to the other
|
||||
describing the dispute with reasonable particularity followed
|
||||
with a written response within ten (10) days of receipt of
|
||||
notice. Each Participant shall promptly designate an executive
|
||||
with requisite authority to resolve the dispute. The informal
|
||||
procedure shall commence within ten (10) days of the date of
|
||||
response. All reasonable requests for non-privileged information
|
||||
reasonably related to the dispute shall be honored. If the
|
||||
dispute is not resolved within thirty (30) days of commencement
|
||||
of the procedure either Participant may proceed to mediation or
|
||||
arbitration pursuant to the rules set forth in (b) or (c) below.
|
||||
|
||||
(b) If the dispute has not been resolved pursuant to (a) above or,
|
||||
if the disputing Participants fail to commence informal dispute
|
||||
resolution pursuant to (a) above, either Participant may, in
|
||||
writing and within twenty (20) days of the response date noted
|
||||
in (a) above, ask the other Participant to participate in a one
|
||||
(1) day mediation with an impartial mediator, and the other
|
||||
Participant shall do so. Each Participant will bear its own
|
||||
expenses and an equal share of the fees of the mediator. If the
|
||||
mediation is not successful the Participants may proceed with
|
||||
arbitration pursuant to (c) below.
|
||||
|
||||
(c) If the dispute has not been resolved pursuant to (a) or (b)
|
||||
above, the dispute shall be promptly referred, no later than one
|
||||
(1) year from the date of original notice and subject to
|
||||
applicable statute of limitations, to binding arbitration in
|
||||
accordance with the UNCITRAL Arbitration Rules in effect on the
|
||||
date of this contract. The appointing authority shall be the
|
||||
International Centre for Dispute Resolution. The case shall be
|
||||
administered by the International Centre for Dispute Resolution
|
||||
under its Procedures for Cases under the UNCITRAL Arbitration
|
||||
Rules. Each Participant shall bear its own expenses and shall
|
||||
share equally in fees of the arbitrator. All arbitrators shall
|
||||
have substantial experience in information technology and/or in
|
||||
the telecommunications business and shall be selected by the
|
||||
disputing participants in accordance with UNCITRAL Arbitration
|
||||
Rules. If any arbitrator, once selected is unable or unwilling
|
||||
to continue for any reason, replacement shall be filled via the
|
||||
process described above and a re-hearing shall be conducted. The
|
||||
disputing Participants will provide each other with all
|
||||
requested documents and records reasonably related to the
|
||||
dispute in a manner that will minimize the expense and
|
||||
inconvenience of both parties. Discovery will not include
|
||||
depositions or interrogatories except as the arbitrators
|
||||
expressly allow upon a showing of need. If disputes arise
|
||||
concerning discovery requests, the arbitrators shall have sole
|
||||
and complete discretion to resolve the disputes. The parties and
|
||||
arbitrator shall be guided in resolving discovery disputes by
|
||||
the Federal Rules of Civil Procedure. The Participants agree
|
||||
that time of the essence principles shall guide the hearing and
|
||||
that the arbitrator shall have the right and authority to issue
|
||||
monetary sanctions in the event of unreasonable delay. The
|
||||
arbitrator shall deliver a written opinion setting forth
|
||||
findings of fact and the rationale for the award within thirty
|
||||
(30) days following conclusion of the hearing. The award of the
|
||||
arbitrator, which may include legal and equitable relief, but
|
||||
which may not include punitive damages, will be final and
|
||||
binding upon the disputing Participants, and judgment may be
|
||||
entered upon it in accordance with applicable law in any court
|
||||
having jurisdiction thereof. In addition to award the
|
||||
arbitrator shall have the discretion to award the prevailing
|
||||
Participant all or part of its attorneys' fees and costs,
|
||||
including fees associated with arbitrator, if the arbitrator
|
||||
determines that the positions taken by the other Participant on
|
||||
material issues of the dispute were without substantial
|
||||
foundation. Any conflict between the UNCITRAL Arbitration Rules
|
||||
and the provisions of this GPA shall be controlled by this GPA.
|
||||
|
||||
21. INTEGRATED AGREEMENT. This GPA, constitutes the complete
|
||||
integrated agreement between the parties concerning the subject matter
|
||||
hereof. All prior and contemporaneous agreements, understandings,
|
||||
negotiations or representations, whether oral or in writing, relating to
|
||||
the subject matter of this GPA are superseded and canceled in their
|
||||
entirety.
|
||||
|
||||
22. WAIVER. No waiver of any of the provisions of this GPA shall be
|
||||
deemed or shall constitute a waiver of any other provision of this GPA,
|
||||
whether or not similar, nor shall such waiver constitute a continuing
|
||||
waiver unless otherwise expressly so provided in writing. The failure
|
||||
of either party to enforce at any time any of the provisions of this
|
||||
GPA, or the failure to require at any time performance by either party
|
||||
of any of the provisions of this GPA, shall in no way be construed to be
|
||||
a present or future waiver of such provisions, nor in any way affect the
|
||||
ability of a Participant to enforce each and every such provision
|
||||
thereafter.
|
||||
|
||||
23. INDEPENDENT CONTRACTORS. Nothing in this GPA shall make the
|
||||
Parties partners, joint venturers, or otherwise associated in or with
|
||||
the business of the other. Parties are, and shall always remain,
|
||||
independent contractors. No Participant shall be liable for any debts,
|
||||
accounts, obligations, or other liabilities of the other Participant,
|
||||
its agents or employees. No party is authorized to incur debts or other
|
||||
obligations of any kind on the part of or as agent for the other. This
|
||||
GPA is not a franchise agreement and does not create a franchise
|
||||
relationship between the parties, and if any provision of this GPA is
|
||||
deemed to create a franchise between the parties, then this GPA shall
|
||||
automatically terminate.
|
||||
|
||||
24. CAPTIONS AND HEADINGS. The captions and headings used in this GPA
|
||||
are used for convenience only and are not to be given any legal effect.
|
||||
|
||||
25. EXECUTION. This GPA may be executed in counterparts, each of which
|
||||
so executed will be deemed to be an original and such counterparts
|
||||
together will constitute one and the same Agreement. The Parties shall
|
||||
transmit to each other a signed copy of the GPA by any means that
|
||||
faithfully reproduces the GPA along with the Signature. For purposes of
|
||||
this GPA, the term "signature" shall include digital signatures as
|
||||
defined by the jurisdiction of the Participant signing the GPA.
|
||||
|
||||
Exhibit A
|
||||
|
||||
Weight Range Requirements
|
||||
|
||||
0-99 May only be used under authorization of Owner
|
||||
|
||||
100-199 May only be used by the Owner's service
|
||||
provider, regardless of authorization.
|
||||
|
||||
200-299 Reserved -- do not use for e164 context.
|
||||
|
||||
300-399 May only be used by the owner of the code under
|
||||
which the Owner's number is a part of.
|
||||
|
||||
400-499 May be used by any entity providing access via
|
||||
direct connectivity to the Public Switched
|
||||
Telephone Network.
|
||||
|
||||
500-599 May be used by any entity providing access via
|
||||
indirect connectivity to the Public Switched
|
||||
Telephone Network (e.g. Via another VoIP
|
||||
provider)
|
||||
|
||||
600- Reserved-- do not use for e164 context.
|
||||
|
||||
Participant Participant
|
||||
|
||||
Company:
|
||||
|
||||
Address:
|
||||
|
||||
Email:
|
||||
|
||||
|
||||
_________________________ _________________________
|
||||
Authorized Signature Authorized Signature
|
||||
|
||||
Name:
|
||||
|
||||
|
||||
END OF GENERAL PEERING AGREEMENT
|
||||
|
||||
------------------------------------------------
|
||||
|
||||
How to Peer using this GPA If you wish to exchange routing information
|
||||
with parties using the e164 DUNDi context, all you must do is execute
|
||||
this GPA with any member of the Peering System and you will become a
|
||||
member of the Peering System and be able to make Routes available in
|
||||
accordance with this GPA.
|
||||
|
||||
DUNDi, IAX, Asterisk and GPA are trademarks of Digium, Inc.
|
@ -0,0 +1,26 @@
|
||||
Distributed Universal Number Directory (DUNDi) (tm)
|
||||
===================================================
|
||||
http://www.dundi.com
|
||||
Mark Spencer, Digium, Inc.
|
||||
|
||||
DUNDi is essentially a trusted, peer-to-peer system for being able to
|
||||
call any phone number from the Internet. DUNDi works by creating a
|
||||
network of nodes called the "DUNDi E.164 Trust Group" which are bound by
|
||||
a common peering agreement known as the General Peering Agreement or
|
||||
GPA. The GPA legally binds the members of the Trust Group to provide
|
||||
good-faith accurate information to the other nodes on the network, and
|
||||
provides standards by which the community can insure the integrity of
|
||||
the information on the nodes themselves. Unlike ENUM or similar
|
||||
systems, DUNDi is explicitly designed to preclude any necessity for a
|
||||
single centralized system which could be a source of fees, regulation,
|
||||
etc.
|
||||
|
||||
You can find the PEERING agreement in the doc directory.
|
||||
|
||||
Much less dramatically, DUNDi can also be used within a private
|
||||
enterprise to share a dialplan efficiently between multiple nodes,
|
||||
without incuring a risk of a single point of failure. In this way,
|
||||
administrators can locally add extensions which become immediately
|
||||
available to the other nodes in the system.
|
||||
|
||||
For more information visit http://www.dundi.com
|
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Distributed Universal Number Discovery (DUNDi)
|
||||
*
|
||||
* Copyright (C) 2004, Digium Inc.
|
||||
*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is Free Software distributed under the terms of
|
||||
* of the GNU General Public License.
|
||||
*/
|
||||
#ifndef _ASTERISK_DUNDI_H
|
||||
#define _ASTERISK_DUNDI_H
|
||||
|
||||
#include <asterisk/channel.h>
|
||||
|
||||
#define DUNDI_PORT 4520
|
||||
|
||||
/* A DUNDi Entity ID is essentially a MAC address, brief and unique */
|
||||
struct _dundi_eid {
|
||||
unsigned char eid[6];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
typedef struct _dundi_eid dundi_eid;
|
||||
|
||||
struct dundi_hdr {
|
||||
unsigned short strans; /* Source transaction */
|
||||
unsigned short dtrans; /* Destination transaction */
|
||||
unsigned char iseqno; /* Next expected incoming sequence number */
|
||||
unsigned char oseqno; /* Outgoing sequence number */
|
||||
unsigned char cmdresp; /* Command / Response */
|
||||
unsigned char cmdflags; /* Command / Response specific flags*/
|
||||
unsigned char ies[0];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct dundi_ie_hdr {
|
||||
unsigned char ie;
|
||||
unsigned char len;
|
||||
unsigned char iedata[0];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define DUNDI_FLAG_RETRANS (1 << 16) /* Applies to dtrans */
|
||||
#define DUNDI_FLAG_RESERVED (1 << 16) /* Applies to strans */
|
||||
|
||||
#define DUNDI_PROTO_NONE 0 /* No answer yet */
|
||||
#define DUNDI_PROTO_IAX 1 /* IAX version 2 */
|
||||
#define DUNDI_PROTO_SIP 2 /* Session Initiation Protocol */
|
||||
#define DUNDI_PROTO_H323 3 /* ITU H.323 */
|
||||
|
||||
#define DUNDI_FLAG_NONEXISTANT (0) /* Isn't and can't be a valid number */
|
||||
#define DUNDI_FLAG_EXISTS (1 << 0) /* Is a valid number */
|
||||
#define DUNDI_FLAG_MATCHMORE (1 << 1) /* Might be valid if you add more digits */
|
||||
#define DUNDI_FLAG_CANMATCH (1 << 2) /* Might be a match */
|
||||
#define DUNDI_FLAG_IGNOREPAT (1 << 3) /* Keep dialtone */
|
||||
#define DUNDI_FLAG_RESIDENTIAL (1 << 4) /* Destination known to be residential */
|
||||
#define DUNDI_FLAG_COMMERCIAL (1 << 5) /* Destination known to be commercial */
|
||||
#define DUNDI_FLAG_MOBILE (1 << 6) /* Destination known to be cellular/mobile */
|
||||
#define DUNDI_FLAG_NOUNSOLICITED (1 << 7) /* No unsolicited calls of any kind through this route */
|
||||
#define DUNDI_FLAG_NOCOMUNSOLICIT (1 << 8) /* No commercial unsolicited calls through this route */
|
||||
|
||||
#define DUNDI_HINT_NONE (0)
|
||||
#define DUNDI_HINT_TTL_EXPIRED (1 << 0) /* TTL Expired */
|
||||
#define DUNDI_HINT_DONT_ASK (1 << 1) /* Don't ask for anything beginning with data */
|
||||
#define DUNDI_HINT_UNAFFECTED (1 << 2) /* Answer not affected by entity list */
|
||||
|
||||
struct dundi_encblock { /* AES-128 encrypted block */
|
||||
unsigned char iv[16]; /* Initialization vector of random data */
|
||||
unsigned char encdata[0]; /* Encrypted / compressed data */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct dundi_answer {
|
||||
dundi_eid eid; /* Original source of answer */
|
||||
unsigned char protocol; /* Protocol (DUNDI_PROTO_*) */
|
||||
unsigned short flags; /* Flags relating to answer */
|
||||
unsigned short weight; /* Weight of answers */
|
||||
unsigned char data[0]; /* Protocol specific URI */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct dundi_hint {
|
||||
unsigned short flags; /* Flags relating to answer */
|
||||
unsigned char data[0]; /* For data for hint */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define DUNDI_CAUSE_SUCCESS 0 /* Success */
|
||||
#define DUNDI_CAUSE_GENERAL 1 /* General unspecified failure */
|
||||
#define DUNDI_CAUSE_DYNAMIC 2 /* Requested entity is dynamic */
|
||||
#define DUNDI_CAUSE_NOAUTH 3 /* No or improper authorization */
|
||||
#define DUNDI_CAUSE_DUPLICATE 4 /* Duplicate request */
|
||||
#define DUNDI_CAUSE_TTL_EXPIRED 5 /* Expired TTL */
|
||||
#define DUNDI_CAUSE_NEEDKEY 6 /* Need new session key to decode */
|
||||
#define DUNDI_CAUSE_BADENCRYPT 7 /* Badly encrypted data */
|
||||
|
||||
struct dundi_cause {
|
||||
unsigned char causecode; /* Numerical cause (DUNDI_CAUSE_*) */
|
||||
char desc[0]; /* Textual description */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define DUNDI_COMMAND_FINAL (0x80) /* Or'd with other flags */
|
||||
|
||||
#define DUNDI_COMMAND_ACK (0 | 0x40) /* Ack a message */
|
||||
#define DUNDI_COMMAND_DPDISCOVER 1 /* Request discovery */
|
||||
#define DUNDI_COMMAND_DPRESPONSE (2 | 0x40) /* Respond to a discovery request */
|
||||
#define DUNDI_COMMAND_EIDQUERY 3 /* Request information for a peer */
|
||||
#define DUNDI_COMMAND_EIDRESPONSE (4 | 0x40) /* Response to a peer query */
|
||||
#define DUNDI_COMMAND_INVALID (7 | 0x40) /* Invalid dialog state (does not require ack) */
|
||||
#define DUNDI_COMMAND_UNKNOWN (8 | 0x40) /* Unknown command */
|
||||
#define DUNDI_COMMAND_NULL 9 /* No-op */
|
||||
#define DUNDI_COMMAND_REGREQ (10) /* Register Request */
|
||||
#define DUNDI_COMMAND_REGRESPONSE (11 | 0x40) /* Register Response */
|
||||
#define DUNDI_COMMAND_CANCEL (12) /* Cancel transaction entirely */
|
||||
#define DUNDI_COMMAND_ENCRYPT (13) /* Send an encrypted message */
|
||||
#define DUNDI_COMMAND_ENCREJ (14 | 0x40) /* Reject an encrypted message */
|
||||
|
||||
/*
|
||||
* Remember that some information elements may occur
|
||||
* more than one time within a message
|
||||
*/
|
||||
|
||||
#define DUNDI_IE_EID 1 /* Entity identifier (dundi_eid) */
|
||||
#define DUNDI_IE_CALLED_CONTEXT 2 /* DUNDi Context (string) */
|
||||
#define DUNDI_IE_CALLED_NUMBER 3 /* Number of equivalent (string) */
|
||||
#define DUNDI_IE_EID_DIRECT 4 /* Entity identifier (dundi_eid), direct connect */
|
||||
#define DUNDI_IE_ANSWER 5 /* An answer (struct dundi_answer) */
|
||||
#define DUNDI_IE_TTL 6 /* Max TTL for this request / Remaining TTL for the response (short)*/
|
||||
#define DUNDI_IE_VERSION 10 /* DUNDi version (should be 1) (short) */
|
||||
#define DUNDI_IE_EXPIRATION 11 /* Recommended expiration (short) */
|
||||
#define DUNDI_IE_UNKNOWN 12 /* Unknown command (byte) */
|
||||
#define DUNDI_IE_CAUSE 14 /* Success or cause of failure */
|
||||
#define DUNDI_IE_REQEID 15 /* EID being requested for EIDQUERY*/
|
||||
#define DUNDI_IE_ENCDATA 16 /* AES-128 encrypted data */
|
||||
#define DUNDI_IE_SHAREDKEY 17 /* RSA encrypted AES-128 key */
|
||||
#define DUNDI_IE_SIGNATURE 18 /* RSA Signature of encrypted shared key */
|
||||
#define DUNDI_IE_KEYCRC32 19 /* CRC32 of encrypted key (int) */
|
||||
#define DUNDI_IE_HINT 20 /* Answer hints (struct ast_hint) */
|
||||
|
||||
#define DUNDI_IE_DEPARTMENT 21 /* Department, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_ORGANIZATION 22 /* Organization, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_LOCALITY 23 /* City/Locality, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_STATE_PROV 24 /* State/Province, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_COUNTRY 25 /* Country, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_EMAIL 26 /* E-mail addy, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_PHONE 27 /* Contact Phone, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_IPADDR 28 /* IP Address, for EIDQUERY (string) */
|
||||
|
||||
#define DUNDI_FLUFF_TIME 2000 /* Amount of time for answer */
|
||||
#define DUNDI_TTL_TIME 200 /* Incremental average time */
|
||||
|
||||
#define DUNDI_DEFAULT_RETRANS 5
|
||||
#define DUNDI_DEFAULT_RETRANS_TIMER 1000
|
||||
#define DUNDI_DEFAULT_TTL 120 /* In seconds/hops like TTL */
|
||||
#define DUNDI_DEFAULT_VERSION 1
|
||||
#define DUNDI_DEFAULT_CACHE_TIME 3600 /* In seconds */
|
||||
#define DUNDI_DEFAULT_KEY_EXPIRE 3600 /* Life of shared key In seconds */
|
||||
#define DUNDI_DEF_EMPTY_CACHE_TIME 60 /* In seconds, cache of empty answer */
|
||||
#define DUNDI_WINDOW 1 /* Max 1 message in window */
|
||||
|
||||
#define DEFAULT_MAXMS 2000
|
||||
|
||||
struct dundi_result {
|
||||
int flags;
|
||||
int weight;
|
||||
int expiration;
|
||||
int techint;
|
||||
dundi_eid eid;
|
||||
char eid_str[20];
|
||||
char tech[10];
|
||||
char dest[256];
|
||||
};
|
||||
|
||||
struct dundi_entity_info {
|
||||
char country[80];
|
||||
char stateprov[80];
|
||||
char locality[80];
|
||||
char org[80];
|
||||
char orgunit[80];
|
||||
char email[80];
|
||||
char phone[80];
|
||||
char ipaddr[80];
|
||||
};
|
||||
|
||||
/* Lookup the given number in the given dundi context (or e164 if unspecified) using the given callerid (if specified) and return up to maxret results in the array specified.
|
||||
returns the number of results found or -1 on a hangup of teh channel. */
|
||||
int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number);
|
||||
|
||||
/* Retrieve information on a specific EID */
|
||||
int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_eid eid);
|
||||
#endif /* _ASTERISK_DUNDI_H */
|
@ -0,0 +1,802 @@
|
||||
/*
|
||||
* Distributed Universal Number Discovery (DUNDi)
|
||||
*
|
||||
* Copyright (C) 2004, Digium Inc.
|
||||
*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is Free Software distributed under the terms of
|
||||
* of the GNU General Public License.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <asterisk/frame.h>
|
||||
#include <asterisk/utils.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <asterisk/dundi.h>
|
||||
#include "dundi-parser.h"
|
||||
#include <asterisk/dundi.h>
|
||||
static void internaloutput(const char *str)
|
||||
{
|
||||
printf(str);
|
||||
}
|
||||
|
||||
static void internalerror(const char *str)
|
||||
{
|
||||
fprintf(stderr, "WARNING: %s", str);
|
||||
}
|
||||
|
||||
static void (*outputf)(const char *str) = internaloutput;
|
||||
static void (*errorf)(const char *str) = internalerror;
|
||||
|
||||
char *dundi_eid_to_str(char *s, int maxlen, dundi_eid *eid)
|
||||
{
|
||||
int x;
|
||||
char *os = s;
|
||||
if (maxlen < 18) {
|
||||
if (s && (maxlen > 0))
|
||||
*s = '\0';
|
||||
} else {
|
||||
for (x=0;x<5;x++) {
|
||||
sprintf(s, "%02x:", eid->eid[x]);
|
||||
s += 3;
|
||||
}
|
||||
sprintf(s, "%02x", eid->eid[5]);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
char *dundi_eid_to_str_short(char *s, int maxlen, dundi_eid *eid)
|
||||
{
|
||||
int x;
|
||||
char *os = s;
|
||||
if (maxlen < 13) {
|
||||
if (s && (maxlen > 0))
|
||||
*s = '\0';
|
||||
} else {
|
||||
for (x=0;x<6;x++) {
|
||||
sprintf(s, "%02X", eid->eid[x]);
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
int dundi_str_to_eid(dundi_eid *eid, char *s)
|
||||
{
|
||||
unsigned int eid_int[6];
|
||||
int x;
|
||||
if (sscanf(s, "%x:%x:%x:%x:%x:%x", &eid_int[0], &eid_int[1], &eid_int[2],
|
||||
&eid_int[3], &eid_int[4], &eid_int[5]) != 6)
|
||||
return -1;
|
||||
for (x=0;x<6;x++)
|
||||
eid->eid[x] = eid_int[x];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dundi_str_short_to_eid(dundi_eid *eid, char *s)
|
||||
{
|
||||
unsigned int eid_int[6];
|
||||
int x;
|
||||
if (sscanf(s, "%2x%2x%2x%2x%2x%2x", &eid_int[0], &eid_int[1], &eid_int[2],
|
||||
&eid_int[3], &eid_int[4], &eid_int[5]) != 6)
|
||||
return -1;
|
||||
for (x=0;x<6;x++)
|
||||
eid->eid[x] = eid_int[x];
|
||||
return 0;
|
||||
}
|
||||
int dundi_eid_zero(dundi_eid *eid)
|
||||
{
|
||||
int x;
|
||||
for (x=0;x<sizeof(eid->eid) / sizeof(eid->eid[0]);x++)
|
||||
if (eid->eid[x]) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dundi_eid_cmp(dundi_eid *eid1, dundi_eid *eid2)
|
||||
{
|
||||
return memcmp(eid1, eid2, sizeof(dundi_eid));
|
||||
}
|
||||
|
||||
static void dump_string(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
maxlen--;
|
||||
if (maxlen > len)
|
||||
maxlen = len;
|
||||
strncpy(output,value, maxlen);
|
||||
output[maxlen] = '\0';
|
||||
}
|
||||
|
||||
static void dump_eid(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == 6)
|
||||
dundi_eid_to_str(output, maxlen, (dundi_eid *)value);
|
||||
else
|
||||
snprintf(output, maxlen, "Invalid EID len %d", len);
|
||||
}
|
||||
|
||||
char *dundi_hint2str(char *buf, int bufsiz, int flags)
|
||||
{
|
||||
strcpy(buf, "");
|
||||
buf[bufsiz-1] = '\0';
|
||||
if (flags & DUNDI_HINT_TTL_EXPIRED) {
|
||||
strncat(buf, "TTLEXPIRED|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_HINT_DONT_ASK) {
|
||||
strncat(buf, "DONTASK|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_HINT_UNAFFECTED) {
|
||||
strncat(buf, "UNAFFECTED|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
/* Get rid of trailing | */
|
||||
if (ast_strlen_zero(buf))
|
||||
strcpy(buf, "NONE|");
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void dump_hint(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
unsigned short flags;
|
||||
char tmp[512];
|
||||
char tmp2[256];
|
||||
if (len < 2) {
|
||||
strncpy(output, "<invalid contents>", maxlen);
|
||||
return;
|
||||
}
|
||||
memcpy(&flags, value, sizeof(flags));
|
||||
flags = ntohs(flags);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
dundi_hint2str(tmp2, sizeof(tmp2), flags);
|
||||
snprintf(tmp, sizeof(tmp), "[%s] ", tmp2);
|
||||
memcpy(tmp + strlen(tmp), value + 2, len - 2);
|
||||
strncpy(output, tmp, maxlen - 1);
|
||||
}
|
||||
|
||||
static void dump_cause(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
static char *causes[] = {
|
||||
"SUCCESS",
|
||||
"GENERAL",
|
||||
"DYNAMIC",
|
||||
"NOAUTH" ,
|
||||
};
|
||||
char tmp[256];
|
||||
char tmp2[256];
|
||||
int mlen;
|
||||
unsigned char cause;
|
||||
if (len < 1) {
|
||||
strncpy(output, "<invalid contents>", maxlen);
|
||||
return;
|
||||
}
|
||||
cause = *((unsigned char *)value);
|
||||
memset(tmp2, 0, sizeof(tmp2));
|
||||
mlen = len - 1;
|
||||
if (mlen > 255)
|
||||
mlen = 255;
|
||||
memcpy(tmp2, value + 1, mlen);
|
||||
if (cause < sizeof(causes) / sizeof(causes[0])) {
|
||||
if (len > 1)
|
||||
snprintf(tmp, sizeof(tmp), "%s: %s", causes[cause], tmp2);
|
||||
else
|
||||
snprintf(tmp, sizeof(tmp), "%s", causes[cause]);
|
||||
} else {
|
||||
if (len > 1)
|
||||
snprintf(tmp, sizeof(tmp), "%d: %s", cause, tmp2);
|
||||
else
|
||||
snprintf(tmp, sizeof(tmp), "%d", cause);
|
||||
}
|
||||
|
||||
strncpy(output,tmp, maxlen);
|
||||
output[maxlen] = '\0';
|
||||
}
|
||||
|
||||
static void dump_int(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == (int)sizeof(unsigned int))
|
||||
snprintf(output, maxlen, "%lu", (unsigned long)ntohl(*((unsigned int *)value)));
|
||||
else
|
||||
snprintf(output, maxlen, "Invalid INT");
|
||||
}
|
||||
|
||||
static void dump_short(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == (int)sizeof(unsigned short))
|
||||
snprintf(output, maxlen, "%d", ntohs(*((unsigned short *)value)));
|
||||
else
|
||||
snprintf(output, maxlen, "Invalid SHORT");
|
||||
}
|
||||
|
||||
static void dump_byte(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == (int)sizeof(unsigned char))
|
||||
snprintf(output, maxlen, "%d", *((unsigned char *)value));
|
||||
else
|
||||
snprintf(output, maxlen, "Invalid BYTE");
|
||||
}
|
||||
|
||||
static char *proto2str(int proto, char *buf, int bufsiz)
|
||||
{
|
||||
|
||||
switch(proto) {
|
||||
case DUNDI_PROTO_NONE:
|
||||
strncpy(buf, "None", bufsiz - 1);
|
||||
break;
|
||||
case DUNDI_PROTO_IAX:
|
||||
strncpy(buf, "IAX", bufsiz - 1);
|
||||
break;
|
||||
case DUNDI_PROTO_SIP:
|
||||
strncpy(buf, "SIP", bufsiz - 1);
|
||||
break;
|
||||
case DUNDI_PROTO_H323:
|
||||
strncpy(buf, "H.323", bufsiz - 1);
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, bufsiz, "Unknown Proto(%d)", proto);
|
||||
}
|
||||
buf[bufsiz-1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *dundi_flags2str(char *buf, int bufsiz, int flags)
|
||||
{
|
||||
strcpy(buf, "");
|
||||
buf[bufsiz-1] = '\0';
|
||||
if (flags & DUNDI_FLAG_EXISTS) {
|
||||
strncat(buf, "EXISTS|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_MATCHMORE) {
|
||||
strncat(buf, "MATCHMORE|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_CANMATCH) {
|
||||
strncat(buf, "CANMATCH|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_IGNOREPAT) {
|
||||
strncat(buf, "IGNOREPAT|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_RESIDENTIAL) {
|
||||
strncat(buf, "RESIDENCE|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_COMMERCIAL) {
|
||||
strncat(buf, "COMMERCIAL|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_MOBILE) {
|
||||
strncat(buf, "MOBILE", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_NOUNSOLICITED) {
|
||||
strncat(buf, "NOUNSLCTD|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
if (flags & DUNDI_FLAG_NOCOMUNSOLICIT) {
|
||||
strncat(buf, "NOCOMUNSLTD|", bufsiz - strlen(buf) - 1);
|
||||
}
|
||||
/* Get rid of trailing | */
|
||||
if (ast_strlen_zero(buf))
|
||||
strcpy(buf, "NONE|");
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void dump_answer(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
struct dundi_answer *answer;
|
||||
char proto[40];
|
||||
char flags[40];
|
||||
char eid_str[40];
|
||||
char tmp[512]="";
|
||||
if (len >= 10) {
|
||||
answer = (struct dundi_answer *)(value);
|
||||
memcpy(tmp, answer->data, (len >= 500) ? 500 : len - 10);
|
||||
dundi_eid_to_str(eid_str, sizeof(eid_str), &answer->eid);
|
||||
snprintf(output, maxlen, "[%s] %d <%s/%s> from [%s]",
|
||||
dundi_flags2str(flags, sizeof(flags), ntohs(answer->flags)),
|
||||
ntohs(answer->weight),
|
||||
proto2str(answer->protocol, proto, sizeof(proto)),
|
||||
tmp, eid_str);
|
||||
} else
|
||||
strncpy(output, "Invalid Answer", maxlen - 1);
|
||||
}
|
||||
|
||||
static void dump_encrypted(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
char iv[33];
|
||||
int x;
|
||||
if ((len > 16) && !(len % 16)) {
|
||||
/* Build up IV */
|
||||
for (x=0;x<16;x++) {
|
||||
snprintf(iv + (x << 1), 3, "%02x", ((unsigned char *)value)[x]);
|
||||
}
|
||||
snprintf(output, maxlen, "[IV %s] %d encrypted blocks\n", iv, len / 16);
|
||||
} else
|
||||
snprintf(output, maxlen, "Invalid Encrypted Datalen %d", len);
|
||||
}
|
||||
|
||||
static void dump_raw(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
int x;
|
||||
unsigned char *u = value;
|
||||
output[maxlen - 1] = '\0';
|
||||
strcpy(output, "[ ");
|
||||
for (x=0;x<len;x++) {
|
||||
snprintf(output + strlen(output), maxlen - strlen(output) - 1, "%02x ", u[x]);
|
||||
}
|
||||
strncat(output + strlen(output), "]", maxlen - strlen(output) - 1);
|
||||
}
|
||||
|
||||
static struct dundi_ie {
|
||||
int ie;
|
||||
char *name;
|
||||
void (*dump)(char *output, int maxlen, void *value, int len);
|
||||
} ies[] = {
|
||||
{ DUNDI_IE_EID, "ENTITY IDENT", dump_eid },
|
||||
{ DUNDI_IE_CALLED_CONTEXT, "CALLED CONTEXT", dump_string },
|
||||
{ DUNDI_IE_CALLED_NUMBER, "CALLED NUMBER", dump_string },
|
||||
{ DUNDI_IE_EID_DIRECT, "DIRECT EID", dump_eid },
|
||||
{ DUNDI_IE_ANSWER, "ANSWER", dump_answer },
|
||||
{ DUNDI_IE_TTL, "TTL", dump_short },
|
||||
{ DUNDI_IE_VERSION, "VERSION", dump_short },
|
||||
{ DUNDI_IE_EXPIRATION, "EXPIRATION", dump_short },
|
||||
{ DUNDI_IE_UNKNOWN, "UKWN DUNDI CMD", dump_byte },
|
||||
{ DUNDI_IE_CAUSE, "CAUSE", dump_cause },
|
||||
{ DUNDI_IE_REQEID, "REQUEST EID", dump_eid },
|
||||
{ DUNDI_IE_ENCDATA, "ENCDATA", dump_encrypted },
|
||||
{ DUNDI_IE_SHAREDKEY, "SHAREDKEY", dump_raw },
|
||||
{ DUNDI_IE_SIGNATURE, "SIGNATURE", dump_raw },
|
||||
{ DUNDI_IE_KEYCRC32, "KEYCRC32", dump_int },
|
||||
{ DUNDI_IE_HINT, "HINT", dump_hint },
|
||||
{ DUNDI_IE_DEPARTMENT, "DEPARTMENT", dump_string },
|
||||
{ DUNDI_IE_ORGANIZATION, "ORGANIZTN", dump_string },
|
||||
{ DUNDI_IE_LOCALITY, "LOCALITY", dump_string },
|
||||
{ DUNDI_IE_STATE_PROV, "STATEPROV", dump_string },
|
||||
{ DUNDI_IE_COUNTRY, "COUNTRY", dump_string },
|
||||
{ DUNDI_IE_EMAIL, "EMAIL", dump_string },
|
||||
{ DUNDI_IE_PHONE, "PHONE", dump_string },
|
||||
{ DUNDI_IE_IPADDR, "ADDRESS", dump_string },
|
||||
};
|
||||
|
||||
const char *dundi_ie2str(int ie)
|
||||
{
|
||||
int x;
|
||||
for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
|
||||
if (ies[x].ie == ie)
|
||||
return ies[x].name;
|
||||
}
|
||||
return "Unknown IE";
|
||||
}
|
||||
|
||||
static void dump_ies(unsigned char *iedata, int spaces, int len)
|
||||
{
|
||||
int ielen;
|
||||
int ie;
|
||||
int x;
|
||||
int found;
|
||||
char interp[1024];
|
||||
char tmp[1024];
|
||||
if (len < 2)
|
||||
return;
|
||||
while(len > 2) {
|
||||
ie = iedata[0];
|
||||
ielen = iedata[1];
|
||||
/* Encrypted data is the remainder */
|
||||
if (ie == DUNDI_IE_ENCDATA)
|
||||
ielen = len - 2;
|
||||
if (ielen + 2> len) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
|
||||
outputf(tmp);
|
||||
return;
|
||||
}
|
||||
found = 0;
|
||||
for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
|
||||
if (ies[x].ie == ie) {
|
||||
if (ies[x].dump) {
|
||||
ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
|
||||
snprintf(tmp, (int)sizeof(tmp), " %s%-15.15s : %s\n", (spaces ? " " : "" ), ies[x].name, interp);
|
||||
outputf(tmp);
|
||||
} else {
|
||||
if (ielen)
|
||||
snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
|
||||
else
|
||||
strcpy(interp, "Present");
|
||||
snprintf(tmp, (int)sizeof(tmp), " %s%-15.15s : %s\n", (spaces ? " " : "" ), ies[x].name, interp);
|
||||
outputf(tmp);
|
||||
}
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
snprintf(tmp, (int)sizeof(tmp), " %sUnknown IE %03d : Present\n", (spaces ? " " : "" ), ie);
|
||||
outputf(tmp);
|
||||
}
|
||||
iedata += (2 + ielen);
|
||||
len -= (2 + ielen);
|
||||
}
|
||||
outputf("\n");
|
||||
}
|
||||
|
||||
void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
|
||||
{
|
||||
char *pref[] = {
|
||||
"Tx",
|
||||
"Rx",
|
||||
" ETx",
|
||||
" Erx" };
|
||||
char *commands[] = {
|
||||
"ACK ",
|
||||
"DPDISCOVER ",
|
||||
"DPRESPONSE ",
|
||||
"EIDQUERY ",
|
||||
"EIDRESPONSE ",
|
||||
"UNKNOWN (5)?",
|
||||
"UNKNOWN (6)?",
|
||||
"INVALID ",
|
||||
"UNKNOWN CMD ",
|
||||
"NULL ",
|
||||
"REQREQ ",
|
||||
"REGRESPONSE ",
|
||||
"CANCEL ",
|
||||
"ENCRYPT ",
|
||||
"ENCREJ " };
|
||||
char class2[20];
|
||||
char *class;
|
||||
char subclass2[20];
|
||||
char *subclass;
|
||||
char tmp[256];
|
||||
char retries[20];
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
if (ntohs(fhi->dtrans) & DUNDI_FLAG_RETRANS)
|
||||
strcpy(retries, "Yes");
|
||||
else
|
||||
strcpy(retries, "No");
|
||||
if ((ntohs(fhi->strans) & DUNDI_FLAG_RESERVED)) {
|
||||
/* Ignore frames with high bit set to 1 */
|
||||
return;
|
||||
}
|
||||
if ((fhi->cmdresp & 0x3f) > (int)sizeof(commands)/(int)sizeof(char *)) {
|
||||
snprintf(class2, (int)sizeof(class2), "(%d?)", fhi->cmdresp);
|
||||
class = class2;
|
||||
} else {
|
||||
class = commands[(int)(fhi->cmdresp & 0x3f)];
|
||||
}
|
||||
snprintf(subclass2, (int)sizeof(subclass2), "%02x", fhi->cmdflags);
|
||||
subclass = subclass2;
|
||||
snprintf(tmp, (int)sizeof(tmp),
|
||||
"%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s (%s)\n",
|
||||
pref[rx],
|
||||
retries, fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command");
|
||||
outputf(tmp);
|
||||
snprintf(tmp, (int)sizeof(tmp),
|
||||
"%s Flags: %s STrans: %5.5d DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? " " : "",
|
||||
subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS,
|
||||
ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port),
|
||||
fhi->cmdresp & 0x80 ? " (Final)" : "");
|
||||
outputf(tmp);
|
||||
dump_ies(fhi->ies, rx > 1, datalen);
|
||||
}
|
||||
|
||||
int dundi_ie_append_raw(struct dundi_ie_data *ied, unsigned char ie, void *data, int datalen)
|
||||
{
|
||||
char tmp[256];
|
||||
if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
|
||||
errorf(tmp);
|
||||
return -1;
|
||||
}
|
||||
ied->buf[ied->pos++] = ie;
|
||||
ied->buf[ied->pos++] = datalen;
|
||||
memcpy(ied->buf + ied->pos, data, datalen);
|
||||
ied->pos += datalen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dundi_ie_append_cause(struct dundi_ie_data *ied, unsigned char ie, unsigned char cause, unsigned char *data)
|
||||
{
|
||||
char tmp[256];
|
||||
int datalen = data ? strlen(data) + 1 : 1;
|
||||
if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
|
||||
errorf(tmp);
|
||||
return -1;
|
||||
}
|
||||
ied->buf[ied->pos++] = ie;
|
||||
ied->buf[ied->pos++] = datalen;
|
||||
ied->buf[ied->pos++] = cause;
|
||||
memcpy(ied->buf + ied->pos, data, datalen-1);
|
||||
ied->pos += datalen-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dundi_ie_append_hint(struct dundi_ie_data *ied, unsigned char ie, unsigned short flags, unsigned char *data)
|
||||
{
|
||||
char tmp[256];
|
||||
int datalen = data ? strlen(data) + 2 : 2;
|
||||
if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
|
||||
errorf(tmp);
|
||||
return -1;
|
||||
}
|
||||
ied->buf[ied->pos++] = ie;
|
||||
ied->buf[ied->pos++] = datalen;
|
||||
flags = htons(flags);
|
||||
memcpy(ied->buf + ied->pos, &flags, sizeof(flags));
|
||||
ied->pos += 2;
|
||||
memcpy(ied->buf + ied->pos, data, datalen-1);
|
||||
ied->pos += datalen-2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dundi_ie_append_encdata(struct dundi_ie_data *ied, unsigned char ie, unsigned char *iv, void *data, int datalen)
|
||||
{
|
||||
char tmp[256];
|
||||
datalen += 16;
|
||||
if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
|
||||
errorf(tmp);
|
||||
return -1;
|
||||
}
|
||||
ied->buf[ied->pos++] = ie;
|
||||
ied->buf[ied->pos++] = datalen;
|
||||
memcpy(ied->buf + ied->pos, iv, 16);
|
||||
ied->pos += 16;
|
||||
if (data) {
|
||||
memcpy(ied->buf + ied->pos, data, datalen-16);
|
||||
ied->pos += datalen-16;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dundi_ie_append_answer(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid, unsigned char protocol, unsigned short flags, unsigned short weight, unsigned char *data)
|
||||
{
|
||||
char tmp[256];
|
||||
int datalen = data ? strlen(data) + 11 : 11;
|
||||
int x;
|
||||
unsigned short myw;
|
||||
if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", dundi_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
|
||||
errorf(tmp);
|
||||
return -1;
|
||||
}
|
||||
ied->buf[ied->pos++] = ie;
|
||||
ied->buf[ied->pos++] = datalen;
|
||||
for (x=0;x<6;x++)
|
||||
ied->buf[ied->pos++] = eid->eid[x];
|
||||
ied->buf[ied->pos++] = protocol;
|
||||
myw = htons(flags);
|
||||
memcpy(ied->buf + ied->pos, &myw, 2);
|
||||
ied->pos += 2;
|
||||
myw = htons(weight);
|
||||
memcpy(ied->buf + ied->pos, &myw, 2);
|
||||
ied->pos += 2;
|
||||
memcpy(ied->buf + ied->pos, data, datalen-11);
|
||||
ied->pos += datalen-11;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
|
||||
{
|
||||
return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
int dundi_ie_append_int(struct dundi_ie_data *ied, unsigned char ie, unsigned int value)
|
||||
{
|
||||
unsigned int newval;
|
||||
newval = htonl(value);
|
||||
return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
|
||||
}
|
||||
|
||||
int dundi_ie_append_short(struct dundi_ie_data *ied, unsigned char ie, unsigned short value)
|
||||
{
|
||||
unsigned short newval;
|
||||
newval = htons(value);
|
||||
return dundi_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
|
||||
}
|
||||
|
||||
int dundi_ie_append_str(struct dundi_ie_data *ied, unsigned char ie, unsigned char *str)
|
||||
{
|
||||
return dundi_ie_append_raw(ied, ie, str, strlen(str));
|
||||
}
|
||||
|
||||
int dundi_ie_append_eid(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid)
|
||||
{
|
||||
return dundi_ie_append_raw(ied, ie, (unsigned char *)eid, sizeof(dundi_eid));
|
||||
}
|
||||
|
||||
int dundi_ie_append_byte(struct dundi_ie_data *ied, unsigned char ie, unsigned char dat)
|
||||
{
|
||||
return dundi_ie_append_raw(ied, ie, &dat, 1);
|
||||
}
|
||||
|
||||
int dundi_ie_append(struct dundi_ie_data *ied, unsigned char ie)
|
||||
{
|
||||
return dundi_ie_append_raw(ied, ie, NULL, 0);
|
||||
}
|
||||
|
||||
void dundi_set_output(void (*func)(const char *))
|
||||
{
|
||||
outputf = func;
|
||||
}
|
||||
|
||||
void dundi_set_error(void (*func)(const char *))
|
||||
{
|
||||
errorf = func;
|
||||
}
|
||||
|
||||
int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen)
|
||||
{
|
||||
/* Parse data into information elements */
|
||||
int len;
|
||||
int ie;
|
||||
char tmp[256];
|
||||
memset(ies, 0, (int)sizeof(struct dundi_ies));
|
||||
ies->ttl = -1;
|
||||
ies->expiration = -1;
|
||||
ies->unknowncmd = -1;
|
||||
ies->cause = -1;
|
||||
while(datalen >= 2) {
|
||||
ie = data[0];
|
||||
len = data[1];
|
||||
if (len > datalen - 2) {
|
||||
errorf("Information element length exceeds message size\n");
|
||||
return -1;
|
||||
}
|
||||
switch(ie) {
|
||||
case DUNDI_IE_EID:
|
||||
case DUNDI_IE_EID_DIRECT:
|
||||
if (len != (int)sizeof(dundi_eid)) {
|
||||
errorf("Improper entity identifer, expecting 6 bytes!\n");
|
||||
} else if (ies->eidcount < DUNDI_MAX_STACK) {
|
||||
ies->eids[ies->eidcount] = (dundi_eid *)(data + 2);
|
||||
ies->eid_direct[ies->eidcount] = (ie == DUNDI_IE_EID_DIRECT);
|
||||
ies->eidcount++;
|
||||
} else
|
||||
errorf("Too many entities in stack!\n");
|
||||
break;
|
||||
case DUNDI_IE_REQEID:
|
||||
if (len != (int)sizeof(dundi_eid)) {
|
||||
errorf("Improper requested entity identifer, expecting 6 bytes!\n");
|
||||
} else
|
||||
ies->reqeid = (dundi_eid *)(data + 2);
|
||||
break;
|
||||
case DUNDI_IE_CALLED_CONTEXT:
|
||||
ies->called_context = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_CALLED_NUMBER:
|
||||
ies->called_number = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_ANSWER:
|
||||
if (len < sizeof(struct dundi_answer)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Answer expected to be >=%d bytes long but was %d\n", (int)sizeof(struct dundi_answer), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
if (ies->anscount < DUNDI_MAX_ANSWERS)
|
||||
ies->answers[ies->anscount++]= (struct dundi_answer *)(data + 2);
|
||||
else
|
||||
errorf("Ignoring extra answers!\n");
|
||||
}
|
||||
break;
|
||||
case DUNDI_IE_TTL:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting ttl to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->ttl = ntohs(*((unsigned short *)(data + 2)));
|
||||
break;
|
||||
case DUNDI_IE_VERSION:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->version = ntohs(*((unsigned short *)(data + 2)));
|
||||
break;
|
||||
case DUNDI_IE_EXPIRATION:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->expiration = ntohs(*((unsigned short *)(data + 2)));
|
||||
break;
|
||||
case DUNDI_IE_KEYCRC32:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting expiration to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->keycrc32 = ntohl(*((unsigned int *)(data + 2)));
|
||||
break;
|
||||
case DUNDI_IE_UNKNOWN:
|
||||
if (len == 1)
|
||||
ies->unknowncmd = data[2];
|
||||
else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case DUNDI_IE_CAUSE:
|
||||
if (len >= 1) {
|
||||
ies->cause = data[2];
|
||||
ies->causestr = data + 3;
|
||||
} else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected at least one byte cause, but was %d long\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case DUNDI_IE_HINT:
|
||||
if (len >= 2) {
|
||||
ies->hint = (struct dundi_hint *)(data + 2);
|
||||
} else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected at least two byte hint, but was %d long\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case DUNDI_IE_DEPARTMENT:
|
||||
ies->q_dept = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_ORGANIZATION:
|
||||
ies->q_org = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_LOCALITY:
|
||||
ies->q_locality = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_STATE_PROV:
|
||||
ies->q_stateprov = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_COUNTRY:
|
||||
ies->q_country = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_EMAIL:
|
||||
ies->q_email = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_PHONE:
|
||||
ies->q_phone = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_IPADDR:
|
||||
ies->q_ipaddr = data + 2;
|
||||
break;
|
||||
case DUNDI_IE_ENCDATA:
|
||||
/* Recalculate len as the remainder of the message, regardless of
|
||||
theoretical length */
|
||||
len = datalen - 2;
|
||||
if ((len > 16) && !(len % 16)) {
|
||||
ies->encblock = (struct dundi_encblock *)(data + 2);
|
||||
ies->enclen = len - 16;
|
||||
} else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted data length %d\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case DUNDI_IE_SHAREDKEY:
|
||||
if (len == 128) {
|
||||
ies->encsharedkey = (unsigned char *)(data + 2);
|
||||
} else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted shared key length %d\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case DUNDI_IE_SIGNATURE:
|
||||
if (len == 128) {
|
||||
ies->encsig = (unsigned char *)(data + 2);
|
||||
} else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Invalid encrypted signature length %d\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(ie), ie, len);
|
||||
outputf(tmp);
|
||||
}
|
||||
/* Overwrite information element with 0, to null terminate previous portion */
|
||||
data[0] = 0;
|
||||
datalen -= (len + 2);
|
||||
data += (len + 2);
|
||||
}
|
||||
/* Null-terminate last field */
|
||||
*data = '\0';
|
||||
if (datalen) {
|
||||
errorf("Invalid information element contents, strange boundary\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Distributed Universal Number Discovery (DUNDi)
|
||||
*
|
||||
* Copyright (C) 2004, Digium Inc.
|
||||
*
|
||||
* Written by Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is Free Software distributed under the terms of
|
||||
* of the GNU General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _DUNDI_PARSER_H
|
||||
#define _DUNDI_PARSER_H
|
||||
|
||||
#include <asterisk/dundi.h>
|
||||
#include <asterisk/aes.h>
|
||||
|
||||
#define DUNDI_MAX_STACK 512
|
||||
#define DUNDI_MAX_ANSWERS 100
|
||||
|
||||
struct dundi_ies {
|
||||
dundi_eid *eids[DUNDI_MAX_STACK + 1];
|
||||
int eid_direct[DUNDI_MAX_STACK + 1];
|
||||
dundi_eid *reqeid;
|
||||
int eidcount;
|
||||
char *called_context;
|
||||
char *called_number;
|
||||
struct dundi_answer *answers[DUNDI_MAX_ANSWERS + 1];
|
||||
struct dundi_hint *hint;
|
||||
int anscount;
|
||||
int ttl;
|
||||
int version;
|
||||
int expiration;
|
||||
int unknowncmd;
|
||||
unsigned char *pubkey;
|
||||
int cause;
|
||||
unsigned char *q_dept;
|
||||
unsigned char *q_org;
|
||||
unsigned char *q_locality;
|
||||
unsigned char *q_stateprov;
|
||||
unsigned char *q_country;
|
||||
unsigned char *q_email;
|
||||
unsigned char *q_phone;
|
||||
unsigned char *q_ipaddr;
|
||||
unsigned char *causestr;
|
||||
unsigned char *encsharedkey;
|
||||
unsigned char *encsig;
|
||||
unsigned long keycrc32;
|
||||
struct dundi_encblock *encblock;
|
||||
int enclen;
|
||||
};
|
||||
|
||||
struct dundi_ie_data {
|
||||
int pos;
|
||||
unsigned char buf[8192];
|
||||
};
|
||||
|
||||
/* Choose a different function for output */
|
||||
extern void dundi_set_output(void (*output)(const char *data));
|
||||
/* Choose a different function for errors */
|
||||
extern void dundi_set_error(void (*output)(const char *data));
|
||||
extern void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
|
||||
|
||||
extern const char *dundi_ie2str(int ie);
|
||||
|
||||
extern int dundi_ie_append_raw(struct dundi_ie_data *ied, unsigned char ie, void *data, int datalen);
|
||||
extern int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin);
|
||||
extern int dundi_ie_append_int(struct dundi_ie_data *ied, unsigned char ie, unsigned int value);
|
||||
extern int dundi_ie_append_short(struct dundi_ie_data *ied, unsigned char ie, unsigned short value);
|
||||
extern int dundi_ie_append_str(struct dundi_ie_data *ied, unsigned char ie, unsigned char *str);
|
||||
extern int dundi_ie_append_eid(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid);
|
||||
extern int dundi_ie_append_cause(struct dundi_ie_data *ied, unsigned char ie, unsigned char cause, unsigned char *desc);
|
||||
extern int dundi_ie_append_hint(struct dundi_ie_data *ied, unsigned char ie, unsigned short flags, unsigned char *data);
|
||||
extern int dundi_ie_append_answer(struct dundi_ie_data *ied, unsigned char ie, dundi_eid *eid, unsigned char protocol, unsigned short flags, unsigned short weight, unsigned char *desc);
|
||||
extern int dundi_ie_append_encdata(struct dundi_ie_data *ied, unsigned char ie, unsigned char *iv, void *data, int datalen);
|
||||
extern int dundi_ie_append_byte(struct dundi_ie_data *ied, unsigned char ie, unsigned char dat);
|
||||
extern int dundi_ie_append(struct dundi_ie_data *ied, unsigned char ie);
|
||||
extern int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen);
|
||||
extern char *dundi_eid_to_str(char *s, int maxlen, dundi_eid *eid);
|
||||
extern char *dundi_eid_to_str_short(char *s, int maxlen, dundi_eid *eid);
|
||||
extern int dundi_str_to_eid(dundi_eid *eid, char *s);
|
||||
extern int dundi_str_short_to_eid(dundi_eid *eid, char *s);
|
||||
extern int dundi_eid_zero(dundi_eid *eid);
|
||||
extern int dundi_eid_cmp(dundi_eid *eid1, dundi_eid *eid2);
|
||||
extern char *dundi_flags2str(char *s, int maxlen, int flags);
|
||||
extern char *dundi_hint2str(char *s, int maxlen, int flags);
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue