diff options
Diffstat (limited to 'src/ipmunge.c')
-rw-r--r-- | src/ipmunge.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/ipmunge.c b/src/ipmunge.c new file mode 100644 index 0000000..44212e0 --- /dev/null +++ b/src/ipmunge.c @@ -0,0 +1,106 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include <netinet/in.h> +#include <arpa/inet.h> +#include "md5.h" + +static void +usage() +{ + fprintf(stderr, "usage: ipmunge [-s data] templ mask\n"); + exit(2); +} + +static int +md5_file(FILE* f, MD5_CTX *ctx) +{ + #define BUF_SIZE 128 + unsigned char buf[BUF_SIZE]; + int r, read = 0; + + while(!feof(f)) + { + r = fread(buf, 1, BUF_SIZE, f); + + if(ferror(f)) + err(1, "couldn't read input data"); + + read += r; + MD5Update(ctx, buf, r); + } + + return read; +} + +int +main(int argc, char* argv[]) +{ + MD5_CTX ctx; + struct in_addr templ; + struct in_addr mask; + struct in_addr result; + const char* data = NULL; + int ch, l, i; + int count = 1; + + memset(&result, 0, sizeof(result)); + memset(&mask, 0, sizeof(mask)); + memset(&templ, 0, sizeof(templ)); + + while((ch = getopt(argc, argv, "s:")) != -1) + { + switch(ch) + { + case 's': + data = optarg; + break; + case '?': + default: + usage(); + break; + } + } + + argc -= optind; + argv += optind; + + if(argc != 2) + usage(); + + if(!inet_aton(argv[0], &templ)) + errx(1, "invalid template address: %s", argv[0]); + + if(!inet_aton(argv[1], &mask)) + errx(1, "invalid template mask: %s", argv[1]); + + MD5Init(&ctx); + + if(data) + { + l = strlen(data); + MD5Update(&ctx, data, l); + } + else + { + l = md5_file(stdin, &ctx); + } + + if(l > 0) + { + unsigned char md[MD5_DIGEST_LENGTH]; + MD5Final(md, &ctx); + memcpy(&result, md, sizeof(result)); + } + + result.s_addr = result.s_addr & ~mask.s_addr; + result.s_addr = result.s_addr | (templ.s_addr & mask.s_addr); + + printf("%s\n", inet_ntoa(result)); + + return 0; +} |