123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- /*
- * This file is part of the Sofia-SIP package
- *
- * Copyright (C) 2005 Nokia Corporation.
- *
- * Contact: Pekka Pessi <pekka.pessi@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
- /**@SIP_PARSER
- *
- * @file test_sip_msg.c Simple SIP message parser/printer tester.
- *
- * @author Pekka Pessi <Pekka.Pessi@nokia.com>.
- *
- * @date Created: Fri Feb 18 10:25:08 2000 ppessi
- */
- #include "config.h"
- /* Avoid casting sip_t to msg_pub_t and sip_header_t to msg_header_t */
- #define MSG_PUB_T struct sip_s
- #define MSG_HDR_T union sip_header_u
- #include "sofia-sip/sip_parser.h"
- #include "sofia-sip/msg_mclass.h"
- #include "sofia-sip/msg_mclass_hash.h"
- #include <sofia-sip/sip_header.h>
- #include <sofia-sip/sip_util.h>
- #include <sofia-sip/msg_addr.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <assert.h>
- int diff(const char *olds, const char *news, int *linep, int *pos)
- {
- const char *o, *n;
- *linep = 0;
- for (o = olds, n = news; *o && *n && *o == *n ; o++, n++) {
- if (*o == '\n') ++*linep;
- }
- *pos = o - olds;
- return *o != *n;
- }
- int test_msg_class(msg_mclass_t const *mc)
- {
- int i, j, N;
- N = mc->mc_hash_size;
- /* Check parser table sanity */
- for (i = 0; i < N; i++) {
- /* Verify each header entry */
- msg_hclass_t *hc = mc->mc_hash[i].hr_class;
- if (hc == NULL)
- continue;
- /* Short form */
- if (hc->hc_short[0])
- assert(mc->mc_short[hc->hc_short[0] - 'a'].hr_class == hc);
- /* Long form */
- for (j = MC_HASH(hc->hc_name, N); j != i; j = (j + 1) % N)
- assert(mc->mc_hash[j].hr_class);
- }
- return 0;
- }
- char * url_print(url_t *url, char buf[1024])
- {
- url_e(buf, 1024, url);
- return buf;
- }
- void print_contact(FILE *f, sip_contact_t *m)
- {
- char const * const *p;
- char buf[1024];
- const char *sep = "\tContact: ";
- for (;m; m = m->m_next) {
- int quoted_url = 0;
- fputs(sep, f); sep = ", ";
- if (m->m_display) {
- quoted_url = 1;
- fprintf(f, "\"%s\" <", m->m_display);
- }
- url_print(m->m_url, buf);
- if (!quoted_url && strpbrk(buf, ",;?")) {
- fputs("<", f);
- }
- fputs(buf, f);
- if (quoted_url) fputs(">", f);
- if (m->m_params)
- for (p = m->m_params; *p; p++)
- fprintf(f, " ;%s", *p);
- if (m->m_comment)
- fprintf(f, " (%s)", m->m_comment);
- }
- fputs("\n", f);
- }
- void print_via(FILE *f, sip_via_t *v)
- {
- char const * const *p;
- char const * sep = "\tVia: ";
- for (;v; v = v->v_next) {
- fputs(sep, f); sep = ", ";
- fprintf(f, "%s %s", v->v_protocol, v->v_host);
- if (v->v_port)
- fprintf(f, ":%s", v->v_port);
- if (v->v_params)
- for (p = v->v_params; *p; p++)
- fprintf(f, " ;%s", *p);
- if (v->v_comment)
- fprintf(f, " (%s)", v->v_comment);
- }
- fputs("\n", f);
- }
- int main(int argc, char *argv[])
- {
- char urlbuf[1024];
- size_t n;
- int m, tcp;
- sip_t *sip;
- int exitcode = 0;
- msg_mclass_t const *sip_mclass = sip_default_mclass();
- msg_t *msg = msg_create(sip_mclass, MSG_FLG_EXTRACT_COPY);
- msg_iovec_t iovec[1];
- tcp = argv[1] && strcmp(argv[1], "-t") == 0;
- test_msg_class(sip_mclass);
- for (n = 0, m = 0;;) {
- if (msg_recv_iovec(msg, iovec, 1, 1, 0) < 0) {
- perror("msg_recv_iovec");
- exit(1);
- }
- assert(iovec->mv_len >= 1);
- n = read(0, iovec->mv_base, 1);
- if (n < 0) {
- perror("test_sip_msg read");
- exit(1);
- }
- msg_recv_commit(msg, n, n == 0);
- if (tcp)
- m = msg_extract(msg);
- if (n == 0 || m < 0)
- break;
- }
- if (!tcp)
- m = msg_extract(msg);
- sip = msg_object(msg);
- if (sip)
- fprintf(stdout, "sip flags = %x\n", sip->sip_flags);
- if (m < 0) {
- fprintf(stderr, "test_sip_msg: parsing error ("MOD_ZD")\n", n);
- exit(1);
- }
- if (sip->sip_flags & MSG_FLG_TRUNC) {
- fprintf(stderr, "test_sip_msg: message truncated\n");
- exit(1);
- }
- if (msg_next(msg)) {
- fprintf(stderr, "test_sip_msg: stuff after message\n");
- exit(1);
- }
- #if 0
- fprintf(stderr, "test_sip_msg: %d headers (%d short ones), %d unknown\n",
- msg->mh_n_headers, msg->mh_n_short, msg->mh_n_unknown);
- if (msg->mh_payload) {
- fprintf(stderr, "\twith payload of %d bytes\n",
- msg->mh_payload->pl_len);
- }
- #endif
- if (MSG_HAS_ERROR(sip->sip_flags) || sip->sip_error) {
- fprintf(stderr, "test_sip_msg: parsing error\n");
- exit(1);
- }
- else if (sip_sanity_check(sip) < 0) {
- fprintf(stderr, "test_sip_msg: message failed sanity check\n");
- exit(1);
- }
- if (sip->sip_request) {
- fprintf(stdout, "\trequest %s (%d) %s %s\n",
- sip->sip_request->rq_method_name,
- sip->sip_request->rq_method,
- url_print(sip->sip_request->rq_url, urlbuf),
- sip->sip_request->rq_version);
- if (sip->sip_request->rq_url->url_type == url_unknown) {
- exitcode = 1;
- fprintf(stderr, "test_sip_msg: invalid request URI\n");
- }
- }
- if (sip->sip_status)
- fprintf(stdout, "\tstatus %s %03d %s\n",
- sip->sip_status->st_version,
- sip->sip_status->st_status,
- sip->sip_status->st_phrase);
- if (sip->sip_cseq)
- fprintf(stdout, "\tCSeq: %u %s (%d)\n",
- sip->sip_cseq->cs_seq,
- sip->sip_cseq->cs_method_name,
- sip->sip_cseq->cs_method);
- if (sip->sip_call_id)
- fprintf(stdout, "\tCall-ID: %s (%x)\n",
- sip->sip_call_id->i_id,
- sip->sip_call_id->i_hash);
- if (sip->sip_from)
- fprintf(stdout, "\tFrom: %s@%s%s%s\n",
- sip->sip_from->a_user ? sip->sip_from->a_user : "[nobody]",
- sip->sip_from->a_host ? sip->sip_from->a_host : "[nowhere]",
- sip->sip_from->a_tag ? " ;tag=" : "",
- sip->sip_from->a_tag ? sip->sip_from->a_tag : "");
- if (sip->sip_to)
- fprintf(stdout, "\tTo: %s@%s%s%s\n",
- sip->sip_to->a_user ? sip->sip_to->a_user : "[nobody]",
- sip->sip_to->a_host ? sip->sip_to->a_host : "[nowhere]",
- sip->sip_to->a_tag ? " ;tag=" : "",
- sip->sip_to->a_tag ? sip->sip_to->a_tag : "");
- if (sip->sip_contact)
- print_contact(stdout, sip->sip_contact);
- if (sip->sip_via)
- print_via(stdout, sip->sip_via);
- if (sip->sip_content_length) {
- fprintf(stdout, "\tcontent length %u\n",
- sip->sip_content_length->l_length);
- }
- if (msg_next(msg)) {
- fprintf(stderr, "test_sip_msg: extra stuff after valid message\n");
- exit(1);
- }
- return exitcode;
- }
|