S.ringAccount("remotes",P->getRemote());
if((P->d.opcode != Opcode::Notify) && PC.get(P,&cached)) { // short circuit - does the PacketCache recognize this question?
- cached.setRemote((struct sockaddr *)(P->remote),P->d_socklen); // inlined
+ cached.setRemote(&P->remote); // inlined
cached.setSocket(P->getSocket()); // inlined
cached.spoofID(P->d.id); // inlined
cached.d.rd=P->d.rd; // copy in recursion desired bit
int CommunicatorClass::doNotifications()
{
- struct sockaddr_in from;
+ ComboAddress from;
Utility::socklen_t fromlen=sizeof(from);
char buffer[1500];
int size;
while((size=recvfrom(d_nsock,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&fromlen))>0) {
DNSPacket p;
- p.setRemote((struct sockaddr *)&from, fromlen);
+ p.setRemote(&from);
if(p.parse(buffer,size)<0) {
L<<Logger::Warning<<"Unable to parse SOA notification answer from "<<p.getRemote()<<endl;
int addrlen=sizeof(sa);
getsockname(d_socket, (struct sockaddr *)&sa, (socklen_t *)&addrlen);
- return sockAddrToString(&sa);
+ return sockAddrToString((struct sockaddr_in*)&sa);
}
string DNSPacket::getRemote() const
{
- return sockAddrToString((struct sockaddr_in *)remote);
+ return remote.toString();
}
uint16_t DNSPacket::getRemotePort() const
{
- if(d_socklen==sizeof(sockaddr_in))
- return ((struct sockaddr_in*)remote)->sin_port;
- return 0;
+ return remote.sin4.sin_port;
}
void DNSPacket::trim()
{
DLOG(L<<"DNSPacket copy constructor called!"<<endl);
d_socket=orig.d_socket;
- memcpy(remote, orig.remote, sizeof(remote));
+ remote=orig.remote;
len=orig.len;
d_qlen=orig.d_qlen;
d_dt=orig.d_dt;
DNSPacket *r=new DNSPacket;
r->setSocket(d_socket);
- r->setRemote((struct sockaddr *)remote, d_socklen);
+ r->setRemote(&remote);
r->setAnswer(true); // this implies the allocation of the header
r->setA(true); // and we are authoritative
r->setRA(0); // no recursion available
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
+#include "iputils.hh"
#ifndef WIN32
#include <sys/socket.h>
unsigned int arcount:16; //!< number of additional resource records
};
- inline void setRemote(const struct sockaddr *a, Utility::socklen_t socklen);
+ inline void setRemote(const ComboAddress*);
string getLocal() const;
string getRemote() const;
uint16_t getRemotePort() const;
//////// DATA !
- char remote[sizeof(sockaddr_in6)];
+ ComboAddress remote;
Utility::socklen_t d_socklen; // 4
uint16_t len; //!< length of the raw binary packet 2
uint16_t qclass; //!< class of the question - should always be INternet 2
}
//! Use this to set where this packet was received from or should be sent to
-inline void DNSPacket::setRemote(const struct sockaddr *s, Utility::socklen_t socklen)
+inline void DNSPacket::setRemote(const ComboAddress *s)
{
- if(socklen>(Utility::socklen_t)sizeof(remote))
- throw AhuException("Address too long for storage: "+itoa(socklen));
-
- memcpy((void *)remote,(void *)s,socklen);
- d_socklen=socklen;
+ remote=*s;
}
inline void DNSPacket::spoofID(uint16_t id)
bool DNSProxy::recurseFor(DNSPacket* p)
{
- return d_ng.match((struct sockaddr_in *)&p->remote);
+ return d_ng.match((ComboAddress *)&p->remote);
}
/** returns false if p->remote is not allowed to recurse via us */
int main(int argc, char** argv)
try
{
- PcapPacketReader pr(argv[1]);
Socket sock(InterNetwork, Datagram);
+ /*
IPEndpoint remote(argc > 2 ? argv[2] : "127.0.0.1",
argc > 3 ? atoi(argv[3]) : 5300);
+ */
- while(pr.getUDPPacket()) {
- try {
- MOADNSParser mdp((const char*)pr.d_payload, pr.d_len);
- for(int i=0; i < mdp.d_qname.length(); ++i)
- if(!isalnum(mdp.d_qname[i]) && mdp.d_qname[i]!='.' && mdp.d_qname[i]!='-' && mdp.d_qname[i]!='_') {
- // cout<<mdp.d_qname<<"|"<<mdp.d_qtype<<"|"<<mdp.d_qclass<<"\n";
- // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
- break;
+ if(argc<2) {
+ cerr<<"Syntax: dnsscan file1 [file2 ..] "<<endl;
+ exit(1);
+ }
+
+ for(int n=1; n < argc; ++n) {
+ PcapPacketReader pr(argv[n]);
+
+ while(pr.getUDPPacket()) {
+ try {
+ MOADNSParser mdp((const char*)pr.d_payload, pr.d_len);
+ for(int i=0; i < mdp.d_qname.length(); ++i)
+ if(!isalnum(mdp.d_qname[i]) && mdp.d_qname[i]!='.' && mdp.d_qname[i]!='-' && mdp.d_qname[i]!='_') {
+ // cout<<mdp.d_qname<<"|"<<mdp.d_qtype<<"|"<<mdp.d_qclass<<"\n";
+ // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
+ break;
+ }
+ if(mdp.d_qtype > 256 || mdp.d_qclass!=1 ) {
+ // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
+
}
- if(mdp.d_qtype > 256 || mdp.d_qclass!=1 ) {
- // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
-
+ for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) {
+
+ }
+
}
- for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) {
-
+ catch(MOADNSException &e) {
+ cout<<"Error from remote "<<U32ToIP(ntohl(*((uint32_t*)&pr.d_ip->ip_src)))<<": "<<e.what()<<"\n";
+ // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
}
-
- }
- catch(MOADNSException &e) {
- cout<<"Error: "<<e.what()<<"\n";
- sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
}
}
}
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002 PowerDNS.COM BV
+ Copyright (C) 2002 - 2006 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
#include <stdio.h>
#include <functional>
#include "ahuexception.hh"
+#include "misc.hh"
using namespace std;
p=new DNSPacket(*p);
p->truncate(512);
buffer=p->getData();
- if(sendto(p->getSocket(),buffer,p->len,0,(struct sockaddr *)(p->remote),p->d_socklen)<0)
+ if(sendto(p->getSocket(),buffer,p->len,0,(struct sockaddr *)(&p->remote),p->d_socklen)<0)
L<<Logger::Error<<"Error sending reply with sendto (socket="<<p->getSocket()<<"): "<<strerror(errno)<<endl;
delete p;
}
else {
- if(sendto(p->getSocket(),buffer,p->len,0,(struct sockaddr *)(p->remote),p->d_socklen)<0)
+ if(sendto(p->getSocket(),buffer,p->len,0,(struct sockaddr *)(&p->remote),p->d_socklen)<0)
L<<Logger::Error<<"Error sending reply with sendto (socket="<<p->getSocket()<<"): "<<strerror(errno)<<endl;
}
}
inline DNSPacket *UDPNameserver::receive(DNSPacket *prefilled)
{
- char remote[ sizeof(sockaddr_in6) ];
+ ComboAddress remote;
extern StatBag S;
Utility::socklen_t addrlen;
char mesg[513];
Utility::sock_t sock=-1;
- memset( remote, 0, sizeof( remote ));
+ memset( &remote, 0, sizeof( remote ));
addrlen=sizeof(remote);
if(d_sockets.size()>1) {
fd_set rfds=d_rfds;
// XXX FIXME this code could be using recvmsg + ip_pktinfo on platforms that support it
- if((len=recvfrom(sock,mesg,sizeof(mesg)-1,0,(sockaddr*) remote, &addrlen))<0) {
+ if((len=recvfrom(sock,mesg,sizeof(mesg)-1,0,(sockaddr*) &remote, &addrlen))<0) {
L<<Logger::Error<<"recvfrom gave error, ignoring: "<<strerror(errno)<<endl;
return 0;
}
sock=d_sockets[0];
len=0;
- if((len=recvfrom(sock,mesg,512,0,(sockaddr*) remote, &addrlen))<0) {
+ if((len=recvfrom(sock,mesg,512,0,(sockaddr*) &remote, &addrlen))<0) {
L<<Logger::Error<<"recvfrom gave error, ignoring: "<<strerror(errno)<<endl;
return 0;
}
}
- DLOG(L<<"Received a packet " << len <<" bytes long from "<<inet_ntoa( reinterpret_cast< sockaddr_in * >( &remote )->sin_addr )<<endl);
+ DLOG(L<<"Received a packet " << len <<" bytes long from "<< remote.toString()<<endl);
DNSPacket *packet;
if(prefilled) // they gave us a preallocated packet
packet=new DNSPacket; // don't forget to free it!
packet->d_dt.set(); // timing
packet->setSocket(sock);
- packet->setRemote((struct sockaddr *)remote, addrlen);
+ packet->setRemote(&remote);
if(packet->parse(mesg, len)<0) {
S.inc("corrupt-packets");
S.ringAccount("remotes-corrupt", packet->getRemote());
struct in_addr inp;
Utility::inet_aton(ip.c_str(),&inp);
- d_toaddr.sin_addr.s_addr=inp.s_addr;
+ d_toaddr.sin4.sin_addr.s_addr=inp.s_addr;
- d_toaddr.sin_port=htons(port);
- d_toaddr.sin_family=AF_INET;
+ d_toaddr.sin4.sin_port=htons(port);
+ d_toaddr.sin4.sin_family=AF_INET;
d_sock=socket(AF_INET,SOCK_STREAM,0);
if(d_sock<0)
{
try {
DNSPacket p;
- p.setRemote((const sockaddr*)&d_toaddr, sizeof(d_toaddr));
+ p.setRemote(&d_toaddr);
p.d_tcp = d_inaxfr; // fixes debian bug 330184
if(p.parse((char *)d_buf, d_len)<0)
throw ResolverException("resolver: unable to parse packet of "+itoa(d_len)+" bytes");
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002 PowerDNS.COM BV
+ Copyright (C) 2002 - 2006 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
#include <string>
#include <vector>
#include <sys/types.h>
-
+#include "iputils.hh"
#ifndef WIN32
# include <arpa/nameser.h>
int d_timeout;
uint32_t d_ip;
bool d_inaxfr;
- struct sockaddr_in d_toaddr;
+ ComboAddress d_toaddr;
};
return -1;
set<GetBestNSAnswer> beenthere;
- int res=doResolve(qname, qtype, ret,0,beenthere);
+ int res=doResolve(qname, qtype, ret, 0, beenthere);
if(!res)
addCruft(qname, ret);
return res;
}
-int TCPNameserver::readLength(int fd, struct sockaddr_in *remote)
+int TCPNameserver::readLength(int fd, ComboAddress *remote)
{
int bytesLeft=2;
unsigned char buf[2];
while(bytesLeft) {
int ret=waitForData(fd, s_timeout);
if(ret<0)
- throw AhuException("Waiting on data from remote TCP client "+string(inet_ntoa(remote->sin_addr))+": "+stringerror());
+ throw AhuException("Waiting on data from remote TCP client "+remote->toString()+": "+stringerror());
ret=recv(fd, reinterpret_cast< char * >( buf ) +2-bytesLeft, bytesLeft,0);
if(ret<0)
- throw AhuException("Trying to read data from remote TCP client "+string(inet_ntoa(remote->sin_addr))+": "+stringerror());
+ throw AhuException("Trying to read data from remote TCP client "+remote->toString()+": "+stringerror());
if(!ret) {
- DLOG(L<<"Remote TCP client "+string(inet_ntoa(remote->sin_addr))+" closed connection");
+ DLOG(L<<"Remote TCP client "+remote->toString()+" closed connection");
return -1;
}
bytesLeft-=ret;
return buf[0]*256+buf[1];
}
-void TCPNameserver::getQuestion(int fd, char *mesg, int pktlen, const struct sockaddr_in &remote)
+void TCPNameserver::getQuestion(int fd, char *mesg, int pktlen, const ComboAddress &remote)
{
int ret=0, bytesread=0;
while(bytesread<pktlen) {
err:;
if(ret<0)
- throw AhuException("Error reading DNS data from TCP client "+string(inet_ntoa(remote.sin_addr))+": "+stringerror());
+ throw AhuException("Error reading DNS data from TCP client "+remote.toString()+": "+stringerror());
else
- throw AhuException("Remote TCP client "+string(inet_ntoa(remote.sin_addr))+" closed connection");
+ throw AhuException("Remote TCP client "+remote.toString()+" closed connection");
}
void *TCPNameserver::doConnection(void *data)
DLOG(L<<"TCP Connection accepted on fd "<<fd<<endl);
for(;;) {
- struct sockaddr_in remote;
+ ComboAddress remote;
int pktlen=readLength(fd, &remote);
if(pktlen<0) // EOF
break;
if(pktlen>511) {
- L<<Logger::Error<<"Received an overly large question from "<<inet_ntoa(remote.sin_addr)<<", dropping"<<endl;
+ L<<Logger::Error<<"Received an overly large question from "<<remote.toString()<<", dropping"<<endl;
break;
}
packet=new DNSPacket;
- packet->setRemote((struct sockaddr *)&remote,sizeof(remote));
+ packet->setRemote(&remote);
packet->d_tcp=true;
if(packet->parse(mesg, pktlen)<0)
break;
DNSPacket* cached=new DNSPacket;
if(!packet->d.rd && (PC.get(packet, cached))) { // short circuit - does the PacketCache recognize this question?
- cached->setRemote((struct sockaddr *)(packet->remote), sizeof(struct sockaddr_in));
+ cached->setRemote(&packet->remote);
cached->spoofID(packet->d.id);
if(sendDelPacket(cached, fd)<0)
goto out;
if(arg().mustDo("disable-axfr"))
return false;
- if( arg()["allow-axfr-ips"].empty() || d_ng.match( (struct sockaddr_in *) &q->remote ) )
+ if( arg()["allow-axfr-ips"].empty() || d_ng.match( (ComboAddress *) &q->remote ) )
return true;
extern CommunicatorClass Communicator;
private:
static int sendDelPacket(DNSPacket *p, int outsock);
- static int readLength(int fd, struct sockaddr_in *remote);
- static void getQuestion(int fd, char *mesg, int pktlen, const struct sockaddr_in &remote);
+ static int readLength(int fd, ComboAddress *remote);
+ static void getQuestion(int fd, char *mesg, int pktlen, const ComboAddress& remote);
static int doAXFR(const string &target, DNSPacket *q, int outsock);
static bool canDoAXFR(DNSPacket *q);
static void *doConnection(void *data);