📄 wsp.c
字号:
/*Copyright (c) 2002-2003 Nicolas Jombart - HSCRedistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare 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 name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIESOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUTNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OFTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*//* $Id: wsp.c,v 1.14 2004/09/08 09:33:56 jombart Exp $ */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <unistd.h>#include <netdb.h>#include "wspp.h"/* * WSP routine * compute the WSP packet */char *wsp(request *req, int *len) {char *packet;char *header;int c, i;char *str, *tmp, *bra, *brb;char ua[] = DEFAULT_UA;int pos, headerlen;char content_type = 0; /* Encode headers */ headerlen = WSP_HEADER_LEN + strlen(ua); /* If we code headers in textual:textual, buffer is big enough */ if(req->headers) headerlen += strlen(req->headers); if((header = (char *) malloc(headerlen)) < 0) return NULL; /* FIXME : how to deal with User-Agent ? specific applications requires to have a mobile phone UA to run... */ header[0] = USER_AGENT; pos = 1; for(i = 0; i < strlen(ua); i++) header[pos++] = ua[i]; header[pos++] = '\0'; /* custom headers */ if(req->headers) { for (str = strtok_r(req->headers, (char *)"\n", &bra); str; str = strtok_r(NULL, (char *)"\n", &bra)) { c = headercode(str); if(c == 0x7f) continue; /* header not supported : Skipped */ header[pos++] = c + 0x80; for (i=0; str[i] != ' '; i++); i++; /* put i in position */ /* special encoding of known parameters */ if(c == 0x2e) { /* content-disposition */ header[pos++] = 128; /* 128 in any case but attachment */ if(!strncasecmp(str+i, "attachment", 10)) header[pos-1] = 129; } else if((c == 0x00) ) { /* accept */ --pos; /* since it will be rewritten */ for(tmp = strtok_r(str+i, (char *)",", &brb); tmp; tmp = strtok_r(NULL, (char *)",", &brb)) { header[pos++] = c | 0x80; while(tmp[0] == ' ') tmp++; header[pos++] = from_ctype(tmp) | 0x80; /* well-known value */ if((header[pos-1] & 0x7f) == 0x7f) pos -= 2; /* cancel if unknown */ } } else if(c == 0x11) { /* Content-type : we need at the top with POST */ content_type = from_ctype(str+i); --pos; } else { /* textual */ for (; str[i]; i++) header[pos++] = str[i]; header[pos++] = '\0'; } } } headerlen = pos; /* compute packet */ if((packet = (char *) malloc(headerlen + strlen(ua) + strlen(req->uri) + req->content_length)) < 0 ) return NULL; packet[0] = 0x1F; /* TID : FIXME */ packet[1] = (char) req->method; /* PDU type */ pos = 2; /* URI Length : uintvar */ { unsigned char enc[6]; if(uintvar(enc, strlen(req->uri)) == 0) { printf("Problem encoding URI length.\n"); return NULL; } for(i = 0; enc[i]; i++) packet[pos++] = enc[i]; } if(req->method == WSP_POST) { /* POST PDU needs Header length */ unsigned char enc[6]; headerlen++; /* + content-type */ if(uintvar(enc, headerlen) == 0) { /* FIXME : needs content-type */ printf("Problem encoding header length.\n"); return NULL; } for(i = 0; enc[i]; i++) packet[pos++] = enc[i]; } /* URI */ for(i=0; i < strlen(req->uri); i++) packet[pos++] = req->uri[i]; if(req->method == WSP_POST) { /* POST PDU needs Content-Type */ packet[pos++] = content_type | 0x80; } /* headers */ for(i = pos, c = 0; (i-pos) < headerlen; i++) packet[i] = header[c++]; pos += headerlen; /* data if any */ if((req->content_length) > 0 && (req->method == WSP_POST)) { --pos; /* XXX */ for(i = 0; i < req->content_length; i++) packet[pos++] = *(req->data++); } *len = pos; return packet;}/* * do_wap routine * send the WSP packet to the given gateway, on the given port * and send back the response * returns received bytes */int do_wap(const char *resp, char *packet, int len, char *gwaddr, int gwport) {struct in_addr gateway;struct hostent *name;struct sockaddr_in gw_addr;int cli_sd;int received;char buffer[MAX_RESPONSE]; /* get hostname */ name = gethostbyname(gwaddr); memcpy(&gateway.s_addr, name->h_addr_list[0], 4); cli_sd = socket(PF_INET, SOCK_DGRAM, 0); if(cli_sd < 0) { perror("socket"); return -1; } /* socket stuff */ memset(&gw_addr, 0, sizeof(gw_addr)); gw_addr.sin_family = AF_INET; gw_addr.sin_addr.s_addr = gateway.s_addr; gw_addr.sin_port = htons(gwport); if( connect(cli_sd, (struct sockaddr *) &gw_addr, sizeof(gw_addr)) == 0) { if(send(cli_sd, packet, len, 0) < 0) { perror("send"); return -1; }#ifdef DEBUG printf("Sent !\n");#endif received = recv(cli_sd, buffer, MAX_RESPONSE, 0); if(received < 0) { perror("recv"); return -1; }#ifdef DEBUG printf("%d bytes received from gateway (%s).\n", received, inet_ntoa(gw_addr.sin_addr));#endif memcpy((char *)resp, buffer, received); return received; close(cli_sd); } else { return -1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -