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 <stdlib.h>
00023 #include <sys/time.h>
00024 #include <time.h>
00025
00026 #include "dtn_api.h"
00027
00028 char *progname;
00029
00030
00031 dtn_bundle_payload_location_t
00032 payload_type = 0;
00033 int copies = 1;
00034 int verbose = 0;
00035 int sleep_time = 0;
00036
00037
00038 int expiration = 3600;
00039 int delivery_receipts = 0;
00040 int delete_receipts = 0;
00041 int forwarding_receipts = 0;
00042 int custody = 0;
00043 int custody_receipts = 0;
00044 int receive_receipts = 0;
00045 int overwrite = 0;
00046 int wait_for_report = 0;
00047
00048 char * data_source = NULL;
00049 char date_buf[256];
00050
00051
00052 int extension_block = 0;
00053 u_int block_type = 0;
00054 u_int block_flags = BLOCK_FLAG_NONE;
00055 char * block_buf = NULL;
00056
00057
00058 char * arg_replyto = NULL;
00059 char * arg_source = NULL;
00060 char * arg_dest = NULL;
00061
00062 dtn_reg_id_t regid = DTN_REGID_NONE;
00063
00064
00065 void parse_options(int, char**);
00066 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle,
00067 dtn_endpoint_id_t * eid,
00068 char * str);
00069 void print_usage();
00070 void print_eid(char * label, dtn_endpoint_id_t * eid);
00071 void fill_payload(dtn_bundle_payload_t* payload);
00072
00073 int
00074 main(int argc, char** argv)
00075 {
00076 int i;
00077 int ret;
00078 dtn_handle_t handle;
00079 dtn_reg_info_t reginfo;
00080 dtn_bundle_spec_t bundle_spec;
00081 dtn_bundle_spec_t reply_spec;
00082 dtn_bundle_id_t bundle_id;
00083 dtn_bundle_payload_t send_payload;
00084 dtn_bundle_payload_t reply_payload;
00085 dtn_extension_block_t block;
00086 struct timeval start, end;
00087
00088
00089
00090 setvbuf(stdout, (char *)NULL, _IOLBF, 0);
00091
00092 parse_options(argc, argv);
00093
00094
00095 if (verbose) fprintf(stdout, "Opening connection to local DTN daemon\n");
00096
00097 int err = dtn_open(&handle);
00098 if (err != DTN_SUCCESS) {
00099 fprintf(stderr, "fatal error opening dtn handle: %s\n",
00100 dtn_strerror(err));
00101 exit(1);
00102 }
00103
00104
00105 memset(&bundle_spec, 0, sizeof(bundle_spec));
00106
00107
00108 if (verbose) fprintf(stdout, "Destination: %s\n", arg_dest);
00109 parse_eid(handle, &bundle_spec.dest, arg_dest);
00110
00111 if (verbose) fprintf(stdout, "Source: %s\n", arg_source);
00112 parse_eid(handle, &bundle_spec.source, arg_source);
00113 if (arg_replyto == NULL)
00114 {
00115 if (verbose) fprintf(stdout, "Reply To: same as source\n");
00116 dtn_copy_eid(&bundle_spec.replyto, &bundle_spec.source);
00117 }
00118 else
00119 {
00120 if (verbose) fprintf(stdout, "Reply To: %s\n", arg_replyto);
00121 parse_eid(handle, &bundle_spec.replyto, arg_replyto);
00122 }
00123
00124 if (verbose)
00125 {
00126 print_eid("source_eid", &bundle_spec.source);
00127 print_eid("replyto_eid", &bundle_spec.replyto);
00128 print_eid("dest_eid", &bundle_spec.dest);
00129 }
00130
00131 if (wait_for_report)
00132 {
00133
00134 memset(®info, 0, sizeof(reginfo));
00135 dtn_copy_eid(®info.endpoint, &bundle_spec.replyto);
00136 reginfo.failure_action = DTN_REG_DROP;
00137 reginfo.regid = regid;
00138 reginfo.expiration = 60 * 60;
00139 if ((ret = dtn_register(handle, ®info, ®id)) != 0) {
00140 fprintf(stderr, "error creating registration (id=%d): %d (%s)\n",
00141 regid, ret, dtn_strerror(dtn_errno(handle)));
00142 exit(1);
00143 }
00144
00145 if (verbose) printf("dtn_register succeeded, regid 0x%x\n", regid);
00146 }
00147
00148
00149 bundle_spec.expiration = expiration;
00150
00151 if (delivery_receipts)
00152 {
00153
00154 bundle_spec.dopts |= DOPTS_DELIVERY_RCPT;
00155 }
00156
00157 if (delete_receipts)
00158 {
00159
00160 bundle_spec.dopts |= DOPTS_DELETE_RCPT;
00161 }
00162
00163 if (forwarding_receipts)
00164 {
00165
00166 bundle_spec.dopts |= DOPTS_FORWARD_RCPT;
00167 }
00168
00169 if (custody)
00170 {
00171
00172 bundle_spec.dopts |= DOPTS_CUSTODY;
00173 }
00174
00175 if (custody_receipts)
00176 {
00177
00178 bundle_spec.dopts |= DOPTS_CUSTODY_RCPT;
00179 }
00180
00181 if (receive_receipts)
00182 {
00183
00184 bundle_spec.dopts |= DOPTS_RECEIVE_RCPT;
00185 }
00186
00187
00188 memset(&block, 0, sizeof(block));
00189 if (extension_block == 1) {
00190 block.type = block_type;
00191 block.flags = block_flags;
00192 block.data.data_len = strlen(block_buf);
00193 block.data.data_val = block_buf;
00194
00195 bundle_spec.blocks.blocks_len = 1;
00196 bundle_spec.blocks.blocks_val = █
00197 }
00198
00199
00200 for (i = 0; i < copies; ++i) {
00201 gettimeofday(&start, NULL);
00202
00203 fill_payload(&send_payload);
00204
00205 memset(&bundle_id, 0, sizeof(bundle_id));
00206
00207 if ((ret = dtn_send(handle, &bundle_spec, &send_payload,
00208 &bundle_id)) != 0)
00209 {
00210 fprintf(stderr, "error sending bundle: %d (%s)\n",
00211 ret, dtn_strerror(dtn_errno(handle)));
00212 exit(1);
00213 }
00214
00215 if (verbose) fprintf(stdout, "bundle sent successfully: id %s,%u.%u\n",
00216 bundle_id.source.uri,
00217 bundle_id.creation_ts.secs,
00218 bundle_id.creation_ts.seqno);
00219
00220 if (wait_for_report)
00221 {
00222 memset(&reply_spec, 0, sizeof(reply_spec));
00223 memset(&reply_payload, 0, sizeof(reply_payload));
00224
00225
00226 if ((ret = dtn_recv(handle, &reply_spec,
00227 DTN_PAYLOAD_MEM, &reply_payload, -1)) < 0)
00228 {
00229 fprintf(stderr, "error getting reply: %d (%s)\n",
00230 ret, dtn_strerror(dtn_errno(handle)));
00231 exit(1);
00232 }
00233 gettimeofday(&end, NULL);
00234
00235 printf("got %d byte report from [%s]: time=%.1f ms\n",
00236 reply_payload.buf.buf_len,
00237 reply_spec.source.uri,
00238 ((double)(end.tv_sec - start.tv_sec) * 1000.0 +
00239 (double)(end.tv_usec - start.tv_usec)/1000.0));
00240 }
00241
00242 if (sleep_time != 0) {
00243 usleep(sleep_time * 1000);
00244 }
00245 }
00246
00247 dtn_close(handle);
00248
00249 if (block_buf != NULL) {
00250 free(block_buf);
00251 block_buf = NULL;
00252 }
00253
00254 return 0;
00255 }
00256
00257 void print_usage()
00258 {
00259 fprintf(stderr, "usage: %s [opts] "
00260 "-s <source_eid> -d <dest_eid> -t <type> -p <payload>\n",
00261 progname);
00262 fprintf(stderr, "options:\n");
00263 fprintf(stderr, " -v verbose\n");
00264 fprintf(stderr, " -h help\n");
00265 fprintf(stderr, " -s <eid|demux_string> source eid)\n");
00266 fprintf(stderr, " -d <eid|demux_string> destination eid)\n");
00267 fprintf(stderr, " -r <eid|demux_string> reply to eid)\n");
00268 fprintf(stderr, " -t <f|t|m|d> payload type: file, tmpfile, message, or date\n");
00269 fprintf(stderr, " -p <filename|string> payload data\n");
00270 fprintf(stderr, " -e <time> expiration time in seconds (default: one hour)\n");
00271 fprintf(stderr, " -i <regid> registration id for reply to\n");
00272 fprintf(stderr, " -n <int> copies of the bundle to send\n");
00273 fprintf(stderr, " -z <time> msecs to sleep between transmissions\n");
00274 fprintf(stderr, " -c request custody transfer\n");
00275 fprintf(stderr, " -C request custody transfer receipts\n");
00276 fprintf(stderr, " -D request for end-to-end delivery receipt\n");
00277 fprintf(stderr, " -X request for deletion receipt\n");
00278 fprintf(stderr, " -R request for bundle reception receipts\n");
00279 fprintf(stderr, " -F request for bundle forwarding receipts\n");
00280 fprintf(stderr, " -w wait for bundle status reports\n");
00281 fprintf(stderr, " -E <int> include extension block and specify type\n");
00282 fprintf(stderr, " -P <int> flag value(s) to include in extension block\n");
00283 fprintf(stderr, " -S <string> extension block content\n");
00284
00285 exit(1);
00286 }
00287
00288 void parse_options(int argc, char**argv)
00289 {
00290 char c, done = 0;
00291 char arg_type = 0;
00292
00293 progname = argv[0];
00294
00295 while (!done)
00296 {
00297 c = getopt(argc, argv, "vhHr:s:d:e:n:woDXFRcCt:p:i:z:E:P:S:");
00298 switch (c)
00299 {
00300 case 'v':
00301 verbose = 1;
00302 break;
00303 case 'h':
00304 case 'H':
00305 print_usage();
00306 exit(0);
00307 return;
00308 case 'r':
00309 arg_replyto = optarg;
00310 break;
00311 case 's':
00312 arg_source = optarg;
00313 break;
00314 case 'd':
00315 arg_dest = optarg;
00316 break;
00317 case 'e':
00318 expiration = atoi(optarg);
00319 break;
00320 case 'n':
00321 copies = atoi(optarg);
00322 break;
00323 case 'w':
00324 wait_for_report = 1;
00325 break;
00326 case 'D':
00327 delivery_receipts = 1;
00328 break;
00329 case 'X':
00330 delete_receipts = 1;
00331 break;
00332 case 'F':
00333 forwarding_receipts = 1;
00334 break;
00335 case 'R':
00336 receive_receipts = 1;
00337 break;
00338 case 'c':
00339 custody = 1;
00340 break;
00341 case 'C':
00342 custody_receipts = 1;
00343 break;
00344 case 't':
00345 arg_type = optarg[0];
00346 break;
00347 case 'p':
00348 data_source = strdup(optarg);
00349 break;
00350 case 'i':
00351 regid = atoi(optarg);
00352 break;
00353 case 'z':
00354 sleep_time = atoi(optarg);
00355 break;
00356 case 'E':
00357 extension_block = 1;
00358 block_type = atoi(optarg);
00359 break;
00360 case 'P':
00361 block_flags = atoi(optarg);
00362 break;
00363 case 'S':
00364 block_buf = strdup(optarg);
00365 break;
00366 case -1:
00367 done = 1;
00368 break;
00369 default:
00370
00371
00372 print_usage();
00373 exit(1);
00374 }
00375 }
00376
00377 #define CHECK_SET(_arg, _what) \
00378 if (_arg == 0) { \
00379 fprintf(stderr, "dtnsend: %s must be specified\n", _what); \
00380 print_usage(); \
00381 exit(1); \
00382 }
00383
00384 CHECK_SET(arg_source, "source eid");
00385 CHECK_SET(arg_dest, "destination eid");
00386 CHECK_SET(arg_type, "payload type");
00387 if (arg_type != 'd') {
00388 CHECK_SET(data_source, "payload data");
00389 }
00390
00391 switch (arg_type)
00392 {
00393 case 'f': payload_type = DTN_PAYLOAD_FILE; break;
00394 case 't': payload_type = DTN_PAYLOAD_TEMP_FILE; break;
00395 case 'm': payload_type = DTN_PAYLOAD_MEM; break;
00396 case 'd':
00397 payload_type = DTN_PAYLOAD_MEM;
00398 data_source = date_buf;
00399 break;
00400 default:
00401 fprintf(stderr, "dtnsend: type argument '%d' invalid\n", arg_type);
00402 print_usage();
00403 exit(1);
00404 }
00405
00406 if (extension_block == 1) {
00407 if (block_type > 255) {
00408 fprintf(stderr, "dtnsend: invalid block type %d\n", block_type);
00409 print_usage();
00410 exit(1);
00411 }
00412
00413 if (block_flags > 255) {
00414 fprintf(stderr, "dtnsend: invalid block flags %d\n", block_flags);
00415 print_usage();
00416 exit(1);
00417 }
00418 }
00419 }
00420
00421 dtn_endpoint_id_t * parse_eid(dtn_handle_t handle,
00422 dtn_endpoint_id_t* eid, char * str)
00423 {
00424
00425 if (!dtn_parse_eid_string(eid, str))
00426 {
00427 if (verbose) fprintf(stdout, "%s (literal)\n", str);
00428 return eid;
00429 }
00430
00431
00432 else if (!dtn_build_local_eid(handle, eid, str))
00433 {
00434 if (verbose) fprintf(stdout, "%s (local)\n", str);
00435 return eid;
00436 }
00437 else
00438 {
00439 fprintf(stderr, "invalid eid string '%s'\n", str);
00440 exit(1);
00441 }
00442 }
00443
00444 void print_eid(char * label, dtn_endpoint_id_t * eid)
00445 {
00446 printf("%s [%s]\n", label, eid->uri);
00447 }
00448
00449 void fill_payload(dtn_bundle_payload_t* payload) {
00450
00451 if (data_source == date_buf) {
00452 time_t current = time(NULL);
00453 strcpy(date_buf, ctime(¤t));
00454 }
00455
00456 memset(payload, 0, sizeof(*payload));
00457 dtn_set_payload(payload, payload_type, data_source, strlen(data_source));
00458 }