📄 domain.c
字号:
qrrp = make_rr(RR_QUERY,sname,CLASS_IN,dtype,0,0,NULL);
SysLfree(sname);
while(looping > 0){
if((result_rrlp=resolver(qrrp)) == NULL
|| result_rrlp->type == dtype)
break;
/* Should be CNAME or PTR record */
/* Replace name and try again */
SysLfree(qrrp->name);
qrrp->name = strdup(result_rrlp->rdata.name);
free_rr(result_rrlp);
result_rrlp = NULL;
looping--;
}
free_rr(qrrp);
return result_rrlp;
}
/* main entry point for address -> domain name resolution.
* Returns string, or NULL if no name found.
*/
char *resolve_a(int32 ip_address, int shorten)
//int32 ip_address; /* search address */
//int shorten; /* return only first part of name (flag)*/
{
struct rr *save_rrlp, *rrlp;
char *result = NULL;
for( rrlp = save_rrlp = inverse_a(ip_address);
rrlp != NULL && result == NULL;
rrlp = rrlp->next ){
if(rrlp->rdlength > 0){
switch(rrlp->type){
case TYPE_PTR:
result = strdup(rrlp->rdata.name);
break;
case TYPE_A:
result = strdup(rrlp->name);
break;
}
}
}
free_rr(save_rrlp);
if(result != NULL && shorten){
int dot;
char *shortened;
if((dot = strcspn(result, ".")) == 0){
shortened = (char *)SysLcalloc(dot+1);
strncpy(shortened, result, dot);
shortened[dot] = '\0';
SysLfree(result);
result = shortened;
}
}
return result;
}
/* Main entry point for domain name -> address resolution.
* Returns 0 if name is currently unresolvable.
*/
int32 resolve(char *name)
{
register struct rr *rrlp;
int32 ip_address = 0;
if(name == NULL)
return 0;
if(isaddr(name))
// return atol(name);
return inet_addr(name);
if((rrlp = resolve_rr(name,TYPE_A)) != NULL
&& rrlp->rdlength > 0)
ip_address = rrlp->rdata.addr;
/* multi-homed hosts are handled here */
// if(rrlp != NULL && rrlp->next != NULL) {
// register struct rr *rrp;
// register struct route *rp;
// u_int16 cost = MAXINT16;
// rrp = rrlp;
/* choose the best of a set of routes */
// while(rrp != NULL) {
// if(rrp->rdlength > 0
// && (rp = rt_lookup(rrp->rdata.addr)) != NULL
// && rp->metric <= cost) {
// ip_address = rrp->rdata.addr;
// cost = rp->metric;
// }
// rrp = rrp->next;
// }
// }
free_rr(rrlp);
return ip_address;
}
/* Main entry point for MX record lookup.
* Returns 0 if name is currently unresolvable.
*/
int32 resolve_mx(char *name)
{
register struct rr *rrp, *arrp;
char *sname, *tmp, *cp;
int32 addr, ip_address = 0;
u_int16 pref = MAXINT16;
if(name == NULL)
return 0;
if(isaddr(name)){
if((sname = resolve_a(atol(name),FALSE)) == NULL)
return 0;
}
else
sname = strdup(name);
cp = sname;
while(1){
rrp = arrp = resolve_rr(sname,TYPE_MX);
/* Search this list of rr's for an MX record */
while(rrp != NULL){
if(rrp->rdlength > 0 && rrp->rdata.mx.pref <= pref &&
(addr = resolve(rrp->rdata.mx.exch)) != 0L){
pref = rrp->rdata.mx.pref;
ip_address = addr;
}
rrp = rrp->next;
}
free_rr(arrp);
if(ip_address != 0)
break;
/* Compose wild card one level up */
if((cp = (char *)strchr(cp,(int)'.')) == NULL)
break;
tmp = (char *)SysLcalloc(strlen(cp)+2);
sprintf(tmp,"*%s",cp); /* wildcard expansion */
SysLfree(sname);
sname = tmp;
cp = sname + 2;
}
SysLfree(sname);
return ip_address;
}
/* Search for local records of the MB, MG and MR type. Returns list of
* matching records.
*/
struct rr *resolve_mailb(char *name) /* local username, without trailing dot */
{
register struct rr *result_rrlp;
struct rr *rrlp;
char *sname;
/* Append trailing dot */
sname = (char *)SysLcalloc(strlen(name)+2);
sprintf(sname,"%s.",name);
rrlp = make_rr(RR_QUERY,sname,CLASS_IN,TYPE_MB,0,0,NULL);
rrlp->next = make_rr(RR_QUERY,sname,CLASS_IN,TYPE_MG,0,0,NULL);
rrlp->next->next = make_rr(RR_QUERY,sname,CLASS_IN,TYPE_MR,0,0,NULL);
SysLfree(sname);
if((result_rrlp = dcache_search(rrlp)) == NULL){
result_rrlp = dfile_search(rrlp);
}
free_rr(rrlp);
if(Dsuffix != NULL){
rrlp = result_rrlp;
while(rrlp != NULL){ /* add domain suffix to data */
if(rrlp->rdlength > 0 &&
rrlp->rdata.name[rrlp->rdlength-1] != '.'){
sname = (char *)SysLcalloc(rrlp->rdlength +
strlen(Dsuffix)+2);
sprintf(sname,"%s.%s",rrlp->rdata.name,Dsuffix);
SysLfree(rrlp->rdata.name);
rrlp->rdata.name = sname;
rrlp->rdlength = (unsigned short)(strlen(sname));
}
rrlp = rrlp->next;
}
}
dcache_add(copy_rr_list(result_rrlp));
return result_rrlp;
}
/*>>>>>>>>>>>>>>>>>>>>APPEND FUNCTIONS<<<<<<<<<<<<<<<<<<<*/
/* Copy a string to a SysLmalloc'ed buffer. Turbo C has this one in its
* library, but it doesn't call SysLmalloc() and can therefore return NULL.
* NOS uses of strdup() generally don't check for NULL, so they need this one.
*/
char *strdup(const char *s)
{
register char *out;
register int len;
if(s == NULL)
return NULL;
len = strlen(s);
out = (char *)SysLcalloc(len+1);
/* This is probably a tad faster than strcpy, since we know the len */
memcpy(out,s,len);
out[len] = '\0';
return out;
}
/* Get the dns packet header from the data buf, return -1 if failed,
* return 0 if successful.
*/
int getdnshdr(struct dhdr *dhdr, u_char *buf)
{
u_int16 tmp;
register u_int16 i;
u_int8 *cp;
struct rr **rrpp;
dhdr->id = get16(&buf[0]);
tmp = get16(&buf[2]);
if(tmp & 0x8000)
dhdr->qr = 1;
dhdr->opcode = (tmp >> 11) & 0xf;
if(tmp & 0x0400)
dhdr->aa = 1;
if(tmp & 0x0200)
dhdr->tc = 1;
if(tmp & 0x0100)
dhdr->rd = 1;
if(tmp & 0x0080)
dhdr->ra = 1;
dhdr->rcode = tmp & 0xf;
dhdr->qdcount = get16(&buf[4]);
dhdr->ancount = get16(&buf[6]);
dhdr->nscount = get16(&buf[8]);
dhdr->arcount = get16(&buf[10]);
/* Now parse the variable length sections */
cp = &buf[12];
/* Question section */
rrpp = &dhdr->questions;
for(i=0;i<dhdr->qdcount;i++){
if((cp = (u_int8 *)getq(rrpp,buf,cp)) == NULL){
SysLfree(buf);
return -1;
}
(*rrpp)->source = RR_QUESTION;
rrpp = &(*rrpp)->next;
}
*rrpp = NULL;
/* Answer section */
rrpp = &dhdr->answers;
for(i=0;i<dhdr->ancount;i++){
if((cp = (u_int8 *)ntohrr(rrpp,buf,cp)) == NULL){
SysLfree(buf);
return -1;
}
(*rrpp)->source = RR_ANSWER;
rrpp = &(*rrpp)->next;
}
*rrpp = NULL;
/* Name server (authority) section */
rrpp = &dhdr->authority;
for(i=0;i<dhdr->nscount;i++){
if((cp = (u_int8 *)ntohrr(rrpp,buf,cp)) == NULL){
SysLfree(buf);
return -1;
}
(*rrpp)->source = RR_AUTHORITY;
rrpp = &(*rrpp)->next;
}
*rrpp = NULL;
/* Additional section */
rrpp = &dhdr->additional;
for(i=0;i<dhdr->arcount;i++){
if((cp = (u_int8 *)ntohrr(rrpp,buf,cp)) == NULL){
SysLfree(buf);
return -1;
}
(*rrpp)->source = RR_ADDITIONAL;
rrpp = &(*rrpp)->next;
}
*rrpp = NULL;
SysLfree(buf);
return 0;
}
static u_int8 *getq(rrpp,msg,cp)
struct rr **rrpp;
u_int8 *msg;
u_int8 *cp;
{
register struct rr *rrp;
int len;
char *name;
*rrpp = rrp = (struct rr *)SysLcalloc(sizeof(struct rr));
name = (char *)SysLcalloc(512);
len = dn_expand(msg,NULL,cp,name,512);
if(len == -1){
SysLfree(name);
return NULL;
}
cp += len;
rrp->name = strdup(name);
rrp->type = get16(cp);
cp += 2;
rrp->class = get16(cp);
cp += 2;
rrp->ttl = 0;
rrp->rdlength = 0;
SysLfree(name);
return cp;
}
/* Read a resource record from a domain message into a host structure */
static u_int8 *
ntohrr(rrpp,msg,cp)
struct rr **rrpp; /* Where to allocate resource record structure */
u_int8 *msg; /* Pointer to beginning of domain message */
u_int8 *cp; /* Pointer to start of encoded RR record */
{
register struct rr *rrp;
int len;
char *name;
*rrpp = rrp = (struct rr *)SysLcalloc(sizeof(struct rr));
name = (char *)SysLcalloc(512);
if((len = dn_expand(msg,NULL,cp,name,512)) == -1){
SysLfree(name);
return NULL;
}
cp += len;
rrp->name = strdup(name);
rrp->type = get16(cp);
cp += 2;
rrp->class = get16(cp);
cp+= 2;
rrp->ttl = get32(cp);
cp += 4;
rrp->rdlength = get16(cp);
cp += 2;
switch(rrp->type){
case TYPE_A:
/* Just read the address directly into the structure */
rrp->rdata.addr = get32(cp);
cp += 4;
break;
case TYPE_CNAME:
case TYPE_MB:
case TYPE_MG:
case TYPE_MR:
case TYPE_NS:
case TYPE_PTR:
/* These types all consist of a single domain name;
* convert it to ascii format
*/
len = dn_expand(msg,NULL,cp,name,512);
if(len == -1){
SysLfree(name);
return NULL;
}
rrp->rdata.name = strdup(name);
rrp->rdlength = (unsigned short)(strlen(name));
cp += len;
break;
case TYPE_HINFO:
len = *cp++;
rrp->rdata.hinfo.cpu = (char *)SysLcalloc(len+1);
strncpy(rrp->rdata.hinfo.cpu,(char *)cp,len);
cp += len;
len = *cp++;
rrp->rdata.hinfo.os = (char *)SysLcalloc(len+1);
strncpy(rrp->rdata.hinfo.os,(char *)cp,len);
cp += len;
break;
case TYPE_MX:
rrp->rdata.mx.pref = get16(cp);
cp += 2;
/* Get domain name of exchanger */
len = dn_expand(msg,NULL,cp,name,512);
if(len == -1){
SysLfree(name);
return NULL;
}
rrp->rdata.mx.exch = strdup(name);
cp += len;
break;
case TYPE_SOA:
/* Get domain name of name server */
len = dn_expand(msg,NULL,cp,name,512);
if(len == -1){
SysLfree(name);
return NULL;
}
rrp->rdata.soa.mname = strdup(name);
cp += len;
/* Get domain name of responsible person */
len = dn_expand(msg,NULL,cp,name,512);
if(len == -1){
SysLfree(name);
return NULL;
}
rrp->rdata.soa.rname = strdup(name);
cp += len;
rrp->rdata.soa.serial = get32(cp);
cp += 4;
rrp->rdata.soa.refresh = get32(cp);
cp += 4;
rrp->rdata.soa.retry = get32(cp);
cp += 4;
rrp->rdata.soa.expire = get32(cp);
cp += 4;
rrp->rdata.soa.minimum = get32(cp);
cp += 4;
break;
case TYPE_TXT:
/* Just stash */
rrp->rdata.data = (char *)SysLcalloc(rrp->rdlength);
memcpy(rrp->rdata.data,cp,rrp->rdlength);
cp += rrp->rdlength;
break;
default:
/* Ignore */
cp += rrp->rdlength;
break;
}
SysLfree(name);
return cp;
}
/* Convert a compressed domain name to the human-readable form */
static int
dn_expand(msg,eom,compressed,full,fullen)
u_int8 *msg; /* Complete domain message */
u_int8 *eom;
u_int8 *compressed; /* Pointer to compressed name */
char *full; /* Pointer to result buffer */
int fullen; /* Length of same */
{
unsigned int slen; /* Length of current segment */
register u_int8 *cp;
int clen = 0; /* Total length of compressed name */
int indirect = 0; /* Set if indirection encountered */
int nseg = 0; /* Total number of segments in name */
cp = compressed;
for(;;){
slen = *cp++; /* Length of this segment */
if(!indirect)
clen++;
if((slen & 0xc0) == 0xc0){
if(!indirect)
clen++;
indirect = 1;
/* Follow indirection */
cp = &msg[((slen & 0x3f)<<8) + *cp];
slen = *cp++;
}
if(slen == 0) /* zero length == all done */
break;
fullen -= slen + 1;
if(fullen < 0)
return -1;
if(!indirect)
clen += slen;
while(slen-- != 0)
*full++ = (char)*cp++;
*full++ = '.';
nseg++;
}
if(nseg == 0){
/* Root name; represent as single dot */
*full++ = '.';
fullen--;
}
*full++ = '\0';
fullen--;
return clen; /* Length of compressed message */
}
/* Put a long in host order into a char array in network order */
static u_int8 *put32(cp,x)
register u_int8 *cp;
int32 x;
{
*cp++ = (unsigned char)(x >> 24);
*cp++ = (unsigned char)(x >> 16);
*cp++ = (unsigned char)(x >> 8);
*cp++ = (unsigned char)x;
return cp;
}
/* Put a short in host order into a char array in network order */
static u_int8 *put16(cp,x)
register u_int8 *cp;
u_int16 x;
{
*cp++ = x >> 8;
*cp++ = (unsigned char)x;
return cp;
}
static u_int16 get16(u_int8 *cp)
{
register u_int16 x;
x = *cp++;
x <<= 8;
x |= *cp;
return x;
}
/* Machine-independent, alignment insensitive network-to-host long conversion */
static int32 get32(u_int8 *cp)
{
int32 rval;
rval = *cp++;
rval <<= 8;
rval |= *cp++;
rval <<= 8;
rval |= *cp++;
rval <<= 8;
rval |= *cp;
return rval;
}
int setint(var,label,argc,argv)
int *var;
char *label;
int argc;
char *argv[];
{
*var = atoi(argv[1]);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -