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