示例#1
0
文件: lib.py 项目: skarcos/pyssimist
def diff(ref_trace, check_trace, input_format="pcapng", tshark_path="", filters={}):
    """
    Diff two pcapng or json files containing network captured data

    :param ref_trace: The first file. Considered as reference.
    :param check_trace: The second file. Checked to contain the same flow as the first file.
    :param input_format: Type of files to be checked. Can be "pcapng"  (default) or "json"
    :param tshark_path: Needed in case the input type is "pcapng" so that the files can be converted to json format
    :param filters: A list of filters to remove noise from messages.
    :return: The result of a list of checks
    """
    list1 = iter(get_msg_list_from_file(trace_file=ref_trace, tshark_path=tshark_path, input_format=input_format))
    list2 = iter(get_msg_list_from_file(trace_file=check_trace, tshark_path=tshark_path, input_format=input_format))
    if list1 is None or list2 is None:
        return None
    count = 0
    if "Call-ID" not in filters:
        filters["Call-ID"] = []
    for msg in list2:
        sip_msg = buildMessage(msg, {})
        if msg_filter(sip_msg, filters) is None:
            if sip_msg.type == "Request":
                filters["Call-ID"].append(sip_msg["Call-ID"])
            continue
        ref_msg = next(list1)
        ref_sip_msg = buildMessage(ref_msg, {})
        while msg_filter(ref_sip_msg, filters) is None:
            if ref_sip_msg.type == "Request":
                filters["Call-ID"].append(ref_sip_msg["Call-ID"])
            ref_msg = next(list1)
            ref_sip_msg = buildMessage(ref_msg, {})

        ref_msg_template = make_sip_message_template(ref_msg)
        msg_template = make_sip_message_template(msg)
        if msg != ref_msg:
            print("{:-^60}".format(" Difference found in message #{} ".format(count)))
            print("{:#^60}".format(" Reference message "))
            print(ref_msg)
            print("{:#^60}".format(" Matched message "))
            print(msg)

            print("{:#^60}".format(" Diff analysis "))
            d = Differ()
            for line in d.compare(ref_msg_template.splitlines(keepends=True),
                                  msg_template.splitlines(keepends=True)):
                print(line.strip())
            return False
        count += 1
    return True
def flow(users, pilot, param):
    parameters = copy(param)
    usera = next(users)
    parameters["userA"] = usera
    parameters["userB"] = pilot
    parameters["source_port"] = link[usera].port

    Invite = buildMessage(message["Invite_SDP_1"], parameters)
    #print(Invite)
    link[usera].send(Invite.contents())

    inBytes = link[usera].waitForData()
    inmessage = handleDA(Invite, parseBytes(inBytes), user)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="100 Trying",\
           "Sent:\n{}Received:\n{}".format(Invite,inmessage)

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="180 Ringing",\
           "A side received Trying and then :\n{}".format(inmessage)

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="200 OK",\
           "A side received Ringing and then:\n{}".format(inmessage)

    m = buildMessage(message["Ack_1"], parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    #print(m)
    link[usera].send(m.contents())

    sleep(parameters["talkDuration"])

    m = buildMessage(message["Bye_1"], parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    #print(m)
    link[usera].send(m.contents())

    inBytes = link[usera].waitForData()
    inmessage = handleDA(m, parseBytes(inBytes), user)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="200 OK",\
           "Sent:\n{}Received:\n{}".format(m,inmessage)
def flow(users, pilot):
    usera = next(users)
    data.parameters["userA"] = usera
    data.parameters["userB"] = pilot
    data.parameters["source_port"] = link[usera].port
    Invite = buildMessage(message["Invite_SDP_1"], data.parameters)
    #print(Invite)
    link[usera].send(Invite.contents())

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="100 Trying",\
           "Sent:\n{}Received:\n{}".format(Invite,inmessage)

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="180 Ringing",\
           "B side sent:\n{}but A side received:\n{}".format(Ringing,inmessage)

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="200 OK",\
           "B side got:\n{}but A side received:\n{}".format(ack,inmessage)

    data.parameters["source_port"] = link[usera].port
    m = buildMessage(message["Ack_1"], data.parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    #print(m)
    link[usera].send(m.contents())

    sleep(talkDuration)

    data.parameters["source_port"] = link[usera].port
    m = buildMessage(message["Bye_1"], data.parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    #print(m)
    link[usera].send(m.contents())

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    #print("IN:",inmessage)
    assert inmessage.type=="Response" and inmessage.status=="200 OK",\
           "Sent:\n{}Received:\n{}".format(m,inmessage)
    def send_new(self,
                 target_sip_ep=None,
                 message_string="",
                 expected_response=None,
                 ignore_messages=[]):
        """ Start a new dialog and send a message """
        if target_sip_ep:
            self.parameters["userA"] = self.number
            self.parameters["userB"] = target_sip_ep.number
        else:
            # In cases like REGISTER, there is no B-side
            # Clear parameters to avoid unexpected results
            self.parameters.pop("userA", None)
            self.parameters.pop("userB", None)

        self.start_new_dialog()

        m = buildMessage(message_string, self.parameters)
        self.link.send(m.contents())
        self.last_sent_message = m

        if expected_response:
            try:
                self.waitForMessage(expected_response, ignore_messages)
            except AssertionError:
                raise AssertionError('{}: "{}" response to "{}"\n{}'.format(
                    self.number, self.last_received_message.status,
                    self.last_sent_message.method, self.last_received_message))
示例#5
0
def Register(user):
    parameters["user"] = user
    m = buildMessage(message["Register_1"], parameters)
    print(m)
    link[user].send(m.contents())
    inBytes = link[user].waitForData()
    inmessage = parseBytes(inBytes)
    print(inmessage)
    assert inmessage.type == "Response" and inmessage.status == "200 OK"
示例#6
0
def reg_user(sip_server, register_message, expiration_in_seconds=360):
    user, address = get_user_from_message(register_message,
                                          header="Contact").split("@")
    # replacement to overcome localhost silliness
    address = address.replace("localhost", "127.0.0.1")
    sip_server.set_parameter("expires", expiration_in_seconds)
    register_200 = buildMessage(message["200_OK_1"])
    register_200.make_response_to(register_message)
    register_200["Contact"] = register_message["Contact"]
    sip_server.reply_to(register_message, register_200.contents())
    sip_server.registered_addresses[user] = address
def Register(user):
    data.parameters["user"] = user
    L = link[user]
    data.parameters["source_port"] = L.port
    m = buildMessage(message["Register_1"], data.parameters)
    #print(m)
    L.send(m.contents())
    inBytes = L.waitForData()
    inmessage = parseBytes(inBytes)
    #print(inmessage)
    assert inmessage.type == "Response" and inmessage.status == "200 OK", "{}\n{}".format(
        user, inmessage)
示例#8
0
文件: lib.py 项目: skarcos/pyssimist
def summarize_trace(filename, *tests, applications=("sip", "http", "rtp"), input_format="pcapng", tshark_path=None,
                    tshark_filter=None, delete_json=True):
    if not tshark_path and platform.system() == "Windows":
        tshark_path = r"C:\Program Files\Wireshark"
    if input_format == "json":
        with open(filename, "r") as j_file:
            j_obj = json.load(j_file)
    elif input_format == "pcapng":
        temp_file = open_cap_file(filename, tshark_path, tshark_filter)
        with open(temp_file, "r") as j_file:
            j_obj = json.load(j_file)
        if delete_json:
            os.remove(temp_file)
    else:
        print("Invalid input file type: {}. Supported formats are pcapng and json".format(input_format))
        return None
    result = {}
    for application in applications:
        result[application] = {"count": 0}
    for j_msg in j_obj:
        frame_protocols = j_msg["_source"]["layers"]["frame"]["frame.protocols"]
        if not any([application in frame_protocols for application in applications]):
            continue
        ip_layer = frame_protocols.split(":")[2]
        transport_layer = frame_protocols.split(":")[3]
        for application in applications:
            if application in j_msg["_source"]["layers"]:
                src_addr = "{:<15}:{:>5}".format(j_msg["_source"]["layers"][ip_layer][ip_layer + ".src"],
                                                 j_msg["_source"]["layers"][transport_layer][
                                                     transport_layer + ".srcport"])
                dst_addr = "{:<15}:{:>5}".format(j_msg["_source"]["layers"][ip_layer][ip_layer + ".dst"],
                                                 j_msg["_source"]["layers"][transport_layer][
                                                     transport_layer + ".dstport"])
                if application == "sip":
                    try:
                        msg_raw = assemble_message_from_json(j_msg, appl=application)
                        msg_obj = buildMessage(msg_raw)
                        msg = check_in_trace(*tests, check_trace=[msg_obj], input_format="list")
                        time_epoch = j_msg["_source"]["layers"]["frame"]["frame.time_epoch"]
                        if not msg:
                            expand = False
                        else:
                            expand = True
                        result[application].setdefault("{}:{}".format(ip_layer, transport_layer), []) \
                            .append((time_epoch, src_addr, dst_addr, msg_obj, expand))
                    except:
                        print("Unable to parse:")
                        pprint(j_msg)
                # result[application]["stream_count"] = len(result[application][ip_layer+":"+transport_layer])
                result[application]["count"] += 1

    return result
def Register(user):
    parameters["user"] = user
    L = link[user]
    parameters["source_port"] = L.port
    parameters["source_ip"] = L.ip
    parameters["dest_ip"] = L.rip
    parameters["dest_port"] = L.rport
    parameters["epid"] = util.epid(user)
    m = buildMessage(message["Register_2"], parameters)
    #print(m)
    L.send(m.contents())
    inBytes = L.waitForData()
    try:
        inmessage = handleDA(m, parseBytes(inBytes), user)
        assert inmessage.type == "Response" and inmessage.status == "200 OK", "{}\n{}".format(
            user, inmessage)
    except:
        traceback.print_exc()
 def reply(self, message_string):
     """ Send a response to a previously received message """
     if "callId" not in self.parameters or not self.parameters['callId']:
         raise Exception("Cannot reply when we are not in a dialog")
     m = buildMessage(message_string, self.parameters)
     for h in ("To", "From", "Via", "Call-ID"):
         m[h] = self.last_received_message[h]
     # do we need to set the to tag for all responses? check rfc3261
     if "tag=" not in m['To']:
         m['To'] += ";tag=" + util.randStr(8)
     if message_string.strip().startswith("SIP"):
         # Sip response. Use received CSeq
         m["CSeq"] = self.last_received_message["CSeq"]
     else:
         # This is not a response, but a new request in the same dialog, so fix the CSeq
         # TODO: fix CSeq according to RFC3261 and ACK according to section 17.1.1.3
         self.parameters["cseq"] += 1
         m["CSeq"] = "{} {}".format(self.parameters["cseq"], m.method)
     self.link.send(m.contents())
示例#11
0
def b2b_uas_establish(sip_server, invite):
    a = get_user_from_message(invite, header="Contact")
    b = get_user_from_message(invite)

    a_user, a_address = a.split("@")
    b_user = b.split("@")[0]
    b_address = sip_server.registered_addresses[b_user]
    if not sip_server.is_registered(a):
        sip_server.reply_to(invite, message["403_Forbidden"])
        return
    if not sip_server.is_registered(b):
        sip_server.reply_to(invite, message["404_Not_Found"])
        return
    sip_server.reply_to(invite, message["Trying_1"])

    sip_server.set_parameter("userB", b_user)
    sip_server.set_parameter("userA", a_user)
    invite_b = buildMessage(message["Invite_SDP_1"],
                            sip_server.sip_endpoint.parameters)
    invite_b.body = invite.body
    sip_server.send_new(b_address, b_user, invite_b.contents())

    time.sleep(0.5)
    b_ringing = sip_server.wait_for_message("180 Ringing",
                                            ignore_messages=["100 Trying"])
    leg_b_dialog = b_ringing.get_dialog()

    time.sleep(0.5)
    a_ringing = sip_server.reply_to(invite, b_ringing.contents())
    leg_a_dialog = a_ringing.get_dialog()

    time.sleep(2)
    b_ok_invite = sip_server.wait_for_message("200 OK", dialog=leg_b_dialog)
    b_ok_invite["Contact"] = invite_b["Contact"]
    sip_server.reply_to(invite, b_ok_invite.contents())

    time.sleep(0.5)
    sip_server.reply_to(b_ok_invite, message["Ack_1"])

    time.sleep(0.5)
    sip_server.wait_for_message("ACK", dialog=leg_a_dialog)
    sip_server.active_calls.append((leg_a_dialog, leg_b_dialog))
示例#12
0
    def send_new(self, target_sip_ep=None, message_string="", expected_response=None, ignore_messages=[]):
        """ Start a new dialog and send a message """
        self.parameters["userA"] = self.number
        if target_sip_ep:
            if isinstance(target_sip_ep, SipEndpoint):
                self.parameters["userB"] = target_sip_ep.number
                target_sip_ep.parameters["userB"] = self.number
            elif isinstance(target_sip_ep, str):
                self.parameters["userB"] = target_sip_ep
            else:
                raise Exception("target_sip_ep must be str or SipEndpoint, not {}".format(type(target_sip_ep)))
        else:
            # In cases like REGISTER, there is no B-side
            # Clear parameters to avoid unexpected results
            # self.parameters.pop("userA", None)
            # self.parameters.pop("userB", None)
            pass

        m = buildMessage(message_string, self.parameters)
        assert m.type == "Request", 'Tried to start a new dialog with a SIP Response'

        new_dialog = self.start_new_dialog()
        new_transaction = self.start_new_transaction(m.method)  # m should always be a request

        m.set_dialog_from(new_dialog)
        m.set_transaction_from(new_transaction)

        self.link.send(m.contents())
        self.save_message(m)

        if expected_response:
            # try:
            self.waitForMessage(message_type=expected_response, dialog=new_dialog, ignore_messages=ignore_messages)
        # except AssertionError:
        #     raise AssertionError('{}: "{}" response to "{}"\n{}'.format(self.number,
        #                                                                 self.get_last_message_in(
        #                                                                     m.get_dialog()).get_status_or_method(),
        #                                                                 m.method,
        #                                                                 m))
        return m
示例#13
0
    def reply(self, message_string, dialog=None):
        """ Send a response to a previously received message """
        if dialog:
            dialog = self.set_dialog(dialog)
        else:
            dialog = self.current_dialog

        if "callId" not in self.parameters or not self.parameters['callId']:
            raise Exception("Cannot reply when we are not in a dialog")

        m = buildMessage(message_string, self.parameters)

        try:
            previous_message = self.get_last_message_in(dialog)
            m.make_response_to(previous_message)
            self.update_to_tag(m.get_dialog())
        except:
            # New dialog, same call-id, eg NOTIFY after Keyset SUBSCRIBE.
            # Must be a SIP Response
            assert m.type == "Request", \
                "Attempted to send a {} response in a new dialog".format(m.get_status_or_method())
            m.set_dialog_from(dialog)

        if m.type == "Request":
            # This is a new request in the same dialog, so fix the CSeq
            # m.increase_cseq()
            self.start_new_transaction(m.method)
        self.save_message(m)

        m.set_transaction_from(self.current_transaction)

        # TODO: fix CSeq according to RFC3261 and ACK according to section 17.1.1.3
        #            self.parameters["cseq"] += 1
        #            m["CSeq"] = "{} {}".format(self.parameters["cseq"], m.method)
        self.link.send(m.contents())
        return m
def WaitForCall(user):
    " Start an agent. Wait for INVITE messages"
    L = link[user]
    expectedMessage = "INVITE"
    while L:
        # Will stop when we set the link of the user to None
        try:
            inBytes = L.waitForData()
            inmessage = parseBytes(inBytes)
            assert inmessage.type==expectedEvent,\
                    "User {} expected {} but got {}".format(user,expectedEvent,inmessage.event)
            #print("User:{} received {}".format(user,inmessage))
        except timeout:
            pass
        finally:
            L = link[user]
    try:
        data.parameters["userB"] = user
        data.parameters["source_port"] = link[user].port
        m = buildMessage(message["Trying_1"], data.parameters)
        for h in ("To", "From", "CSeq", "Via", "Call-ID"):
            m[h] = inmessageb[h]
        #print(m)
        link[user].send(m.contents())

        data.parameters["source_port"] = link[user].port
        Ringing = buildMessage(message["Ringing_1"], data.parameters)
        for h in ("To", "From", "CSeq", "Via", "Call-ID"):
            Ringing[h] = inmessageb[h]
        toTag = ";tag=" + util.randStr(8)
        Ringing["To"] = Ringing["To"] + toTag
        #print(Ringing)
        link[user].send(Ringing.contents())

        data.parameters["source_port"] = link[user].port
        m = buildMessage(message["200_OK_SDP_1"], data.parameters)
        for h in ("To", "From", "CSeq", "Via", "Call-ID"):
            m[h] = Ringing[h]
        m["To"] = m["To"] + toTag
        #print(m)
        link[user].send(m.contents())

        inBytes = link[user].waitForData()
        ack = parseBytes(inBytes)
        #print("IN:",ack)
        assert ack.type=="Request" and ack.method=="ACK",\
               "Sent:\n{}Received:\n{}".format(m,ack)

        inBytes = link[user].waitForData()
        Bye = parseBytes(inBytes)
        #print("IN:",Bye)
        assert Bye.type=="Request" and Bye.method=="BYE",\
               "A side sent:\n{}B side received:\n{}".format(m,inmessage)

        data.parameters["source_port"] = link[user].port
        m = buildMessage(message["200_OK_1"], data.parameters)
        for h in ("To", "From", "CSeq", "Via", "Call-ID"):
            m[h] = Bye[h]
        #print(m)
        link[user].send(m.contents())

    finally:
        # When call is done wait for next call
        AgentState(user)
示例#15
0
from tshark_tools.lib import get_from_cap_file
from sip.SipParser import buildMessage

L = get_from_cap_file("only_sip.pcap",
                      tshark_path=r"c:\Program Files\Wireshark")

calls = []

for message in L:
    m = buildMessage(message, {})

    if m.get_status_or_method() == "INVITE":
        calls.append(m.header["Call-ID"])
    elif m["Call-ID"] in calls and m.type == "Response":
        assert m.status in ("200 OK", "100 Trying", "180 Ringing"), \
            "Validation error: Received:\n{}".format(m.contents())
示例#16
0
def flow(users):
    usera = next(users)
    userb = next(users)
    parameters["userA"] = usera
    parameters["userB"] = userb
    serverThreads.append(
        util.serverThread(WaitForCstaEvents, usera, assertLeg="A"))
    serverThreads.append(
        util.serverThread(WaitForCstaEvents, userb, assertLeg="B"))
    parameters["source_port"] = link[usera].port
    Invite = buildMessage(message["Invite_SDP_1"], parameters)
    # print(Invite)
    link[usera].send(Invite.contents())

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    # print("IN:",inmessage)
    assert inmessage.type == "Response" and inmessage.status == "100 Trying", \
        "Sent:\n{}Received:\n{}".format(Invite, inmessage)

    #    inBytes=linkCsta[usera].waitForData()
    #    cstaevent=parseBytes_csta(inBytes)
    #    assert cstaevent.event=="ServiceInitiated", "Expected:{}  Received:{}".format("ServiceInitiated",str(cstaevent))

    inBytes = link[userb].waitForData()
    inmessageb = parseBytes(inBytes)
    # print("IN:",inmessageb)
    assert inmessageb.type == "Request" and inmessageb.method == "INVITE", \
        "A side sent:\n{}and got Trying, but B side received:\n{}".format(Invite, inmessage)

    parameters["source_port"] = link[userb].port
    m = buildMessage(message["Trying_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        m[h] = inmessageb[h]
    # print(m)
    link[userb].send(m.contents())

    parameters["source_port"] = link[userb].port
    Ringing = buildMessage(message["Ringing_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        Ringing[h] = inmessageb[h]
    toTag = ";tag=" + util.randStr(8)
    Ringing["To"] = Ringing["To"] + toTag
    # print(Ringing)
    link[userb].send(Ringing.contents())

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    # print("IN:",inmessage)
    assert inmessage.type == "Response" and inmessage.status == "180 Ringing", \
        "B side sent:\n{}but A side received:\n{}".format(Ringing, inmessage)

    parameters["source_port"] = link[userb].port
    m = buildMessage(message["200_OK_SDP_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        m[h] = Ringing[h]
    m["To"] = m["To"] + toTag
    # print(m)
    link[userb].send(m.contents())

    inBytes = link[userb].waitForData()
    ack = parseBytes(inBytes)
    # print("IN:",ack)
    assert ack.type == "Request" and ack.method == "ACK", \
        "Sent:\n{}Received:\n{}".format(m, ack)

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    # print("IN:",inmessage)
    assert inmessage.type == "Response" and inmessage.status == "200 OK", \
        "B side got:\n{}but A side received:\n{}".format(ack, inmessage)

    parameters["source_port"] = link[usera].port
    m = buildMessage(message["Ack_1"], parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    # print(m)
    link[usera].send(m.contents())

    sleep(talkDuration)

    parameters["source_port"] = link[usera].port
    m = buildMessage(message["Bye_1"], parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    # print(m)
    link[usera].send(m.contents())

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    # print("IN:",inmessage)
    assert inmessage.type == "Response" and inmessage.status == "200 OK", \
        "Sent:\n{}Received:\n{}".format(m, inmessage)

    inBytes = link[userb].waitForData()
    Bye = parseBytes(inBytes)
    # print("IN:",Bye)
    assert Bye.type == "Request" and Bye.method == "BYE", \
        "A side sent:\n{}B side received:\n{}".format(m, inmessage)

    parameters["source_port"] = link[userb].port
    m = buildMessage(message["200_OK_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        m[h] = Bye[h]
    # print(m)
    link[userb].send(m.contents())
def WaitForCall(user, param):
    " Start an agent. Wait for INVITE messages"
    parameters = copy(param)
    parameters["number"] = 0
    L = link[user]
    expectedMessage = "INVITE"
    while L:
        # Will stop when we set the link of the user to None
        try:
            inBytes = L.waitForData()
            invite = parseBytes(inBytes)
            assert invite.type=="Request" and invite.method==expectedMessage,\
                    "User {} expected {} but got:\n{}".format(user,expectedMessage,invite)
            #print("User:{} received {}".format(user,inmessage))
            break
        except timeout:
            pass
        finally:
            L = link[user]
    if not L:
        return
    try:
        parameters["userB"] = user
        parameters["source_port"] = link[user].port
        m = buildMessage(message["Trying_1"], parameters)
        for h in ("To", "From", "CSeq", "Via", "Call-ID"):
            m[h] = invite[h]
        #print(m)
        link[user].send(m.contents())

        Ringing = buildMessage(message["Ringing_1"], parameters)
        for h in ("To", "From", "CSeq", "Via", "Call-ID"):
            Ringing[h] = invite[h]
        for h in ("Allow", "Allow-Events", "X-Siemens-Call-Type"):
            if h in invite.headers:
                Ringing[h] = invite[h]
        toTag = ";tag=" + util.randStr(8)
        Ringing["To"] = Ringing["To"] + toTag
        #print(Ringing)
        link[user].send(Ringing.contents())

        sleep(0.5)

        m = buildMessage(message["200_OK_SDP_1"], parameters)
        # Preserve Content-Length
        bkp = m["Content-Length"]
        for h in Ringing.headers:  #("To", "From", "CSeq","Via","Call-ID","Contact"):
            m[h] = Ringing[h]
        m["Content-Length"] = bkp
        link[user].send(m.contents())

        inBytes = link[user].waitForData()
        ack = parseBytes(inBytes)
        #print("IN:",ack)
        assert ack.type=="Request" and ack.method=="ACK",\
               "Sent:\n{}Received:\n{}".format(m,ack)

        nobye = True
        acceptable = ("BYE", "UPDATE")
        while nobye:
            inBytes = link[user].waitForData(2 * parameters["talkDuration"])
            inmessage = parseBytes(inBytes)
            nobye = not (inmessage.type == "Request"
                         and inmessage.method == "BYE")
            assert inmessage.type=="Request" and inmessage.method in acceptable,\
                   "Expected one of {} but received :\n{}".format(str(acceptable),inmessage)
            m = buildMessage(message["200_OK_1"], parameters)
            for h in ("To", "From", "CSeq", "Via", "Call-ID"):
                m[h] = inmessage[h]
            #print(m)
            link[user].send(m.contents())

    except:
        traceback.print_exc()
    finally:
        # When call is done wait for next call
        del parameters
        WaitForCall(user, param)
示例#18
0
def flow():
    parameters["userA"] = usera
    parameters["userB"] = userb
    parameters["expires"] = "0"

    Invite = buildMessage(message["Invite_SDP_1"], parameters)
    print(Invite)
    link[usera].send(Invite.contents())
    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    print("IN:", inmessage)
    assert inmessage.type == "Response" and inmessage.status == "100 Trying"

    inBytes = link[userb].waitForData()
    inmessageb = parseBytes(inBytes)
    print("IN:", inmessageb)
    assert inmessageb.type == "Request" and inmessageb.method == "INVITE"

    parameters["callId"] = inmessage["Call-ID"]
    m = buildMessage(message["Trying_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        m[h] = inmessageb[h]
    print(m)
    link[userb].send(m.contents())

    Ringing = buildMessage(message["Ringing_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        Ringing[h] = inmessageb[h]
    toTag = ";tag=" + util.randStr(8)
    Ringing["To"] = Ringing["To"] + toTag
    print(Ringing)
    link[userb].send(Ringing.contents())

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    print("IN:", inmessage)
    assert inmessage.type == "Response" and inmessage.status == "180 Ringing"

    m = buildMessage(message["200_OK_SDP_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        m[h] = Ringing[h]
    m["To"] = m["To"] + toTag
    print(m)
    link[userb].send(m.contents())

    inBytes = link[userb].waitForData()
    inmessage = parseBytes(inBytes)
    print("IN:", inmessage)
    assert inmessage.type == "Request" and inmessage.method == "ACK"

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    print("IN:", inmessage)
    assert inmessage.type == "Response" and inmessage.status == "200 OK"

    m = buildMessage(message["Ack_1"], parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    print(m)
    link[usera].send(m.contents())

    sleep(talkDuration)

    m = buildMessage(message["Bye_1"], parameters)
    for h in ("To", "From", "Call-ID"):
        m[h] = inmessage[h]
    print(m)
    link[usera].send(m.contents())

    inBytes = link[usera].waitForData()
    inmessage = parseBytes(inBytes)
    print("IN:", inmessage)
    assert inmessage.type == "Response" and inmessage.status == "200 OK"

    inBytes = link[userb].waitForData()
    Bye = parseBytes(inBytes)
    print("IN:", Bye)
    assert Bye.type == "Request" and Bye.method == "BYE"

    m = buildMessage(message["200_OK_1"], parameters)
    for h in ("To", "From", "CSeq", "Via", "Call-ID"):
        m[h] = Bye[h]
    print(m)
    link[userb].send(m.contents())
示例#19
0
文件: lib.py 项目: skarcos/pyssimist
def check_in_trace(*conditions_list, check_trace, input_format="pcapng", tshark_path=""):
    """
    Look in the given trace file for a Message that matches the given conditions
    :param conditions_list: A list of dictionaries containing the conditions that a message in the trace should match.
                        Best described by an example:
           {"Message": "INVITE",                <- Message Req URI/Status Line should contain this string (re supported)
            "Headers": {"CSeq": "INVITE",       <- Message Header CSeq must contain this string (re)
                        "Supported": "timer"},  <- Message Header Supported must contain this string (re)
            "sdp": {"any": "PMCA",              <- Message sdp body must contain this text anywhere
                    "a_line": "PMCU",           <- Message sdp body must contain this text in an (a) line (re)
                    "o_line": "IP4"}            <- Message sdp body must contain this text in an (o) line
           "xml":  {"any": "ns:recording",      <- Message xml body must contain this text anywhere
                    "label tag": "audio",       <- Message xml body must contain this text in an a "label" tag
                    "label aor attr": "911@"}   <- Message xml body must contain this text in an "aor" attribute of
                                                    a "label" tag
            }
    :param check_trace: The trace containing the network capture under test
    :param input_format: Type of files to be checked. Can be "pcapng"  (default) or "json"
    :param tshark_path: Needed in case the input type is "pcapng" so that the files can be converted to json format
    :return:
    """
    result = []
    if input_format == "list":
        msg_list = check_trace
    else:
        msg_list = get_msg_list_from_file(check_trace, input_format=input_format, tshark_path=tshark_path)
    if not conditions_list:
        return msg_list
    for conditions in conditions_list:
        for msg_str in msg_list:
            try:
                if isinstance(msg_str, SipMessage):
                    msg = msg_str
                else:
                    msg = buildMessage(msg_str)
            except:
                print("Failed to parse", msg_str)
                raise
            match = True
            for check in conditions:
                if check == "Message":
                    if not re.search(conditions["Message"], msg.get_status_or_method(), re.IGNORECASE):
                        match = False
                        continue
                elif check == "Headers":
                    for header in conditions["Headers"]:
                        if header not in msg.headers:
                            match = False
                            continue
                        elif not re.search(conditions["Headers"][header], msg[header], re.IGNORECASE):
                            match = False
                            continue
                elif check == "sdp":
                    for sdpline in conditions["sdp"]:
                        if sdpline == "any":
                            if not re.search(conditions["sdp"]["any"], msg.body, re.IGNORECASE):
                                match = False
                                continue
                        elif sdpline.endswith("_line"):
                            line_type = sdpline[0]
                            if not re.search(line_type + "=.*" + conditions["sdp"][sdpline], msg.body, re.IGNORECASE):
                                match = False
                                continue

                elif check == "xml":
                    if "<?xml" not in msg.body:
                        match = False
                        continue
                    xml_part_of_body = "<?xml" + msg.body.split("<?xml")[1].split("\r\n\r\n")[0]
                    xml_body_obj = XmlBody(xml_part_of_body)
                    for xmlelement in conditions["xml"]:
                        if xmlelement == "any":
                            if not re.search(conditions["xml"]["any"], msg.body, re.IGNORECASE):
                                match = False
                                continue
                        elif xmlelement.endswith(" tag"):
                            xml_tag = xmlelement.split(" ")[0]
                            all_tags = xml_body_obj.get_all(xml_tag)
                            if not all_tags:
                                match = False
                                continue
                            elif not any(re.search(conditions["xml"][xmlelement], tag.text, re.IGNORECASE)
                                         for tag in all_tags):
                                match = False
                                continue
                        elif xmlelement.endswith(" attr"):
                            xml_tag = xmlelement.split(" ")[0]
                            xml_attr = xmlelement.split(" ")[1]
                            all_tags = xml_body_obj.get_all(xml_tag)
                            if not all_tags:
                                match = False
                                continue
                            elif not any(re.search(conditions["xml"][xmlelement], tag.get(xml_attr), re.IGNORECASE)
                                         for tag in all_tags
                                         if tag.get(xml_attr) is not None):
                                match = False
                                continue
                else:
                    print("Unsupported check", check)
                    raise

            if match:
                result.append(msg)
                break
    return result
示例#20
0
 def notify_ok(self, inmessage):
     notify_response = buildMessage(message["200_OK_Notify"])
     notify_response.make_response_to(inmessage)
     notify_response["Contact"] = inmessage["Contact"]
     self.reply_to(inmessage, notify_response.contents())