#include #include #include #include #include #include #include #include #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; }