From b39da562da7f3a29acb6ba360939ebc4bce4cfdc Mon Sep 17 00:00:00 2001 From: "fredrik@DOLDA2000.COM" Date: Fri, 29 Apr 2005 00:42:03 +0000 Subject: [PATCH] First should-be-working version. git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/icmp-dn@213 959494ce-11ee-0310-bf91-de5d638817bd --- icmpdnd.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/icmpdnd.c b/icmpdnd.c index 0169e6d..3fa1792 100644 --- a/icmpdnd.c +++ b/icmpdnd.c @@ -1,6 +1,6 @@ /* * icmpdnd - ICMP Domain Name responder daemon for Linux - * Copyright (C) 2004 Fredrik Tolf + * Copyright (C) 2005 Fredrik Tolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -53,8 +54,6 @@ struct rephdr { #define ICMP_NAMEREQ 37 #define ICMP_NAMEREP 38 -#define TTL 3600 - volatile int alive; size_t filldn(char *dst) @@ -131,18 +130,43 @@ void cksum(void *hdr, size_t len) int main(int argc, char **argv) { int ret; - int s, namelen, datalen; + int c, s, namelen, datalen; + int daemonize, ttl; unsigned char buf[65536]; struct sockaddr_in name; struct reqhdr req; struct rephdr rep; struct iphdr iphdr; - + + daemonize = 1; + ttl = 3600; + while((c = getopt(argc, argv, "nht:")) != -1) { + switch(c) { + case 't': + ttl = atoi(optarg); + break; + case 'n': + daemonize = 0; + break; + case 'h': + case '?': + case ':': + default: + fprintf(stderr, "usage: icmpdnd [-n]"); + exit((c == 'h')?0:1); + } + } + if((s = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { perror("could not create raw socket"); exit(1); } + if(daemonize) + daemon(0, 0); + + openlog("icmpdnd", LOG_PID, LOG_DAEMON); + alive = 1; while(alive) { namelen = sizeof(name); @@ -150,32 +174,32 @@ int main(int argc, char **argv) if(ret < 0) { if(errno == EINTR) continue; - perror("recvfrom"); + syslog(LOG_ERR, "error in receiving datagram: %m"); exit(1); } - if(ret < sizeof(iphdr)) + if(ret < sizeof(iphdr) + sizeof(req)) continue; memcpy(&iphdr, buf, sizeof(iphdr)); + memcpy(&req, buf + sizeof(iphdr), sizeof(req)); if(iphdr.protocol != IPPROTO_ICMP) continue; - if(ret < sizeof(iphdr) + sizeof(req)) - continue; - memcpy(&req, buf + sizeof(iphdr), sizeof(req)); if(req.type != ICMP_NAMEREQ) continue; rep.type = ICMP_NAMEREP; rep.code = 0; rep.id = req.id; rep.seq = req.seq; - rep.ttl = htonl(TTL); + rep.ttl = htonl(ttl); memcpy(buf, &rep, sizeof(rep)); datalen = filldn(buf + sizeof(rep)); - + cksum(buf, datalen + sizeof(rep)); - + + /* XXX: The correct source address needs to be filled in from + * the request's destination address. */ ret = sendto(s, buf, datalen + sizeof(rep), 0, (struct sockaddr *)&name, namelen); if(ret < 0) { - perror("sendto"); + syslog(LOG_WARNING, "error in sending reply: %m"); exit(1); } } -- 2.11.0