00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include <unistd.h>
00020 #include <errno.h>
00021 #include <strings.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <sys/time.h>
00025 #include "dtn_api.h"
00026
00027 #define BUFSIZE 16
00028
00029 const char *progname;
00030
00031 int verbose = 0;
00032 int quiet = 0;
00033 char* endpoint = NULL;
00034 dtn_reg_id_t regid = DTN_REGID_NONE;
00035 int expiration = 30;
00036 int count = 0;
00037 int failure_action = DTN_REG_DEFER;
00038 char* failure_script = "";
00039 int register_only = 0;
00040 int change = 0;
00041 int unregister = 0;
00042 int recv_timeout = -1;
00043 int no_find_reg = 0;
00044
00045 void
00046 usage()
00047 {
00048 fprintf(stderr, "usage: %s [opts] <endpoint> \n", progname);
00049 fprintf(stderr, "options:\n");
00050 fprintf(stderr, " -v verbose\n");
00051 fprintf(stderr, " -q quiet\n");
00052 fprintf(stderr, " -h help\n");
00053 fprintf(stderr, " -d <eid|demux_string> endpoint id\n");
00054 fprintf(stderr, " -r <regid> use existing registration regid\n");
00055 fprintf(stderr, " -n <count> exit after count bundles received\n");
00056 fprintf(stderr, " -e <time> registration expiration time in seconds "
00057 "(default: one hour)\n");
00058 fprintf(stderr, " -f <defer|drop|exec> failure action\n");
00059 fprintf(stderr, " -F <script> failure script for exec action\n");
00060 fprintf(stderr, " -x call dtn_register and immediately exit\n");
00061 fprintf(stderr, " -c call dtn_change_registration and immediately exit\n");
00062 fprintf(stderr, " -u call dtn_unregister and immediately exit\n");
00063 fprintf(stderr, " -N don't try to find an existing registration\n");
00064 fprintf(stderr, " -t <timeout> timeout value for call to dtn_recv\n");
00065 }
00066
00067 void
00068 parse_options(int argc, char**argv)
00069 {
00070 char c, done = 0;
00071
00072 progname = argv[0];
00073
00074 while (!done)
00075 {
00076 c = getopt(argc, argv, "vqhHd:r:e:f:F:xn:cuNt:");
00077 switch (c)
00078 {
00079 case 'v':
00080 verbose = 1;
00081 break;
00082 case 'q':
00083 quiet = 1;
00084 break;
00085 case 'h':
00086 case 'H':
00087 usage();
00088 exit(0);
00089 return;
00090 case 'r':
00091 regid = atoi(optarg);
00092 break;
00093 case 'e':
00094 expiration = atoi(optarg);
00095 break;
00096 case 'f':
00097 if (!strcasecmp(optarg, "defer")) {
00098 failure_action = DTN_REG_DEFER;
00099
00100 } else if (!strcasecmp(optarg, "drop")) {
00101 failure_action = DTN_REG_DROP;
00102
00103 } else if (!strcasecmp(optarg, "exec")) {
00104 failure_action = DTN_REG_EXEC;
00105
00106 } else {
00107 fprintf(stderr, "invalid failure action '%s'\n", optarg);
00108 usage();
00109 exit(1);
00110 }
00111 case 'F':
00112 failure_script = optarg;
00113 break;
00114 case 'x':
00115 register_only = 1;
00116 break;
00117 case 'n':
00118 count = atoi(optarg);
00119 break;
00120 case 'c':
00121 change = 1;
00122 break;
00123 case 'u':
00124 unregister = 1;
00125 break;
00126 case 'N':
00127 no_find_reg = 1;
00128 break;
00129 case 't':
00130 recv_timeout = atoi(optarg);
00131 break;
00132 case -1:
00133 done = 1;
00134 break;
00135 default:
00136
00137
00138 usage();
00139 exit(1);
00140 }
00141 }
00142
00143 endpoint = argv[optind];
00144 if (!endpoint && (regid == DTN_REGID_NONE)) {
00145 fprintf(stderr, "must specify either an endpoint or a regid\n");
00146 usage();
00147 exit(1);
00148 }
00149
00150 if ((change || unregister) && (regid == DTN_REGID_NONE)) {
00151 fprintf(stderr, "must specify regid when using -%c option\n",
00152 change ? 'c' : 'u');
00153 usage();
00154 exit(1);
00155 }
00156
00157 if (failure_action == DTN_REG_EXEC && failure_script == NULL) {
00158 fprintf(stderr, "failure action EXEC must supply script\n");
00159 usage();
00160 exit(1);
00161 }
00162 }
00163
00164
00165 int
00166 main(int argc, char** argv)
00167 {
00168 int i;
00169 u_int k;
00170 int ret;
00171 int total_bytes = 0;
00172 dtn_handle_t handle;
00173 dtn_endpoint_id_t local_eid;
00174 dtn_reg_info_t reginfo;
00175 dtn_bundle_spec_t spec;
00176 dtn_bundle_payload_t payload;
00177 unsigned char* buffer;
00178 char s_buffer[BUFSIZE];
00179 int call_bind;
00180
00181
00182
00183 setvbuf(stdout, (char *)NULL, _IOLBF, 0);
00184
00185 progname = argv[0];
00186
00187 parse_options(argc, argv);
00188
00189 if (count == 0) {
00190 printf("dtnrecv (pid %d) starting up\n", getpid());
00191 } else {
00192 printf("dtnrecv (pid %d) starting up -- count %u\n", getpid(), count);
00193 }
00194
00195
00196 if (verbose) printf("opening connection to dtn router...\n");
00197 int err = dtn_open(&handle);
00198 if (err != DTN_SUCCESS) {
00199 fprintf(stderr, "fatal error opening dtn handle: %s\n",
00200 dtn_strerror(err));
00201 exit(1);
00202 }
00203 if (verbose) printf("opened connection to dtn router...\n");
00204
00205
00206
00207 memset(®info, 0, sizeof(reginfo));
00208
00209 if ((regid == DTN_REGID_NONE) || change)
00210 {
00211
00212
00213
00214 if (endpoint[0] == '/') {
00215 if (verbose) printf("calling dtn_build_local_eid.\n");
00216 dtn_build_local_eid(handle, &local_eid, (char *) endpoint);
00217 if (verbose) printf("local_eid [%s]\n", local_eid.uri);
00218 } else {
00219 if (verbose) printf("calling parse_eid_string\n");
00220 if (dtn_parse_eid_string(&local_eid, endpoint)) {
00221 fprintf(stderr, "invalid destination endpoint '%s'\n",
00222 endpoint);
00223 goto err;
00224 }
00225 }
00226
00227
00228 dtn_copy_eid(®info.endpoint, &local_eid);
00229 reginfo.regid = regid;
00230 reginfo.expiration = expiration;
00231 reginfo.failure_action = failure_action;
00232 reginfo.script.script_val = failure_script;
00233 reginfo.script.script_len = strlen(failure_script) + 1;
00234 }
00235
00236 if (change) {
00237 if ((ret = dtn_change_registration(handle, regid, ®info)) != 0) {
00238 fprintf(stderr, "error changing registration: %d (%s)\n",
00239 ret, dtn_strerror(dtn_errno(handle)));
00240 goto err;
00241 }
00242 printf("change registration succeeded, regid %d\n", regid);
00243 goto done;
00244 }
00245
00246 if (unregister) {
00247 if (dtn_unregister(handle, regid) != 0) {
00248 fprintf(stderr, "error in unregister regid %d: %s\n",
00249 regid, dtn_strerror(dtn_errno(handle)));
00250 goto err;
00251 }
00252
00253 printf("unregister succeeded, regid %d\n", regid);
00254 goto done;
00255 }
00256
00257
00258
00259 if (regid == DTN_REGID_NONE && ! no_find_reg) {
00260 if (dtn_find_registration(handle, &local_eid, ®id) != 0) {
00261 if (dtn_errno(handle) != DTN_ENOTFOUND) {
00262 fprintf(stderr, "error in find_registration: %s\n",
00263 dtn_strerror(dtn_errno(handle)));
00264 goto err;
00265 }
00266 }
00267 printf("find registration succeeded, regid %d\n", regid);
00268 call_bind = 1;
00269 }
00270
00271
00272 if (regid == DTN_REGID_NONE) {
00273 if ((ret = dtn_register(handle, ®info, ®id)) != 0) {
00274 fprintf(stderr, "error creating registration: %d (%s)\n",
00275 ret, dtn_strerror(dtn_errno(handle)));
00276 goto err;
00277 }
00278
00279 printf("register succeeded, regid %d\n", regid);
00280 call_bind = 0;
00281 } else {
00282 call_bind = 1;
00283 }
00284
00285 if (register_only) {
00286 goto done;
00287 }
00288
00289 if (call_bind) {
00290
00291 printf("binding to regid %d\n", regid);
00292 if (dtn_bind(handle, regid) != 0) {
00293 fprintf(stderr, "error binding to registration: %s\n",
00294 dtn_strerror(dtn_errno(handle)));
00295 goto err;
00296 }
00297 }
00298
00299
00300 if (count == 0) {
00301 printf("looping forever to receive bundles\n");
00302 } else {
00303 printf("looping to receive %d bundles\n", count);
00304 }
00305 for (i = 0; (count == 0) || (i < count); ++i) {
00306 memset(&spec, 0, sizeof(spec));
00307 memset(&payload, 0, sizeof(payload));
00308
00309 if (!quiet) {
00310 printf("dtn_recv [%s]...\n", local_eid.uri);
00311 }
00312
00313 if ((ret = dtn_recv(handle, &spec,
00314 DTN_PAYLOAD_MEM, &payload, recv_timeout)) < 0)
00315 {
00316 fprintf(stderr, "error getting recv reply: %d (%s)\n",
00317 ret, dtn_strerror(dtn_errno(handle)));
00318 goto err;
00319 }
00320
00321 total_bytes += payload.buf.buf_len;
00322
00323 if (quiet) {
00324 dtn_free_payload(&payload);
00325 continue;
00326 }
00327
00328 printf("%d bytes from [%s]: transit time=%d ms\n",
00329 payload.buf.buf_len,
00330 spec.source.uri, 0);
00331
00332 buffer = (unsigned char *) payload.buf.buf_val;
00333 for (k=0; k < payload.buf.buf_len; k++)
00334 {
00335 if (buffer[k] >= ' ' && buffer[k] <= '~')
00336 s_buffer[k%BUFSIZE] = buffer[k];
00337 else
00338 s_buffer[k%BUFSIZE] = '.';
00339
00340 if (k%BUFSIZE == 0)
00341 {
00342 printf("%07x ", k);
00343 }
00344 else if (k%2 == 0)
00345 {
00346 printf(" ");
00347 }
00348
00349 printf("%02x", buffer[k] & 0xff);
00350
00351
00352 if (k%BUFSIZE == BUFSIZE-1)
00353 {
00354 printf(" | %.*s\n", BUFSIZE, s_buffer);
00355 }
00356 }
00357
00358
00359 if (k%BUFSIZE != BUFSIZE-1) {
00360 while (k%BUFSIZE != BUFSIZE-1) {
00361 if (k%2 == 0) {
00362 printf(" ");
00363 }
00364 printf(" ");
00365 k++;
00366 }
00367 printf(" | %.*s\n",
00368 (int)payload.buf.buf_len%BUFSIZE,
00369 s_buffer);
00370 }
00371 printf("\n");
00372
00373 dtn_free_payload(&payload);
00374 }
00375
00376 printf("dtnrecv (pid %d) exiting: %d bundles received, %d total bytes\n\n",
00377 getpid(), i, total_bytes);
00378
00379 done:
00380 dtn_close(handle);
00381 return 0;
00382
00383 err:
00384 dtn_close(handle);
00385 return 1;
00386 }