~ubuntu-branches/ubuntu/raring/maradns/raring

« back to all changes in this revision

Viewing changes to deadwood-2.4.10/sqa/sqa_tcp_buffering_2/show_packet_stdout.c

  • Committer: Bazaar Package Importer
  • Author(s): Nicholas Bamber
  • Date: 2011-02-04 16:26:50 UTC
  • mfrom: (1.1.15 upstream) (10.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20110204162650-3gsrxedcsbp8vkeq
Tags: 1.4.06-1
* New maintainer (Closes: #610842)
* New upstream version
* Upped standards version to 3.9.1 - no changes
* Changed to '3.0 (quilt)' format
* Rewrote debian/rules and added patches to not change source code
* Resolved python dependencies
* Refreshed copyright to DEP-5 standard
* Put 'set -e' in maintainer scripts
* Added patch to fix spelling mistakes
* Tightened up installation of binaries, examples, docs and man pages
* Added patch to improve readability of man pages
* Registered tutorial HTML with doc-base
* TODO.Debian: Added plan for future versions 
* Added extract of bug report about binding to 0.0.0.0
  to doc-base. (Closes: #486497)
* Install resolvconf-script to examples, cf. #608946
* Install zoneserver.init to examples, cf. #582069

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2009 Sam Trenholme
2
 
 *
3
 
 * TERMS
4
 
 *
5
 
 * Redistribution and use in source and binary forms, with or without
6
 
 * modification, are permitted provided that the following conditions
7
 
 * are met:
8
 
 *
9
 
 * 1. Redistributions of source code must retain the above copyright
10
 
 *    notice, this list of conditions and the following disclaimer.
11
 
 * 2. Redistributions in binary form must reproduce the above copyright
12
 
 *    notice, this list of conditions and the following disclaimer in the
13
 
 *    documentation and/or other materials provided with the distribution.
14
 
 *
15
 
 * This software is provided 'as is' with no guarantees of correctness or
16
 
 * fitness for purpose.
17
 
 */
18
 
 
19
 
/* This is a simple DNS-over-TCP server that reads a DNS packet over
20
 
 * port 53 TCP, then outputs that packet on the standard input.  Then
21
 
 * the program reads standard input and outputs the DNS packet on
22
 
 * standard input */
23
 
 
24
 
#include <stdint.h>
25
 
#include <stdlib.h>
26
 
#include <string.h>
27
 
#include <stdio.h>
28
 
#include <sys/socket.h>
29
 
#include <arpa/inet.h>
30
 
#include <netinet/in.h>
31
 
#include <unistd.h>
32
 
 
33
 
/* We use a special SOCKET type for easier Windows porting */
34
 
#define SOCKET int
35
 
 
36
 
/* Get port: Get a port locally and return the socket the port is on */
37
 
SOCKET get_port(uint32_t ip, struct sockaddr_in *dns) {
38
 
        SOCKET sock;
39
 
        int len_inet;
40
 
 
41
 
        /* Bind to port 53 */
42
 
        sock = socket(AF_INET,SOCK_STREAM,0);
43
 
        if(sock == -1) {
44
 
                perror("socket error");
45
 
                exit(0);
46
 
        }
47
 
        memset(dns,0,sizeof(struct sockaddr_in));
48
 
        dns->sin_family = AF_INET;
49
 
        dns->sin_port = htons(53);
50
 
        dns->sin_addr.s_addr = ip;
51
 
        if(dns->sin_addr.s_addr == INADDR_NONE) {
52
 
                perror("Problem with bind");
53
 
                exit(0);
54
 
        }
55
 
        len_inet = sizeof(struct sockaddr_in);
56
 
        if(bind(sock,(struct sockaddr *)dns,len_inet) == -1) {
57
 
                perror("bind error");
58
 
                exit(0);
59
 
        }
60
 
 
61
 
        /* Linux kernel bug */
62
 
        /* fcntl(sock, F_SETFL, O_NONBLOCK); */
63
 
 
64
 
        return sock;
65
 
}
66
 
 
67
 
#define calc_dns_len(a) ((a[0] & 0xff) << 8) | (a[1] & 0xff)
68
 
 
69
 
/* Get a single nibble from stdin in hex */
70
 
int8_t get_nibble() {
71
 
        char nib;
72
 
 
73
 
        while((nib = (getc(stdin)))) {
74
 
 
75
 
                /* We allow pauses to test TCP buffering */
76
 
                if(nib == '-') {
77
 
                        sleep(1);
78
 
                        return -2;
79
 
                /* Hex-ASCII to bin conversion */
80
 
                } else if(nib >= '0' && nib <= '9') {
81
 
                        return nib - '0';
82
 
                } else if(nib >= 'A' && nib <= 'F') {
83
 
                        return nib - 'A' + 10;
84
 
                } else if(nib >= 'a' && nib <= 'f') {
85
 
                        return nib - 'a' + 10;
86
 
                }
87
 
        }
88
 
        return -1;
89
 
 
90
 
}
91
 
 
92
 
/* Get a single byte from stdin in hex */
93
 
int16_t get_stdin_hex() {
94
 
        char low;
95
 
        char high;
96
 
 
97
 
        high = get_nibble();
98
 
        if(high == -2) {
99
 
                return -2;
100
 
        }
101
 
        low = get_nibble();
102
 
        if(low == -2) {
103
 
                return -2;
104
 
        }
105
 
 
106
 
        return (high << 4) | low;
107
 
}
108
 
 
109
 
int main(int argc, char **argv) {
110
 
        uint32_t ip;
111
 
        int a;
112
 
        SOCKET sock;
113
 
        SOCKET local;
114
 
        uint32_t dns_l, place;
115
 
        struct sockaddr_in dns;
116
 
        uint8_t buffer[1512], id1, id2;
117
 
        ssize_t len;
118
 
        int16_t get;
119
 
 
120
 
        if(argc >= 2) {
121
 
                ip = inet_addr(argv[1]);
122
 
        } else {
123
 
                ip = 0; /* All IP addresses */
124
 
        }
125
 
        sock = get_port(ip,&dns);
126
 
        if(listen(sock, 250) == -1) {
127
 
                perror("listen error");
128
 
                exit(0);
129
 
        }
130
 
        len = sizeof(struct sockaddr_in);
131
 
        local = accept(sock,(struct sockaddr *)&dns,(void *)&len);
132
 
        if(local == -1) {
133
 
                perror("accept error");
134
 
                exit(0);
135
 
        }
136
 
        /* Blocking: Get 2-byte length header */
137
 
        len = recv(local, buffer, 2, MSG_WAITALL);
138
 
        if(len == -1) {
139
 
                perror("recv error");
140
 
        }
141
 
        for(a=0; a < len; a++) {
142
 
                printf("%02X",buffer[a]);
143
 
        }
144
 
        dns_l = calc_dns_len(buffer);
145
 
        /* Blocking: Get DNS packet */
146
 
        len = recv(local, buffer, dns_l, MSG_WAITALL);
147
 
        for(a=0; a < len; a++) {
148
 
                printf("%02X ",buffer[a]);
149
 
        }
150
 
        id1 = buffer[0];
151
 
        id2 = buffer[1];
152
 
        printf("\n");
153
 
        /* Now, send a packet back from stdin */
154
 
        buffer[0] = get_stdin_hex();
155
 
        buffer[1] = get_stdin_hex();
156
 
        dns_l = calc_dns_len(buffer);
157
 
        if(send(local, buffer, 2, MSG_WAITALL) == -1) {
158
 
                perror("send error len");
159
 
                exit(0);
160
 
        }
161
 
        place = 0;
162
 
        for(a=0; a < dns_l; ) {
163
 
                get = get_stdin_hex();
164
 
                if(get == -2) {
165
 
                        if(send(local,buffer + place, a - place, MSG_WAITALL)
166
 
                           == -1) {
167
 
                                perror("send error pause");
168
 
                                exit(0);
169
 
                        }
170
 
                        printf("%d bytes sent\n",a - place);
171
 
                        place = a;
172
 
                } else {
173
 
                        buffer[a] = get;
174
 
                        buffer[0] = id1;
175
 
                        buffer[1] = id2;
176
 
                        a++;
177
 
                }
178
 
        }
179
 
        if(send(local,buffer + place,dns_l - place, MSG_WAITALL) == -1) {
180
 
                perror("send error");
181
 
                exit(0);
182
 
        }
183
 
        printf("%d bytes sent\n",dns_l - place);
184
 
        return 0;
185
 
}