00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef lint
00039 static char copyright[] =
00040 "@(#) Copyright (c) 2002\n\
00041 Netherlands Forensic Institute. All rights reserved.\n";
00042 #endif
00043
00044
00045
00046
00047
00048
00049
00050 #ifdef HAVE_CONFIG_H
00051 #include "config.h"
00052 #endif
00053
00054 #include <assert.h>
00055 #include <errno.h>
00056 #include <sys/types.h>
00057 #include <netdb.h>
00058 #include <netinet/in.h>
00059 #include <arpa/inet.h>
00060 #include <sys/socket.h>
00061 #include <string.h>
00062 #include <signal.h>
00063 #include <stdlib.h>
00064 #include <unistd.h>
00065
00066 #include "rdd.h"
00067 #include "rdd_internals.h"
00068 #include "error.h"
00069 #include "msgprinter.h"
00070 #include "reader.h"
00071 #include "writer.h"
00072 #include "netio.h"
00073
00074 #if !defined(HAVE_UNISTD_H) && !defined (HAVE_ARPA_INET_H) && !defined(HAVE_SYS_SOCKET_H)
00075 typedef int socklen_t;
00076 #endif
00077
00078
00079
00080 struct netnum {
00081 unsigned lo;
00082 unsigned hi;
00083 };
00084
00085 static int net_verbose;
00086
00087 static int
00088 pack_netnum(struct netnum *packed, rdd_count_t num)
00089 {
00090 if (packed == 0) {
00091 return RDD_BADARG;
00092 }
00093 packed->hi = htonl((num >> 32) & 0xffffffff);
00094 packed->lo = htonl(num & 0xffffffff);
00095 return RDD_OK;
00096 }
00097
00098 static int
00099 unpack_netnum(struct netnum *packed, rdd_count_t *num)
00100 {
00101 if (packed == 0) {
00102 return RDD_BADARG;
00103 }
00104 if (num == 0) {
00105 return RDD_BADARG;
00106 }
00107
00108 rdd_count_t lo, hi;
00109
00110 hi = (rdd_count_t) ntohl(packed->hi);
00111 lo = (rdd_count_t) ntohl(packed->lo);
00112 *num = (hi << 32) | lo;
00113 return RDD_OK;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 int
00129 rdd_send_info(RDD_WRITER *writer, char *file_name,
00130 rdd_count_t file_size,
00131 rdd_count_t block_size,
00132 rdd_count_t split_size,
00133 int ewf,
00134 unsigned flags)
00135 {
00136 struct netnum hdr[6];
00137 unsigned flen;
00138 int rc;
00139
00140 if (writer == 0) {
00141 return RDD_BADARG;
00142 }
00143 if (file_name == 0) {
00144 return RDD_BADARG;
00145 }
00146
00147 flen = strlen(file_name) + 1;
00148 if (flen > RDD_MAX_FILENAMESIZE) {
00149 return RDD_ERANGE;
00150 }
00151
00152 rc = pack_netnum(&hdr[0], (rdd_count_t) flen);
00153 if (rc != RDD_OK) {
00154 return rc;
00155 }
00156 rc = pack_netnum(&hdr[1], file_size);
00157 if (rc != RDD_OK) {
00158 return rc;
00159 }
00160 rc = pack_netnum(&hdr[2], block_size);
00161 if (rc != RDD_OK) {
00162 return rc;
00163 }
00164 rc = pack_netnum(&hdr[3], split_size);
00165 if (rc != RDD_OK) {
00166 return rc;
00167 }
00168 rc = pack_netnum(&hdr[4], ewf);
00169 if (rc != RDD_OK) {
00170 return rc;
00171 }
00172 rc = pack_netnum(&hdr[5], (rdd_count_t) flags);
00173 if (rc != RDD_OK) {
00174 return rc;
00175 }
00176
00177 rc = rdd_writer_write(writer,
00178 (const unsigned char *) hdr, sizeof hdr);
00179 if (rc != RDD_OK) {
00180 return rc;
00181 }
00182
00183 rc = rdd_writer_write(writer, (unsigned char *) file_name, flen);
00184 if (rc != RDD_OK) {
00185 return rc;
00186 }
00187
00188
00189
00190 return RDD_OK;
00191 }
00192
00193
00194
00195 static int
00196 receive(RDD_READER *reader, unsigned char *buf, unsigned buflen)
00197 {
00198 unsigned nread = 0;
00199 int rc;
00200
00201 if (reader == 0) {
00202 return RDD_BADARG;
00203 }
00204
00205 if (buf == 0) {
00206 return RDD_BADARG;
00207 }
00208
00209 rc = rdd_reader_read(reader, buf, buflen, &nread);
00210 if (rc != RDD_OK) {
00211 return rc;
00212 }
00213 if (nread != buflen) {
00214 return RDD_ESYNTAX;
00215 }
00216
00217 return RDD_OK;
00218 }
00219
00220
00221
00222
00223
00224 int
00225 rdd_recv_info(RDD_READER *reader, char **file_name,
00226 rdd_count_t *file_size,
00227 rdd_count_t *block_size,
00228 rdd_count_t *split_size,
00229 int * ewf,
00230 unsigned *flagp)
00231 {
00232 struct netnum hdr[6];
00233 rdd_count_t flen;
00234 rdd_count_t flags;
00235 int rc;
00236
00237 if (reader == 0) {
00238 return RDD_BADARG;
00239 }
00240 if (file_name == 0) {
00241 return RDD_BADARG;
00242 }
00243 if (file_size == 0) {
00244 return RDD_BADARG;
00245 }
00246 if (block_size == 0) {
00247 return RDD_BADARG;
00248 }
00249 if (split_size == 0) {
00250 return RDD_BADARG;
00251 }
00252 if (ewf == 0) {
00253 return RDD_BADARG;
00254 }
00255 if (flagp == 0) {
00256 return RDD_BADARG;
00257 }
00258
00259
00260 rc = receive(reader, (unsigned char *) &hdr, sizeof hdr);
00261 if (rc != RDD_OK) {
00262 return rc;
00263 }
00264
00265
00266
00267 rc = unpack_netnum(&hdr[0], &flen);
00268 if (rc != RDD_OK) {
00269 return rc;
00270 }
00271 rc = unpack_netnum(&hdr[1], file_size);
00272 if (rc != RDD_OK) {
00273 return rc;
00274 }
00275 rc = unpack_netnum(&hdr[2], block_size);
00276 if (rc != RDD_OK) {
00277 return rc;
00278 }
00279 rc = unpack_netnum(&hdr[3], split_size);
00280 if (rc != RDD_OK) {
00281 return rc;
00282 }
00283 rdd_count_t temp_ewf;
00284 rc = unpack_netnum(&hdr[4], &temp_ewf);
00285 if (rc != RDD_OK) {
00286 return rc;
00287 }
00288 if (temp_ewf) {
00289 *ewf = temp_ewf;
00290 } else {
00291 *ewf = 0;
00292 }
00293 rc = unpack_netnum(&hdr[5], &flags);
00294 if (rc != RDD_OK) {
00295 return rc;
00296 }
00297
00298 *flagp = (unsigned) flags;
00299
00300 if (flen > RDD_MAX_FILENAMESIZE) {
00301 return RDD_ERANGE;
00302 }
00303
00304 if (flen == 0) {
00305 return RDD_ESYNTAX;
00306 }
00307
00308 if ((*file_name = malloc(flen)) == 0) {
00309 return RDD_NOMEM;
00310 }
00311
00312 rc = receive(reader, (unsigned char *) *file_name, flen);
00313 if (rc != RDD_OK) {
00314 return rc;
00315 }
00316 if (*file_name != '\0') {
00317 if ((*file_name)[flen-1] != '\0') {
00318 return RDD_ESYNTAX;
00319 }
00320 }
00321
00322 return RDD_OK;
00323 }
00324
00325 int
00326 rdd_init_server(RDD_MSGPRINTER *printer, unsigned int port, int *server_sock)
00327 {
00328 struct sockaddr_in addr;
00329 int sock = -1;
00330 int on = 1;
00331
00332
00333 if (server_sock == 0) {
00334 return RDD_BADARG;
00335 }
00336 if (printer == 0) {
00337 *server_sock = -1;
00338 return RDD_BADARG;
00339 }
00340
00341 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
00342 rdd_mp_unixmsg(printer, RDD_MSG_ERROR, errno,
00343 "cannot create TCP socket");
00344 goto error;
00345 }
00346
00347 memset(&addr, 0, sizeof(addr));
00348 addr.sin_family = AF_INET;
00349 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00350 addr.sin_port = htons(port);
00351
00352 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
00353 rdd_mp_unixmsg(printer, RDD_MSG_ERROR, errno,
00354 "cannot set socket option SO_REUSEADDR");
00355 goto error;
00356 }
00357
00358 if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
00359 rdd_mp_unixmsg(printer, RDD_MSG_ERROR, errno,
00360 "cannot bind TCP socket to local port %u", port);
00361 goto error;
00362 }
00363
00364 if (listen(sock, 5) < 0) {
00365 rdd_mp_unixmsg(printer, RDD_MSG_ERROR, errno,
00366 "cannot listen to TCP socket");
00367 goto error;
00368 }
00369
00370 *server_sock = sock;
00371 return RDD_OK;
00372
00373 error:
00374 if (sock != -1) {
00375 (void) close(sock);
00376 }
00377 *server_sock = -1;
00378 return RDD_EOPEN;
00379 }
00380
00381 int
00382 rdd_await_connection(RDD_MSGPRINTER *printer, int server_sock,
00383 int *client_sock)
00384 {
00385 struct sockaddr_in addr;
00386 socklen_t len = sizeof(addr);
00387 int clsock = -1;
00388
00389
00390 if (client_sock == 0) {
00391 return RDD_BADARG;
00392 }
00393 if (printer == 0) {
00394 *client_sock = -1;
00395 return RDD_BADARG;
00396 }
00397
00398 if ((clsock = accept(server_sock, (struct sockaddr *)&addr, &len)) < 0) {
00399 rdd_mp_unixmsg(printer, RDD_MSG_ERROR, errno,
00400 "cannot accept client connection");
00401 goto error;
00402 }
00403
00404 if (net_verbose) {
00405 rdd_mp_message(printer, RDD_MSG_INFO,
00406 "Accepted inbound connection from %s",
00407 inet_ntoa(addr.sin_addr));
00408 }
00409
00410 *client_sock = clsock;
00411 return RDD_OK;
00412
00413 error:
00414 if (clsock != -1) {
00415 (void) close(clsock);
00416 }
00417 *client_sock = -1;
00418 return RDD_EOPEN;
00419 }