📄 fakewap.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * fakewap.c - simulate wap clients talking directly to wap gw. * * This module can be built also in Windows where you should * add unzipped ".\wininc" to your include directories. * * The protocol: * * * A) Fakewap -> Gateway * * WTP: Invoke PDU * WSP: Connect PDU * * B) Gateway -> Fakewap * * WTP: Result PDU * WSP: ConnectReply PDU * * C) Fakewap -> Gateway * * WTP: Ack PDU * * D) Fakewap -> Gateway * * WTP: Invoke PDU * WSP: Get PDU (data: URL) * * E) Gateway -> Fakewap * * WTP: Result PDU (data: WML page) * WSP: Reply PDU * * F) Fakewap -> Gateway * * WTP: Ack PDU * * G) Fakewap -> Gateway * * WTP: Invoke PDU * WSP: Disconnect PDU * * * Packets A-C open a WAP session. Packets D-F fetch a WML page. * Packet G closes the session. * * The test terminates when all packets have been sent. * * Tid verification uses following protocol (at WTP level only): * * A) Fakewap -> Gateway * * Either WSP Connect PDU with tid_new flag set on or same PDU with a * *seriously* wrapped up tid (only WTP header affected). Seriously * means tid being out of the window: * * |----------------------------| * tid space * * |-------------| * wrapping up * tid window * * B) Gateway -> Fakewap * * Ack PDU, tid verification flag set on. * * C) Fakewap -> Gateway * * Ack PDU, tid verification flag set on (this means a positive * answer). * * Antti Saarenheimo for WapIT Ltd. */#define MAX_SEND (0)static char usage[] = "\Usage: fakewap [options] url ...\n\\n\where options are:\n\\n\-h help\n\-v verbose\n\-g hostname hostname or IP number of gateway (default: localhost)\n\-p port port number of gateway (default: 9201)\n\-m max maximum number of requests fakewap will make (default: 1)\n\-i interval interval between requests (default: 1.0 seconds)\n\-c threads number of concurrent clients simulated (default: 1)\n\-V protoversion protocol version field, as an integer (default: 0)\n\-T pdu-type PDU type, as an integer (default: 1)\n\-t tcl transaction class, as an integer (default: 2)\n\-n set tid_new flag in packets, forces gateway to flush cache\n\ (default: off)\n\-s test separation, by concatenating ack and disconnect pdus\n\ (default: off)\n\-d difference difference between successive tid numbers (default: 1)\n\-F Accept failure and continue rather than exiting\n\-w Write/print received data (experimental)\n\\n\The urls are fetched in random order.\n\";#include <errno.h>#include <ctype.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <sys/param.h>#include <math.h>#include <signal.h>#include "gwlib/gwlib.h"#define GET_WTP_PDU_TYPE(hdr) (hdr[0] >> 3)static int get_wtp_pdu_type(Octstr *hdr) { return octstr_get_char(hdr, 0) >> 3;}#define WTP_PDU_INVOKE 1#define WTP_PDU_RESULT 2#define WTP_PDU_ACK 3#define WTP_PDU_ABORT 4/*** Common parameters*/char **urls;int num_urls;Octstr *hostname = NULL;Octstr *gateway_addr = NULL;double interval = 1.0;unsigned short port = 9201;int max_send = 1;unsigned short tid_addition = 1;Mutex *mutex;int threads = 1;int num_sent = 0;time_t start_time, end_time;double totaltime = 0, besttime = 1000000L, worsttime = 0;int verbose = 0;int nofailexit = 0;int writedata = 0;int test_separation = 0;/* * PDU type, version number and transaction class are supplied by a * command line argument. WSP_Concat is a concatenation of WTP_Ack and * WSP_Disconnect PDUs. */unsigned char WSP_Connect[] = {0x06, 0x00, 0x00, 0x00, /* WSP part */ 0x01, /* PDU type */ 0x10, /* Version 1.0 */ 0x00, /* Capability length */ 0x02, /* Headers length = 2*/ /* Capabilities */ /* Headers */ 0x80, 0x80 /* Accept: *\* */ };unsigned char WSP_ConnectReply[] = {0x16, 0x80, 0x00, 0x02 };unsigned char WTP_Ack[] = {0x18, 0x00, 0x00 };unsigned char WTP_TidVe[] = {0x1C, 0x00, 0x00 };unsigned char WTP_Abort[] = {0x20, 0x00, 0x00, 0x00 };unsigned char WSP_Get[] = {0x0E, 0x00, 0x00, 0x02, 0x40 };/* This used to also expect a content-type of 0x94, but that's too difficult * to check now that Kannel does full header encoding. */unsigned char WSP_Reply[] = {0x16, 0x80, 0x00, 0x04, 0x20 };unsigned char WSP_Disconnect[] = {0x0E, 0x00, 0x00, 0x00, 0x05 };unsigned char WSP_Concat[] = {0x00, 0x03, 0x18, 0x00, 0x00, 0x05, 0x0E, 0x00, 0x00, 0x00, 0x05 };/*** In this case it does not matter what is the byte order*/#define SET_GTR( hdr ) hdr[0] |= 0x04#define SET_TID( hdr, tid) \ hdr[1] |= (0x7f & ((tid) >> 8)); \ hdr[2] = (char)(tid)#define GET_TID( hdr ) (((hdr[1] & 0x7f) << 8) + hdr[2])#define CONSTRUCT_EXPECTED_REPLY_HDR( dest, template, tid ) \ if (sizeof(dest) < sizeof(template)) panic(0,"buffer overflow.");\ memcpy( dest, template, sizeof(template));\ SET_TID( dest, tid )static void set_tid(Octstr *hdr, int tid) { int c; c = octstr_get_char(hdr, 1); c |= 0x7f & (tid >> 8); octstr_set_char(hdr, 1, c); octstr_set_char(hdr, 2, (unsigned char) tid);}/* Use this only on Invoke packets, the others have no tid_new field */static void set_tid_new(Octstr *hdr) { int c; c = octstr_get_char(hdr, 3); c |= 0x40; octstr_set_char(hdr, 3, c);}#ifndef min#define min(a,b) (a < b ? a : b)#endif/*** if -v option has been defined, function prints the trace message and** the first bytes in the message header*/static void print_msg( const char * trace, unsigned char * msg, int msg_len ) { int i; if (verbose) { mutex_lock( mutex ); printf( "%s (len %d): ", trace, msg_len ); for (i = 0; i < msg_len && i < 16; i++) printf( "%02X ", msg[i] ); printf( "\n"); mutex_unlock( mutex ); }}/*** if -w option has been defined, function prints the trace message and** the first bytes in the message header*/ static void print_data( const char * trace, unsigned char * msg, int msg_len ) { int i; if (verbose || writedata) { mutex_lock( mutex ); printf( "%s (len %d): ", trace, msg_len ); for (i = 0; i < msg_len && i < msg_len; i++) printf( "%c", isprint(msg[i]) ? msg[i] : '_'); printf( "\n"); mutex_unlock( mutex ); }}/* Choose a random message from a table of messages. */static char *choose_message(char **urls, int num_urls) { /* the following doesn't give an even distribution, but who cares */ return urls[gw_rand() % num_urls];}/* returns next tid, given current tid. Every thread has its own * port, so has its own tid space. */static unsigned short next_tid(unsigned short old_tid) { return (old_tid + tid_addition) % (1 << 15);}/*** Function stores WAP/WSP variable length integer to buffer and returns ** actual len*/static int StoreVarInt( unsigned char *buf, unsigned long varInt ){ int i, len = 1, non_zero_bits = 7; /* ** Skip all zero high bits */ while ((varInt >> non_zero_bits) != 0) { non_zero_bits += 7; len++; } /* ** Read the higest bits first. */ for (i = 0; i < len; i++) { buf[i] = ((unsigned char)(varInt >> (non_zero_bits-7)) & 0x7f) | 0x80; non_zero_bits -= 7; } buf[len-1] &= 0x7f; return len;}/*** Function length of WAP/WSP variable length integer in the buffer*/static int ReadVarIntLen( const unsigned char *buf ){ int len = 1; while (buf[len-1] & 0x80) len++; return len;}/*** Function sends message to WAP GW*/static intwap_msg_send( int fd, unsigned char * hdr, int hdr_len, unsigned short tid, int tid_new, unsigned char * data, int data_len ){ int ret; Octstr *datagram; datagram = octstr_create(""); if (hdr != NULL) octstr_append_data(datagram, hdr, hdr_len); set_tid(datagram, tid); if (get_wtp_pdu_type(datagram) == WTP_PDU_INVOKE) { /* request ack every time */ int c; c = octstr_get_char(datagram, 3); octstr_set_char(datagram, 3, c | 0x10); if (tid_new) set_tid_new(datagram); } if (data != NULL) octstr_append_data(datagram, data, data_len); #if 0 debug("fakewap", 0, "Sending WDP datagram:"); octstr_dump(datagram, 0);#endif ret = udp_sendto(fd, datagram, gateway_addr); if (ret == -1) { error(0, "Sending to socket failed"); return -1; } if (verbose) { debug("", 0, "Sent packet:"); octstr_dump(datagram, 0); } octstr_destroy(datagram); return ret;}/*** Function receives a wap wtl/wsp message. If the headers has been** given, it must match with the received message.** Return value:** > 0 => length of received data** == 0 => got acknowlengement or abort but not the expected data** < 0 => error,*/static intwap_msg_recv( int fd, const char * hdr, int hdr_len, unsigned short tid, unsigned char * data, int data_len,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -