diff --git a/src/config_init.c b/src/config_init.c index ed219b48..dab9a91f 100644 --- a/src/config_init.c +++ b/src/config_init.c @@ -202,82 +202,36 @@ config_init(fko_cli_options_t *options, int argc, char **argv) options->port = FKO_DEFAULT_PORT; while ((cmd_arg = getopt_long(argc, argv, - "A:a:D:G:S:Q:p:P:B:bghqdTvVn", cmd_opts, &index)) != -1) { + "a:A:bB:D:gG:hm:np:P:qQ:S:TU:vV", cmd_opts, &index)) != -1) { switch(cmd_arg) { - case 'A': - strlcpy(options->access_str, optarg, MAX_LINE_LEN); - break; - case 'D': - strlcpy(options->spa_server_ip_str, optarg, MAX_IP_STR_LEN); - break; case 'a': strlcpy(options->allow_ip_str, optarg, MAX_IP_STR_LEN); break; - case 'G': - strlcpy(options->get_key_file, optarg, MAX_PATH_LEN); - break; - case 'B': - strlcpy(options->save_packet_file, optarg, MAX_PATH_LEN); + case 'A': + strlcpy(options->access_str, optarg, MAX_LINE_LEN); break; case 'b': options->save_packet_file_append = 1; break; - case 'Q': - strlcpy(options->spoof_ip_src_str, optarg, MAX_IP_STR_LEN); + case 'B': + strlcpy(options->save_packet_file, optarg, MAX_PATH_LEN); break; - case 'U': - strlcpy(options->spoof_user, optarg, MAX_USERNAME_LEN); + case 'D': + strlcpy(options->spa_server_ip_str, optarg, MAX_IP_STR_LEN); break; - case 'p': - options->port = atoi(optarg); - if (options->port < 0 || options->port > 65535) { - fprintf(stderr, "[*] Unrecognized port: %s\n", optarg); - exit(1); - } + case 'g': + case GPG_ENCRYPTION: + options->use_gpg = 1; break; - case 'P': - if (strncmp(optarg, "udp", strlen("udp")) == 0) - options->proto = IPPROTO_UDP; - else if (strncmp(optarg, "tcp", strlen("tcp")) == 0) - options->proto = IPPROTO_TCP; - else if (strncmp(optarg, "icmp", strlen("icmp")) == 0) - options->proto = IPPROTO_ICMP; - else { - fprintf(stderr, "[*] Unrecognized protocol: %s\n", optarg); - exit(1); - } - break; - case 'S': - options->src_port = atoi(optarg); - if (options->port < 0 || options->port > 65535) { - fprintf(stderr, "[*] Unrecognized port: %s\n", optarg); - exit(1); - } - break; - case 'q': - options->quiet = 1; - break; - case 'n': - options->no_save = 1; - break; - case 'T': - options->test = 1; - break; - case 'd': - options->debug = 1; - break; - case 'v': - options->verbose = 1; - break; - case 'V': - options->version = 1; + case 'G': + strlcpy(options->get_key_file, optarg, MAX_PATH_LEN); break; case 'h': usage(); exit(0); + case 'm': case FKO_DIGEST_NAME: - case 'm': if(strncasecmp(optarg, "md5", 3) == 0) options->digest_type = FKO_DIGEST_MD5; else if(strncasecmp(optarg, "sha1", 4) == 0) @@ -290,9 +244,54 @@ config_init(fko_cli_options_t *options, int argc, char **argv) exit(1); } break; - case 'g': - case GPG_ENCRYPTION: - options->use_gpg = 1; + case 'n': + options->no_save = 1; + break; + case 'p': + options->port = atoi(optarg); + if (options->port < 0 || options->port > 65535) { + fprintf(stderr, "[*] Unrecognized port: %s\n", optarg); + exit(1); + } + break; + case 'P': + if (strncmp(optarg, "udp", strlen("udp")) == 0) + options->proto = FKO_PROTO_UDP; + else if (strncmp(optarg, "tcpraw", strlen("tcpraw")) == 0) + options->proto = FKO_PROTO_TCP_RAW; + else if (strncmp(optarg, "tcp", strlen("tcp")) == 0) + options->proto = FKO_PROTO_TCP; + else if (strncmp(optarg, "icmp", strlen("icmp")) == 0) + options->proto = FKO_PROTO_ICMP; + else { + fprintf(stderr, "[*] Unrecognized protocol: %s\n", optarg); + exit(1); + } + break; + case 'q': + options->quiet = 1; + break; + case 'Q': + strlcpy(options->spoof_ip_src_str, optarg, MAX_IP_STR_LEN); + break; + case 'S': + options->src_port = atoi(optarg); + if (options->port < 0 || options->port > 65535) { + fprintf(stderr, "[*] Unrecognized port: %s\n", optarg); + exit(1); + } + break; + case 'T': + options->test = 1; + break; + case 'U': + strlcpy(options->spoof_user, optarg, MAX_USERNAME_LEN); + break; + case 'v': + options->verbose = 1; + break; + case 'V': + options->version = 1; break; case GPG_RECIP_KEY: options->use_gpg = 1; @@ -334,7 +333,7 @@ config_init(fko_cli_options_t *options, int argc, char **argv) void usage(void) { - fprintf(stderr, "\n%s version %s\n%s\n\n", MY_NAME, MY_VERSION, MY_DESC); + fprintf(stderr, "\n%s client version %s\n%s\n\n", MY_NAME, MY_VERSION, MY_DESC); fprintf(stderr, "Usage: fwknop -A [-s|-R|-a] -D [options]\n\n" " -h, --help - Print this usage message and exit.\n" @@ -348,8 +347,10 @@ usage(void) " -D, --destination - Specify the IP address of the fwknop server.\n" " -p, --server-port - Set the destination port for outgoing SPA\n" " packet.\n" - " -P, --source-protocol - Set the protocol (UDP, TCP, ICMP) for the\n" - " outgoing SPA packet.\n" + " -P, --source-protocol - Set the protocol (udp, tcp, tcpraw, icmp) for\n" + " the outgoing SPA packet. Note: The 'tcpraw'\n" + " and 'icmp' modes use raw sockets and thus\n" + " require root access to run.\n" " -S, --source-port - Set the source port for outgoing SPA packet.\n" " -Q, --spoof-source - Set the source IP for outgoing SPA packet.\n" " -U, --spoof-user - Set the username within outgoing SPA packet.\n" @@ -357,7 +358,6 @@ usage(void) " -G, --get-key - Load an encryption key/password from a file.\n" " -T, --test - Build the SPA packet but do not send it over\n" " the network.\n" - " -d, --debug - Set debug mode.\n" " -v, --verbose - Set verbose mode.\n" " -V, --version - Print version number.\n" " -m, --digest-type - Speciy the message digest algorithm to use.\n" diff --git a/src/config_init.h b/src/config_init.h index f902727f..af77d8d7 100644 --- a/src/config_init.h +++ b/src/config_init.h @@ -46,30 +46,29 @@ enum { */ static struct option cmd_opts[] = { - {"access", 1, NULL, 'A'}, - {"destination", 1, NULL, 'D'}, {"allow-ip", 1, NULL, 'a'}, - {"server-port", 1, NULL, 'p'}, - {"server-proto", 1, NULL, 'P'}, - {"source-port", 1, NULL, 'S'}, - {"spoof-src", 1, NULL, 'Q'}, - {"spoof-user", 1, NULL, 'U'}, - {"save-packet", 1, NULL, 'B'}, + {"access", 1, NULL, 'A'}, {"save-packet-append", 0, NULL, 'b'}, - {"get-key", 1, NULL, 'G'}, - {"quiet", 0, NULL, 'q'}, - {"debug", 0, NULL, 'd'}, - {"test", 0, NULL, 'T'}, - {"no-save", 0, NULL, 'n'}, - {"verbose", 0, NULL, 'v'}, - {"version", 0, NULL, 'V'}, - {"help", 0, NULL, 'h'}, + {"save-packet", 1, NULL, 'B'}, {"digest-type", 1, NULL, FKO_DIGEST_NAME}, + {"destination", 1, NULL, 'D'}, {"gpg-encryption", 0, NULL, 'g'}, {"gpg-recipient-key", 1, NULL, GPG_RECIP_KEY }, {"gpg-signer-key", 1, NULL, GPG_SIGNER_KEY }, {"gpg-home-dir", 1, NULL, GPG_HOME_DIR }, {"gpg-agent", 0, NULL, GPG_AGENT }, + {"get-key", 1, NULL, 'G'}, + {"help", 0, NULL, 'h'}, + {"no-save", 0, NULL, 'n'}, + {"server-port", 1, NULL, 'p'}, + {"server-proto", 1, NULL, 'P'}, + {"quiet", 0, NULL, 'q'}, + {"spoof-src", 1, NULL, 'Q'}, + {"source-port", 1, NULL, 'S'}, + {"test", 0, NULL, 'T'}, + {"spoof-user", 1, NULL, 'U'}, + {"verbose", 0, NULL, 'v'}, + {"version", 0, NULL, 'V'}, {0, 0, 0, 0} }; diff --git a/src/fwknop.c b/src/fwknop.c index c9301072..48608350 100644 --- a/src/fwknop.c +++ b/src/fwknop.c @@ -29,12 +29,10 @@ #include "utils.h" #include "getpasswd.h" -/* Used by the get_user_pw function below. +/* prototypes */ -#define CRYPT_OP_ENCRYPT 1 -#define CRYPT_OP_DECRYPT 2 - char* get_user_pw(fko_cli_options_t *options, int crypt_op); +static void display_ctx(fko_ctx_t ctx); void errmsg(char *msg, int err); int @@ -60,7 +58,6 @@ main(int argc, char **argv) return(1); } - /* Display version info and exit. */ if (options.version) { @@ -184,13 +181,17 @@ main(int argc, char **argv) */ if (!options.test) { - //if(send_spa_packet(ctx, &options) < 1) res = send_spa_packet(ctx, &options); - if(res < 1) + if(res < 0) { perror("send_spa_packet"); return(1); } + else + { + if(options.verbose) + fprintf(stderr, "[+] send_spa_packet: bytes sent: %i\n", res); + } } else { @@ -295,6 +296,8 @@ errmsg(char *msg, int err) { MY_NAME, msg, err, fko_errstr(err)); } +/* Show the fields of the FKO context. +*/ static void display_ctx(fko_ctx_t ctx) { diff --git a/src/fwknop.h b/src/fwknop.h index 56229430..cd89c91c 100644 --- a/src/fwknop.h +++ b/src/fwknop.h @@ -29,8 +29,9 @@ #include "fwknop_common.h" -/* prototypes +/* Used by the get_user_pw function below. */ -static void display_ctx(fko_ctx_t ctx); +#define CRYPT_OP_ENCRYPT 1 +#define CRYPT_OP_DECRYPT 2 #endif /* FWKNOP_H */ diff --git a/src/fwknop_common.h b/src/fwknop_common.h index c4aa3858..4800f6c8 100644 --- a/src/fwknop_common.h +++ b/src/fwknop_common.h @@ -35,6 +35,8 @@ #include #include +#include + #if STDC_HEADERS #include #include @@ -74,9 +76,18 @@ */ #define DEF_CONFIG_FILE MY_NAME".conf" +/* Protocol assignment values +*/ +enum { + FKO_PROTO_UDP, + FKO_PROTO_TCP, + FKO_PROTO_TCP_RAW, + FKO_PROTO_ICMP +}; + /* Other common defines */ -#define FKO_DEFAULT_PROTO IPPROTO_UDP +#define FKO_DEFAULT_PROTO FKO_PROTO_UDP #define FKO_DEFAULT_PORT 62201 #define MAX_IP_STR_LEN 16 @@ -109,7 +120,6 @@ typedef struct fko_cli_options unsigned int digest_type; /* Various command-line flags */ - unsigned char debug; unsigned char quiet; /* --quiet mode */ unsigned char verbose; /* --verbose mode */ unsigned char version; /* --version */ diff --git a/src/spa_comm.c b/src/spa_comm.c index 182886c6..3ccf2451 100644 --- a/src/spa_comm.c +++ b/src/spa_comm.c @@ -31,96 +31,134 @@ unsigned short chksum(unsigned short *buf, int nbytes) { - unsigned int sum; - unsigned short oddbyte; + unsigned int sum; + unsigned short oddbyte; - sum = 0; - while (nbytes > 1) { - sum += *buf++; - nbytes -= 2; - } + sum = 0; + while (nbytes > 1) + { + sum += *buf++; + nbytes -= 2; + } - if (nbytes == 1) { - oddbyte = 0; - *((unsigned short *) &oddbyte) = *(unsigned short *) buf; - sum += oddbyte; - } + if (nbytes == 1) + { + oddbyte = 0; + *((unsigned short *) &oddbyte) = *(unsigned short *) buf; + sum += oddbyte; + } - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); - return (unsigned short) ~sum; + return (unsigned short) ~sum; } /* Send the SPA data via UDP packet. */ int -send_spa_packet_udp(fko_ctx_t ctx, struct sockaddr_in *saddr, +send_spa_packet_udp(char *spa_data, int sd_len, struct sockaddr_in *saddr, struct sockaddr_in *daddr, fko_cli_options_t *options) { - int res; - char *spa_data; + int sock, res; - int sock = socket(AF_INET, SOCK_DGRAM, 0); + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) { - fprintf(stderr, "[*] Could not create UDP socket.\n"); - return(0); - } - - res = fko_get_spa_data(ctx, &spa_data); - - if(res != FKO_SUCCESS) + if (sock < 0) { - fprintf(stderr, - "send_spa_packet_udp: Error #%i from fko_get_spa_data: %s\n", - res, fko_errstr(res) - ); - return(0); + perror("[*] send_spa_packet_udp: create socket: "); + return(sock); } - return(sendto(sock, spa_data, strlen(spa_data), 0, - (struct sockaddr *)daddr, sizeof(*daddr))); + res = sendto(sock, spa_data, sd_len, 0, + (struct sockaddr *)daddr, sizeof(*daddr)); + + if(res < 0) + { + perror("[*] send_spa_packet_udp: sendto error: "); + } + else if(res != sd_len) + { + fprintf(stderr, "[#] Warning: bytes sent (%i) not spa data length (%i).\n", + res, sd_len); + } + + close(sock); + + return(res); } -/* Send the SPA data via TCP packet. +/* Send the SPA data packet via an established TCP connection. */ int -send_spa_packet_tcp(fko_ctx_t ctx, struct sockaddr_in *saddr, +send_spa_packet_tcp(char *spa_data, int sd_len, struct sockaddr_in *saddr, struct sockaddr_in *daddr, fko_cli_options_t *options) { int res; + + int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock < 0) + { + perror("[*] send_spa_packet_tcp: create socket: "); + return(sock); + } + + res = connect(sock, (struct sockaddr *)daddr, sizeof(*daddr)); + if(res < 0) + { + perror("[*] send_spa_packet_tcp: connect: "); + close(sock); + return(-1); + } + + res = send(sock, spa_data, sd_len, 0); + + if(res < 0) + { + perror("[*] send_spa_packet_tcp: send error: "); + } + else if(res != sd_len) + { + fprintf(stderr, "[#] Warning: bytes sent (%i) not spa data length (%i).\n", + res, sd_len); + } + + close(sock); + + return(res); +} + +/* Send the SPA data via raw TCP packet. +*/ +int +send_spa_packet_tcp_raw(char *spa_data, int sd_len, struct sockaddr_in *saddr, + struct sockaddr_in *daddr, fko_cli_options_t *options) +{ +#ifdef WIN32 + fprintf(stderr, "[*] send_spa_packet_tcp_raw: raw packets are not yet supported.\n"); + return(-1); +#else + int sock, res; char pkt_data[2048] = {0}; /* Should be enough for our purposes */ - char *spa_data; - int sd_len; struct iphdr *iph = (struct iphdr *) pkt_data; struct tcphdr *tcph = (struct tcphdr *) (pkt_data + sizeof (struct iphdr)); int hdrlen = sizeof(struct iphdr) + sizeof(struct tcphdr); - char one = 1; + /* Values for setsockopt. + */ + int one = 1; + const int *so_val = &one; - int sock = socket (PF_INET, SOCK_RAW, IPPROTO_RAW); - - if (sock < 0) { - fprintf(stderr, "[*] Could not create UDP socket. Error = %i\n", errno); - return(0); - } - - res = fko_get_spa_data(ctx, &spa_data); - - if(res != FKO_SUCCESS) + sock = socket (PF_INET, SOCK_RAW, IPPROTO_RAW); + if (sock < 0) { - fprintf(stderr, - "send_spa_packet_tcp: Error #%i from fko_get_spa_data: %s\n", - res, fko_errstr(res) - ); - return(0); + perror("[*] send_spa_packet_tcp_raw: create socket: "); + return(sock); } - sd_len = strlen(spa_data); - /* Put the spa data in place. */ memcpy((pkt_data + hdrlen), spa_data, sd_len); @@ -170,51 +208,60 @@ send_spa_packet_tcp(fko_ctx_t ctx, struct sockaddr_in *saddr, /* Make sure the kernel knows the header is included in the data so it * doesn't try to insert its own header into the packet. */ - if ((res = setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one))) < 0) - fprintf (stderr, "[*] send_spa_packet_tcp: setsockopt: error %i - Cannot set HDRINCL!\n", errno); + if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, so_val, sizeof(one)) < 0) + perror("[*] send_spa_packet_tcp_raw: setsockopt HDRINCL: "); - return(sendto (sock, pkt_data, iph->tot_len, 0, - (struct sockaddr *)daddr, sizeof(*daddr))); + res = sendto (sock, pkt_data, iph->tot_len, 0, + (struct sockaddr *)daddr, sizeof(*daddr)); + + if(res < 0) + { + perror("[*] send_spa_packet_tcp_raw: sendto error: "); + } + else if(res != sd_len) + { + fprintf(stderr, "[#] Warning: bytes sent (%i) not spa data length (%i).\n", + res, sd_len); + } + + close(sock); + + return(res); + +#endif /* !WIN32 */ } /* Send the SPA data via ICMP packet. */ int -send_spa_packet_icmp(fko_ctx_t ctx, struct sockaddr_in *saddr, +send_spa_packet_icmp(char *spa_data, int sd_len, struct sockaddr_in *saddr, struct sockaddr_in *daddr, fko_cli_options_t *options) { +#ifdef WIN32 + fprintf(stderr, "[*] send_spa_packet_icmp: raw packets are not yet supported.\n"); + return(-1); +#else int res; char pkt_data[2048] = {0}; - char *spa_data; - int sd_len; struct iphdr *iph = (struct iphdr *) pkt_data; struct icmphdr *icmph = (struct icmphdr *) (pkt_data + sizeof (struct iphdr)); int hdrlen = sizeof(struct iphdr) + sizeof(struct icmphdr); - char one = 1; + /* Values for setsockopt. + */ + int one = 1; + const int *so_val = &one; int sock = socket (PF_INET, SOCK_RAW, IPPROTO_RAW); - if (sock < 0) { - fprintf(stderr, "[*] Could not create UDP socket. Error = %i\n", errno); - return(0); - } - - res = fko_get_spa_data(ctx, &spa_data); - - if(res != FKO_SUCCESS) + if (sock < 0) { - fprintf(stderr, - "send_spa_packet_tcp: Error #%i from fko_get_spa_data: %s\n", - res, fko_errstr(res) - ); - return(0); + perror("[*] send_spa_packet_icmp: create socket: "); + return(sock); } - sd_len = strlen(spa_data); - /* Put the spa data in place. */ memcpy((pkt_data + hdrlen), spa_data, sd_len); @@ -250,11 +297,27 @@ send_spa_packet_icmp(fko_ctx_t ctx, struct sockaddr_in *saddr, /* Make sure the kernel knows the header is included in the data so it * doesn't try to insert its own header into the packet. */ - if ((res = setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one))) < 0) - fprintf (stderr, "[*] send_spa_packet_tcp: setsockopt: error %i - Cannot set HDRINCL!\n", errno); + if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, so_val, sizeof(one)) < 0) + perror("[*] send_spa_packet_icmp: setsockopt HDRINCL: "); - return(sendto (sock, pkt_data, iph->tot_len, 0, - (struct sockaddr *)daddr, sizeof(*daddr))); + res = sendto (sock, pkt_data, iph->tot_len, 0, + (struct sockaddr *)daddr, sizeof(*daddr)); + + if(res < 0) + { + perror("[*] send_spa_packet_icmp: sendto error: "); + } + else if(res != sd_len) + { + fprintf(stderr, "[#] Warning: bytes sent (%i) not spa data length (%i).\n", + res, sd_len); + } + + close(sock); + + return(res); + +#endif /* !WIN32 */ } /* Function used to send the SPA data. @@ -262,12 +325,33 @@ send_spa_packet_icmp(fko_ctx_t ctx, struct sockaddr_in *saddr, int send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options) { - int rv = 0; - struct sockaddr_in saddr, daddr; + int res, sd_len; + char *spa_data; + + struct sockaddr_in saddr, daddr; #ifdef WIN32 WSADATA wsa_data; +#endif + /* Get our spa data here. + */ + res = fko_get_spa_data(ctx, &spa_data); + + if(res != FKO_SUCCESS) + { + fprintf(stderr, + "send_spa_packet: Error #%i from fko_get_spa_data: %s\n", + res, fko_errstr(res) + ); + return(-1); + } + + sd_len = strlen(spa_data); + +#ifdef WIN32 + /* Winsock needs to be initialized... + */ rv = WSAStartup( MAKEWORD(1,1), &wsa_data ); if( rv != 0 ) { @@ -276,15 +360,13 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options) } #endif - /* initialize to zeros - */ memset(&saddr, 0, sizeof(saddr)); memset(&daddr, 0, sizeof(daddr)); saddr.sin_family = AF_INET; daddr.sin_family = AF_INET; - /* set source address and port + /* Set source address and port */ if (options->src_port) saddr.sin_port = htons(options->src_port); @@ -296,18 +378,39 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options) else saddr.sin_addr.s_addr = INADDR_ANY; /* default */ - /* set destination address and port */ + /* Set destination address and port + */ daddr.sin_port = htons(options->port); daddr.sin_addr.s_addr = inet_addr(options->spa_server_ip_str); - if (options->proto == IPPROTO_UDP) - rv = send_spa_packet_udp(ctx, &saddr, &daddr, options); - else if (options->proto == IPPROTO_TCP) - rv = send_spa_packet_tcp(ctx, &saddr, &daddr, options); - else if (options->proto == IPPROTO_ICMP) - rv = send_spa_packet_icmp(ctx, &saddr, &daddr, options); + errno = 0; - return rv; + switch (options->proto) + { + case FKO_PROTO_UDP: + res = send_spa_packet_udp(spa_data, sd_len, &saddr, &daddr, options); + break; + + case FKO_PROTO_TCP: + res = send_spa_packet_tcp(spa_data, sd_len, &saddr, &daddr, options); + break; + + case FKO_PROTO_TCP_RAW: + res = send_spa_packet_tcp_raw(spa_data, sd_len, &saddr, &daddr, options); + break; + + case FKO_PROTO_ICMP: + res = send_spa_packet_icmp(spa_data, sd_len, &saddr, &daddr, options); + break; + + default: + /* --DSS XXX: What to we really want to do here? */ + fprintf(stderr, "[*] %i is not a valid or supported protocol.\n", + options->proto); + res = -1; + } + + return res; } /* Function to write SPA packet data to the filesystem @@ -318,17 +421,6 @@ int write_spa_packet_data(fko_ctx_t ctx, fko_cli_options_t *options) char *spa_data; int res; - if (options->save_packet_file_append) { - if((fp = fopen(options->save_packet_file, "a")) == NULL) { - return 0; - } - } else { - unlink(options->save_packet_file); - if((fp = fopen(options->save_packet_file, "w")) == NULL) { - return 0; - } - } - res = fko_get_spa_data(ctx, &spa_data); if(res != FKO_SUCCESS) @@ -337,7 +429,24 @@ int write_spa_packet_data(fko_ctx_t ctx, fko_cli_options_t *options) "write_spa_packet_data: Error #%i from fko_get_spa_data: %s\n", res, fko_errstr(res) ); - exit(1); + + return(-1); + } + + if (options->save_packet_file_append) + { + fp = fopen(options->save_packet_file, "a"); + } + else + { + unlink(options->save_packet_file); + fp = fopen(options->save_packet_file, "w"); + } + + if(fp == NULL) + { + perror("write_spa_packet_data: "); + return(-1); } fprintf(fp, "%s\n", @@ -345,7 +454,7 @@ int write_spa_packet_data(fko_ctx_t ctx, fko_cli_options_t *options) fclose(fp); - return 1; + return(1); } /***EOF***/ diff --git a/src/spa_comm.h b/src/spa_comm.h index 4e8b4689..edf3c50c 100644 --- a/src/spa_comm.h +++ b/src/spa_comm.h @@ -39,12 +39,107 @@ #endif #endif -#include -#include -#include -#include +/* We will roll our own packet header structs. */ + +/* The IP header +*/ +struct iphdr +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int ihl:4; + unsigned int version:4; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned int version:4; + unsigned int ihl:4; +#else + #error "Please fix " +#endif + unsigned char tos; + unsigned short tot_len; + unsigned short id; + unsigned short frag_off; + unsigned char ttl; + unsigned char protocol; + unsigned short check; + unsigned int saddr; + unsigned int daddr; +}; -/* Prototypes +/* The TCP header +*/ +struct tcphdr +{ + unsigned short source; + unsigned short dest; + unsigned int seq; + unsigned int ack_seq; +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned short res1:4; + unsigned short doff:4; + unsigned short fin:1; + unsigned short syn:1; + unsigned short rst:1; + unsigned short psh:1; + unsigned short ack:1; + unsigned short urg:1; + unsigned short res2:2; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned short doff:4; + unsigned short res1:4; + unsigned short res2:2; + unsigned short urg:1; + unsigned short ack:1; + unsigned short psh:1; + unsigned short rst:1; + unsigned short syn:1; + unsigned short fin:1; +#else + #error "Adjust your defines" +#endif + unsigned short window; + unsigned short check; + unsigned short urg_ptr; +}; + +/* The ICMP header +*/ +struct icmphdr +{ + unsigned char type; /* message type */ + unsigned char code; /* type sub-code */ + unsigned short checksum; + union + { + struct + { + unsigned short id; + unsigned short sequence; + } echo; /* echo datagram */ + unsigned int gateway; /* gateway address */ + struct + { + unsigned short __unused; + unsigned short mtu; + } frag; /* path mtu discovery */ + } un; +}; + +#define ICMP_ECHOREPLY 0 /* Echo Reply */ +#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ +#define ICMP_SOURCE_QUENCH 4 /* Source Quench */ +#define ICMP_REDIRECT 5 /* Redirect (change route) */ +#define ICMP_ECHO 8 /* Echo Request */ +#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ +#define ICMP_PARAMETERPROB 12 /* Parameter Problem */ +#define ICMP_TIMESTAMP 13 /* Timestamp Request */ +#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ +#define ICMP_INFO_REQUEST 15 /* Information Request */ +#define ICMP_INFO_REPLY 16 /* Information Reply */ +#define ICMP_ADDRESS 17 /* Address Mask Request */ +#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ + + +/* Function Prototypes */ int send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options); int write_spa_packet_data(fko_ctx_t ctx, fko_cli_options_t *options);