/************************************************************************ * * * fakedns - Copyright 2008 Matteo Croce * * A fake DNS server that always replies the same IP for every hostname * * * ***********************************************************************/ #include #include #include #include #include #include #include const u_int8_t reply[] = { 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, }; int main(int argc, char *argv[]) { u_int8_t buffer[512] = {0}; int sockfd, recv; struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(53) }; struct sockaddr_in from; socklen_t sinsize = sizeof(from); struct in_addr addr; if (argc != 2) { fprintf(stderr, "usage: %s \n", *argv); return 1; } if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket()"); return 1; } inet_pton(AF_INET, argv[1], &addr); memset(&sin.sin_zero, 0, 8); if(bind(sockfd, (const struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("bind()"); return 1; } if(daemon(0, 0)) return 0; while(1) { recv = recvfrom(sockfd, buffer, 512, 0, (struct sockaddr *)&from, &sinsize); if(recv < 0) { perror("recv"); return 1; } memcpy(buffer + recv, reply, sizeof(reply)); memcpy(buffer + recv + sizeof(reply), &addr.s_addr, sizeof(addr.s_addr)); buffer[2] = 0x81; // DNS response buffer[3] = 0x80; buffer[7] = 1; recv = sendto(sockfd, buffer, recv + 16, 0, (struct sockaddr *)&from, sinsize); if(recv < 0) { perror("sendto"); return 1; } } return 0; }