/* return true if successful. */
/* */
/********************************************************/
-static _Bool checkmx(char *domain,AFNTYP *afnnum,char *seq)
+static _Bool checkmx(char *domain,AFNTYP *afnnum,char *mx)
{
+#define OPEP "gesspf.c:checkmx"
+
_Bool found;
+int cidr;
+char *mxdom;
+MXTYP **mxlist;
+struct addrinfo hints;
+int phase;
+_Bool proceed;
found=false;
+cidr=128;
+mxdom=domain;
+mxlist=(MXTYP **)0;
+(void) memset(&hints,'\000',sizeof(hints));
+hints.ai_family=PF_UNSPEC;
+hints.ai_socktype=SOCK_STREAM;
+hints.ai_flags=HINTFLG;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //getting the list of MX
+ if (mx!=(char *)0) { //always
+ char *ptr;
+
+ (void) printf("JMPDBG mx value=<%s>\n",mx);
+ if ((ptr=strchr(mx,'/'))!=(char *)0) {
+ *ptr='\000';
+ cidr=atoi(ptr+1);
+ }
+ if ((ptr=strchr(mx,':'))!=(char *)0) {
+ *ptr='\000';
+ mxdom=ptr+1;
+ }
+ }
+ break;
+ case 1 : //getting the list of MX for mxdomain
+ if ((mxlist=dns_getmx(mxdom))==(MXTYP **)0) {
+ (void) rou_alert(0,"%s empty MX list for domain <%s> (remote DNS config?)",
+ OPEP,mxdom);
+ phase=999; //trouble no need to go further
+ }
+ break;
+ case 2 : //getting the list of MX for mxdomain
+ for (int i=0;(found==false)&&(mxlist[i]!=(MXTYP *)0);i++) {
+ int status;
+ struct addrinfo *res;
+ struct addrinfo *rp;
+
+ status=getaddrinfo(mxlist[i]->mxname,"",&hints,&res);
+ if (status!=0) {
+ (void) rou_alert(0,"%s Unable to find addrinfo for <%s> (error=<%s>)",
+ OPEP,mxlist[i]->mxname,gai_strerror(status));
+ continue;
+ }
+ rp=res;
+ for (int j=0;rp!=(struct addrinfo *)0;rp=rp->ai_next,j++) {
+ AFNTYP *addrnum;
+
+ if ((addrnum=afn_getaddrinfo(rp))==(AFNTYP *)0) {
+ (void) rou_alert(0,"%s Found unknown inet family for <%s> IP number",
+ OPEP,mxlist[i]->mxname);
+ continue;
+ }
+ switch (afn_cmpipnum(addrnum,afnnum,cidr)) {
+ case false : //not found
+ break;
+ case true : //found
+ found=true;
+ break;
+ case -1 : //trouble?
+ (void) rou_alert(0,"%s Unable to compare MX IP for "
+ "host <%s> (error=<%s>)",
+ OPEP,mxlist[i]->mxname,strerror(errno));
+ break;
+ }
+ addrnum=afn_freeipnum(addrnum);
+ if (found==true)
+ break; //no need to loop further
+ }
+ (void) freeaddrinfo(res);
+ }
+ mxlist=dns_freemxlist(mxlist);
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
return found;
+
+#undef OPEP
}
/*
\f
spf=locspf;
break;
case mch_mx : //This is a MX refrence
- if (checkmx(domain,afnnum,seq+1)==true)
+ if (checkmx(domain,afnnum,seq)==true)
spf=locspf;
break;
case mch_ip4 : //This is IPV4 number
*/
/********************************************************/
/* */
+/* Routine to convert a addrinfo struct to an */
+/* IP number in AFNTYP structure. */
+/* */
+/********************************************************/
+PUBLIC AFNTYP *afn_getaddrinfo(struct addrinfo *rp)
+
+{
+AFNTYP *afnnum;
+
+afnnum=(AFNTYP *)0;
+if (rp!=(struct addrinfo *)0) {
+ u_char *ptr;
+
+ ptr=(u_char *)0;
+ afnnum=calloc(1,sizeof(AFNTYP));
+ afnnum->afntype=rp->ai_family;
+ switch (rp->ai_family) {
+ case AF_INET :
+ afnnum->afnmask=32;
+ ptr=(u_char *)&(((struct sockaddr_in *)rp->ai_addr)->sin_addr.s_addr);
+ break;
+ case AF_INET6 :
+ afnnum->afnmask=128;
+ ptr=(u_char *)&(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr.s6_addr);
+ break;
+ default : /*trouble trouble */
+ afnnum=afn_freeipnum(afnnum);
+ break;
+ }
+ if (ptr!=(u_char *)0)
+ (void) memmove(afnnum->ip,ptr,afnnum->afnmask/8);
+ }
+return afnnum;
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Routine to convert clean string to be */
/* IP number in AFNTYP structure. */
/* */
//space to store (at least) IPV6 number
#define AFT sizeof(struct in6_addr)
+#define HINTFLG AI_ALL|AI_CANONNAME|AI_CANONIDN
+
typedef struct {
char *strnumip; //IP in string format
int afntype; //IP type
//IP number
extern char *afn_stripnum(AFNTYP *afnnum);
+//procedure to convert a addrinfo struct to an
+//IP number in AFNTYP structure.
+extern AFNTYP *afn_getaddrinfo(struct addrinfo *rp);
+
//procedure to convert a IP as string to an AFNTYP structure
extern AFNTYP *afn_getipnum(char *cleanipstr);
*/
/********************************************************/
/* */
+/* Procedure to free memory used by a list of */
+/* MXTYP. */
+/* */
+/********************************************************/
+PUBLIC MXTYP **dns_freemxlist(MXTYP **mxlist)
+
+{
+if (mxlist!=(MXTYP **)0) {
+ for (int i=0;mxlist[i]!=(MXTYP *)0;i++)
+ (void) free(mxlist[i]);
+ (void) free(mxlist);
+ mxlist=(MXTYP **)0;
+ }
+return mxlist;
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
/* Procedure to extract a domain MX. */
/* If the domain doesn't exist or domain */
/* do not have a MX, a void pointer is */