/* Sub kevel procedure to manage IP number. */
/* */
/********************************************************/
-#include <arpa/inet.h>
-#include <errno.h>
+#include <ifaddrs.h>
#include <malloc.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/types.h>
#include "subafn.h"
#define PUBLIC //to specify public variable
+/*
+\f
+*/
+/********************************************************/
+/* */
+/* procedure to build a list of local server IP */
+/* */
+/********************************************************/
+static char *getlocalipstr()
+
+{
+#define OPEP "subafn.c:getlocalipstr,"
+
+char *localip;
+struct ifaddrs *ifaddr;
+int phase;
+_Bool proceed;
+
+localip=strdup("");
+ifaddr=(struct ifaddrs *)0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //Get list of interface
+ if (getifaddrs(&ifaddr)<0) {
+ (void) fprintf(stderr,"%s Unable to get local IP (error=<%s> system?)\n",
+ OPEP,strerror(errno));
+ phase=999; //No need to go further;
+ }
+ break;
+ case 1 : //cans list of interface
+ for (struct ifaddrs *ifa=ifaddr;ifa!=(struct ifaddrs *)0;ifa=ifa->ifa_next) {
+ int family;
+ int taille;
+ int er;
+ char *newloc;
+ char host[NI_MAXHOST];
+
+ if (ifa->ifa_addr==(struct sockaddr *)0)
+ continue;
+ family=ifa->ifa_addr->sa_family;
+ switch (family) {
+ case AF_INET :
+ taille=sizeof(struct sockaddr_in);
+ break;
+ case AF_INET6 :
+ taille=sizeof(struct sockaddr_in6);
+ continue; //No scanning for IPV6 Number (Jun 2025)
+ break;
+ default :
+ continue;
+ break;
+ }
+ er=getnameinfo(ifa->ifa_addr,taille,host,NI_MAXHOST,NULL,0,NI_NUMERICHOST);
+ if (er!=0) {
+ (void) fprintf(stderr,"%s getnameinfo() failed: (error=<%s> system?)\n",
+ OPEP,gai_strerror(er));
+ continue;
+ }
+ newloc=(char *)calloc(strlen(localip)+strlen(host)+3,sizeof(char));
+ if (strlen(localip)>0) {
+ (void) strcpy(newloc,localip);
+ (void) strcat(newloc,",");
+ }
+ (void) strcat(newloc,host);
+ (void) free(localip);
+ localip=newloc;
+ }
+ break;
+ case 2 : //free memory
+ (void) freeifaddrs(ifaddr);
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return localip;
+
+#undef OPEP
+}
/*
\f
*/
*/
/********************************************************/
/* */
+/* Procedure to transforme ONE clean IP to an AFN */
+/* structure. */
+/* */
+/********************************************************/
+static AFNTYP *getoneafn(char *onecleanipstr)
+
+{
+#define OPEP "subafn.c:getoneanf,"
+#define ZIPV4 "0.0.0.0"
+
+AFNTYP *afnnum;
+int phase;
+int proceed;
+
+afnnum=(AFNTYP *)0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : /*lets say ip format ok */
+ afnnum=(AFNTYP *)calloc(1,sizeof(AFNTYP));
+ afnnum->afntype=AF_INET;
+ afnnum->afnmask=32;
+ if (strchr(onecleanipstr,':')==(char *)0)
+ phase++; //This is an IPV4 number
+ break;
+ case 1 : //IP is an IPV6 format
+ if (strcasestr(onecleanipstr,STRIPV6)==onecleanipstr)
+ onecleanipstr+=strlen(STRIPV6);
+ afnnum->afntype=AF_INET6;
+ afnnum->afnmask=128;
+ break;
+ case 2 : //lets convert it
+ switch (inet_pton(afnnum->afntype,onecleanipstr,afnnum->ip)) {
+ case 1 : //success
+ break;
+ case 0 : //Invalid IP number
+ (void) fprintf(stderr,"Unable to convert IP <%s> (Invalid IP number)\n",
+ onecleanipstr);
+ afnnum=afn_freeipnum(afnnum);
+ phase=999; //no need to go further
+ break;
+ case -1 : //Invalid IP number
+ (void) fprintf(stderr,"Unable to convert IP <%s> (error=<%s>)\n",
+ onecleanipstr,strerror(errno));
+ afnnum=afn_freeipnum(afnnum);
+ phase=999; //no need to go further
+ break;
+ default : //Unexpected Result
+ (void) fprintf(stderr,"Unexpected status to convert IP <%s> "
+ "(error=<%s> BUG!?)\n",
+ onecleanipstr,strerror(errno));
+ afnnum=afn_freeipnum(afnnum);
+ phase=999; //no need to go further
+ }
+ break;
+ case 3 : //lets convert it
+ afnnum->strnumip=afn_getstrip(afnnum);
+ //(void) printf("JMPDBG <%s> -> converted to <%s>\n",
+ //onecleanipstr,afnnum->strnumip);
+ break;
+ default : /*SAFE guard */
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return afnnum;
+
+#undef OPEP
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Routine to fee memory used by an AFNTYP */
/* */
/********************************************************/
PUBLIC char *afn_stripnum(AFNTYP *num)
{
-#define OPEP "subafn.c:afn_stripnum"
+#define OPEP "subafn.c:afn_stripnumm,"
char *strip;
const char *markr;
/* IP number in AFNTYP structure. */
/* */
/********************************************************/
-PUBLIC AFNTYP *afn_getipnum(char *cleanipstr)
+PUBLIC AFNTYP **afn_getipnum(char *cleanipstr)
{
#define OPEP "subafn.c:afn_getipnum"
#define ZIPV4 "0.0.0.0"
-AFNTYP *afnnum;
+AFNTYP **afnlist;
+char *iplist;
int phase;
int proceed;
-afnnum=(AFNTYP *)0;
+afnlist=(AFNTYP **)calloc(1,sizeof(AFNTYP *));
+iplist=(char *)0;
phase=0;
proceed=true;
while (proceed==true) {
phase=999; //No need to go further
}
break;
- case 1 : /*lets say ip format ok */
- afnnum=(AFNTYP *)calloc(1,sizeof(AFNTYP));
- afnnum->afntype=AF_INET;
- afnnum->afnmask=32;
- if (strchr(cleanipstr,':')==(char *)0)
- phase++; //This is an IPV4 number
- break;
- case 2 : //IP is an IPV6 format
- if (strcasestr(cleanipstr,STRIPV6)==cleanipstr)
- cleanipstr+=strlen(STRIPV6);
- afnnum->afntype=AF_INET6;
- afnnum->afnmask=128;
- break;
- case 3 : //checking '0' situation
+ case 1 : //checking '0' situation
if (strcmp(cleanipstr,"0")==0)
- cleanipstr=ZIPV4;
+ cleanipstr=ZIPV4;
break;
- case 4 : //lets convert it
- switch (inet_pton(afnnum->afntype,cleanipstr,afnnum->ip)) {
- case 1 : //success
- break;
- case 0 : //Invalid IP number
- (void) fprintf(stderr,"Unable to convert IP <%s> (Invalid IP number)\n",
- cleanipstr);
- afnnum=afn_freeipnum(afnnum);
- phase=999; //no need to go further
- break;
- case -1 : //Invalid IP number
- (void) fprintf(stderr,"Unable to convert IP <%s> (error=<%s>)\n",
- cleanipstr,strerror(errno));
- afnnum=afn_freeipnum(afnnum);
- phase=999; //no need to go further
- break;
- default : //Unexpected Result
- (void) fprintf(stderr,"Unexpected status to convert IP <%s> "
- "(error=<%s> BUG!?)\n",
- cleanipstr,strerror(errno));
- afnnum=afn_freeipnum(afnnum);
- phase=999; //no need to go further
+ case 2 : //checking '0' situation
+ iplist=strdup(cleanipstr);
+ if (strcmp(iplist,ZIPV4)==0) {
+ (void) free(iplist);
+ iplist=getlocalipstr();
}
+ if (strlen(iplist)==0)
+ phase++; //No need to scan
break;
- case 5 : //lets convert it
- afnnum->strnumip=afn_getstrip(afnnum);
- //(void) printf("JMPDBG <%s> -> converted to <%s>\n",
- //cleanipstr,afnnum->strnumip);
+ case 3 : //scanning the iplist
+ char *ptr;
+ int num;
+
+ ptr=iplist;
+ num=0;
+ while (ptr!=(char *)0) {
+ char *next;
+ AFNTYP *afnloc;
+
+ if ((next=strchr(ptr,','))!=(char *)0) {
+ *next='\000';
+ next++;
+ }
+ if ((afnloc=getoneafn(ptr))!=(AFNTYP *)0) {
+ afnlist[num]=afnloc;
+ num++;
+ afnlist=(AFNTYP **)realloc(afnlist,num*sizeof(AFNTYP *));
+ afnlist[num]=(AFNTYP *)0;
+ }
+ ptr=next;
+ }
+ break;
+ case 4 : //free memory used
+ (void) free(iplist);
break;
default : /*SAFE guard */
proceed=false;
}
phase++;
}
-return afnnum;
+return afnlist;
#undef ZIPV4
#undef OPEP