Exemple #1
0
static int is_ipv4_ok(main_server_st *s, struct sockaddr_storage *ip, struct sockaddr_storage *net, struct sockaddr_storage *mask)
{
	struct sockaddr_storage broadcast;
	unsigned i;

	memcpy(&broadcast, net, sizeof(broadcast));
       	for (i=0;i<sizeof(struct in_addr);i++) {
       		SA_IN_U8_P(&broadcast)[i] |= ~(SA_IN_U8_P(&mask)[i]);
	}

	if (ip_lease_exists(s, ip, sizeof(struct sockaddr_in)) != 0 ||
	    ip_cmp(ip, net) == 0 ||
	    ip_cmp(ip, &broadcast) == 0) {
	    return 0;
	}
	return 1;
}
Exemple #2
0
static int is_ipv6_ok(main_server_st *s, struct sockaddr_storage *ip, struct sockaddr_storage *net, struct sockaddr_storage *mask)
{
	if (ip_lease_exists(s, ip, sizeof(struct sockaddr_in6)) != 0 ||
	    ip_cmp(ip, net) == 0) {
	    return 0;
	}
	return 1;
}
Exemple #3
0
static bool ip_lease_cmp(const void* _c1, void* _c2)
{
const struct ip_lease_st* c1 = _c1;
struct ip_lease_st* c2 = _c2;

	if (c1->rip_len == c2->rip_len &&
		ip_cmp(&c1->rip, &c2->rip, c2->rip_len) == 0)
		return 1;

	return 0;
}
int handle_resume_fetch_req(main_server_st * s, struct proc_st *proc,
			    const SessionResumeFetchMsg * req,
			    SessionResumeReplyMsg * rep)
{
	tls_cache_st *cache;
	struct htable_iter iter;
	size_t key;

	rep->reply = SESSION_RESUME_REPLY_MSG__RESUME__REP__FAILED;

	key = hash_any(req->session_id.data, req->session_id.len, 0);

	cache = htable_firstval(s->tls_db.ht, &iter, key);
	while (cache != NULL) {
		if (req->session_id.len == cache->session_id_size &&
		    memcmp(req->session_id.data, cache->session_id,
			   req->session_id.len) == 0) {

			if (proc->remote_addr_len == cache->remote_addr_len &&
			    ip_cmp(&proc->remote_addr, &cache->remote_addr) == 0) {

				rep->reply =
				    SESSION_RESUME_REPLY_MSG__RESUME__REP__OK;

				rep->has_session_data = 1;

				rep->session_data.data =
				    (void *)cache->session_data;
				rep->session_data.len =
				    cache->session_data_size;

				mslog_hex(s, proc, LOG_DEBUG, "TLS session DB resuming",
					  req->session_id.data,
					  req->session_id.len, 0);

				return 0;
			}
		}

		cache = htable_nextval(s->tls_db.ht, &iter, key);
	}

	return 0;

}
Exemple #5
0
inline
int cx_track(ip_t *ip_src, uint16_t src_port,ip_t *ip_dst, uint16_t dst_port,
               uint8_t ip_proto, uint32_t p_bytes, uint8_t tcpflags,struct timeval tstamp, int af) {

   connection *cxt = NULL;
   connection *head = NULL;

   /* for non-ipv6 addresses, indexes 1, 2 and 3 are zero and don't influence the hash */
   uint64_t hash = ip_hash(ip_src, ip_dst, src_port, dst_port, ip_proto, BUCKET_SIZE);

   cxt = bucket[hash];
   head = cxt;

   while ( cxt != NULL ) {
      if ( cxt->s_port == src_port && cxt->d_port == dst_port
           && cxt->vlanid == vlanid
           && ip_cmp(cxt->s_ip, ip_src) == 0
           && ip_cmp(cxt->d_ip, ip_dst) == 0 )
      {
         cxt->s_tcpFlags    |= tcpflags;
         cxt->s_total_bytes += p_bytes;
         cxt->s_total_pkts  += 1;
         cxt->last_pkt_time  = tstamp;

         if ( mode & MODE_DUMP )
         {
            cxt->last_offset = dump_file_offset + p_bytes;
            snprintf(cxt->last_dump, STDBUF, "%s", dump_file);
         }
         else if ( mode & MODE_FILE )
         {
            cxt->last_offset = read_file_offset + p_bytes;
            snprintf(cxt->last_dump, STDBUF, "%s", read_file);
         }

         return 0;
      }
      else if ( cxt->d_port == src_port && cxt->s_port == dst_port
                && cxt->vlanid == vlanid
                && ip_cmp(cxt->s_ip, ip_dst) == 0
                && ip_cmp(cxt->d_ip, ip_src) == 0 )
      {
         cxt->d_tcpFlags    |= tcpflags;
         cxt->d_total_bytes += p_bytes;
         cxt->d_total_pkts  += 1;
         cxt->last_pkt_time  = tstamp;

         if ( mode & MODE_DUMP )
         {
            cxt->last_offset = dump_file_offset + p_bytes;
            snprintf(cxt->last_dump, STDBUF, "%s", dump_file);
         }
         else if ( mode & MODE_FILE )
         {
            cxt->last_offset = read_file_offset + p_bytes;
            snprintf(cxt->last_dump, STDBUF, "%s", read_file);
         }

         return 0;
      }
      cxt = cxt->next;
   }

   if ( cxt == NULL ) {
      cxtrackerid += 1;
      cxt = (connection*) calloc(1, sizeof(connection));
      //cxt_alloc++;
      if (head != NULL ) {
         head->prev = cxt;
      }
      /* printf("[*] New connection...\n"); */
      cxt->cxid           = cxtrackerid;
      cxt->ipversion      = af;
      cxt->vlanid         = vlanid;
      cxt->s_tcpFlags     = tcpflags;
      /* cxt->d_tcpFlags     = 0x00; */
      cxt->s_total_bytes  = p_bytes;
      cxt->s_total_pkts   = 1;
      /* cxt->d_total_bytes  = 0; */
      /* cxt->d_total_pkts   = 0; */
      cxt->start_time     = tstamp;

      if ( mode & MODE_DUMP )
      {
         cxt->start_offset = dump_file_offset;
         cxt->last_offset = cxt->start_offset + p_bytes;
         snprintf(cxt->start_dump, STDBUF, "%s", dump_file);
         snprintf(cxt->last_dump, STDBUF, "%s", dump_file);
      }
      else if ( mode & MODE_FILE )
      {
         cxt->start_offset = read_file_offset;
         cxt->last_offset = cxt->start_offset + p_bytes;
         snprintf(cxt->start_dump, STDBUF, "%s", read_file);
         snprintf(cxt->last_dump, STDBUF, "%s", read_file);
      }
      else
      {
         cxt->start_offset = -1;
         cxt->last_offset = -1;
      }

      cxt->last_pkt_time  = tstamp;

      cxt->s_ip          = ip_src;
      cxt->d_ip          = ip_dst;
      /* This should be Zeroed due to calloc */
      /*
      if (af == AF_INET) {
         cxt->s_ip.s6_addr32[1]          = 0;
         cxt->s_ip.s6_addr32[2]          = 0;
         cxt->s_ip.s6_addr32[3]          = 0;
         cxt->d_ip.s6_addr32[1]          = 0;
         cxt->d_ip.s6_addr32[2]          = 0;
         cxt->d_ip.s6_addr32[3]          = 0;
      }
      */
      cxt->s_port         = src_port;
      cxt->d_port         = dst_port;
      cxt->proto          = ip_proto;
      cxt->next           = head;
      //cxt->prev           = NULL;

      /* New connections are pushed on to the head of bucket[s_hash] */
      bucket[hash] = cxt;

      /* Return value should be 1, telling "ip_tracked" not to try
       * to free the memory allocated for ip_src and ip_dst          */
      return 1;
   }

   /* Should never be here! */
   return 0;
}
Exemple #6
0
/* etnlegend, 2006.04.25, clean up bbsd_single ... */

#include "bbs.h"
#include <arpa/telnet.h>
#include <sys/resource.h>

#ifdef HAVE_REVERSE_DNS
#include <netdb.h>
#endif /* HAVE_REVERSE_DNS */

#undef LOAD_LIMIT /* Temporarily Disable All Load Limit Detection */

#if defined(LOAD_LIMIT) && defined(AIX)
#include <rpcsvc/rstat.h>
#endif /* LOAD_LIMIT && AIX */

#define SOCKFD                          3           /* listen sock file descriptor, should be set to 3 for consistent ! */
#define MAX_PENDING_CONNECTIONS         50
#define MAXLIST                         1000
#define CON_THRESHOLD                   (5.0/18)    /* (1000.0/3600) */
#define CON_THRESHOLD2                  1.0

#ifdef HAVE_IPV6_SMTH
#define KBS_SIN_MEMBER(_sin,_member)    _sin.sin6_##_member
#define KBS_SIN_FAMILY                  AF_INET6
#define KBS_SIN_ADDR_DEFAULT            in6addr_any
struct ip_struct {          /* size on 32-bit / 64-bit machine */
    struct in6_addr ip;     /*           16       16           */
    time_t first;           /*            4        8           */
    time_t last;            /*            4        8           */
    int t;                  /*            4        4           */
};                          /*           28       36   bytes   */
typedef struct sockaddr_in6             KBS_SOCKADDR_IN;
typedef struct in6_addr                 KBS_IN_ADDR;
#ifdef LEGACY_IPV4_DISPLAY
#define KBS_SET_FROMHOST(_sin,_from)                                            \
    (                                                                           \
            !ISV4ADDR(KBS_SIN_MEMBER(_sin,addr))?                                   \
            inet_ntop(AF_INET6,&KBS_SIN_MEMBER(_sin,addr),_from,IPLEN):             \
            inet_ntop(AF_INET,&KBS_SIN_MEMBER(_sin,addr).s6_addr[12],_from,IPLEN)   \
    )
#endif /* LEGACY_IPV4_DISPLAY */
#else /* ! HAVE_IPV6_SMTH */
#define KBS_SIN_MEMBER(_sin,_member)    _sin.sin_##_member
#define KBS_SIN_FAMILY                  AF_INET
#define KBS_SIN_ADDR_DEFAULT            inaddr_any
struct ip_struct {          /* size on 32-bit / 64-bit machine */
    unsigned char ip[4];    /*            4        4           */
    int t;                  /*            4        4           */
    time_t first;           /*            4        8           */
    time_t last;            /*            4        8           */
};                          /*           16       24   bytes   */
typedef struct sockaddr_in              KBS_SOCKADDR_IN;
typedef struct in_addr                  KBS_IN_ADDR;
#endif /* HAVE_IPV6_SMTH */

#define KBS_SET_SIN_FAMILY(_sin)        do{KBS_SIN_MEMBER(_sin,family)=KBS_SIN_FAMILY;}while(0)
#define KBS_SET_SIN_PORT(_sin,_port)    do{KBS_SIN_MEMBER(_sin,port)=htons(_port);}while(0)
#define KBS_SET_SIN_ADDR(_sin,_addr)    do{KBS_SIN_MEMBER(_sin,addr)=_addr;}while(0)
#ifndef KBS_SET_FROMHOST
#define KBS_SET_FROMHOST(_sin,_from)    inet_ntop(KBS_SIN_FAMILY,&KBS_SIN_MEMBER(_sin,addr),_from,IPLEN)
#endif /* KBS_SET_FROMHOST */

#ifndef SSHBBS
#define KBS_WRITE(_fd,_ptr,_len)        write(_fd,_ptr,_len)
static const unsigned char cmd[]={
    IAC,DO,TELOPT_TTYPE,                        /* cmd 0 size = 3  */
    IAC,SB,TELOPT_TTYPE,TELQUAL_SEND,IAC,SE,    /* cmd 1 size = 6  */
    IAC,WILL,TELOPT_ECHO,                       /* cmd 2 size = 3  */
    IAC,WILL,TELOPT_SGA,                        /* cmd 3 size = 3  */
    IAC,WILL,TELOPT_BINARY,                     /* cmd 4 size = 3  */
    IAC,DO,TELOPT_NAWS,                         /* cmd 5 size = 3  */
    IAC,DO,TELOPT_BINARY                        /* cmd 6 size = 3  */
};                                              /* total size = 24 */
#ifndef HAVE_IPV6_SMTH
static struct in_addr inaddr_any;
#endif /* HAVE_IPV6_SMTH */
static int mport;
static int no_fork;
static int server_pid;
const select_func x_select=select;
const read_func x_read=read;
#else /* SSHBBS */
#include "ssh_funcs.h"
#define KBS_WRITE(_fd,_ptr,_len)        ssh_write(_fd,_ptr,_len)
extern char **saved_argv;
static int ssh_exiting;
const select_func x_select=ssh_select;
const read_func x_read=ssh_read;
#endif /* ! SSHBBS */

static const int max_load = 79;
static int heavy_load;
static int initIP;
static struct ip_struct *ips;
static struct ip_struct *bads;
static struct ip_struct *proxies;

static inline int proxy_getpeername(int sockfd,struct sockaddr *addr,socklen_t *len)
{
    return getpeername(sockfd,addr,len);
}
static inline int local_Net_Sleep(time_t time)
{
    fd_set fds,efds;
    struct timeval tv;
    char buf[256];
    FD_ZERO(&fds);FD_ZERO(&efds);
    FD_SET(0,&fds);FD_SET(0,&efds);
    for (tv.tv_sec=time,tv.tv_usec=0;select(1,&fds,NULL,&efds,&tv)>0;tv.tv_sec=time,tv.tv_usec=0) {
        if (FD_ISSET(0,&efds)||!(recv(0,buf,256,0)>0))
            break;
        FD_SET(0,&fds);FD_SET(0,&efds);
    }
    return 0;
}
static inline int local_prints(const char *fmt,...)
{
    va_list ap;
    char buf[1024];
    va_start(ap,fmt);
    vsprintf(buf,fmt,ap);
    va_end(ap);
    return KBS_WRITE(0,buf,strlen(buf));
}
#ifdef LOAD_LIMIT
static inline int get_load(double *load)
{
#if defined(HAVE_GETLOADAVG)
    return getloadavg(load,3);
#elif defined(LINUX) /* ! HAVE_GETLOADAVG && LINUX */
    FILE *fp;
    int ret;
    double avg[3];
    load[0]=0;
    load[1]=0;
    load[2]=0;
    if (!(fp=fopen("/proc/loadavg","r")))
        return 0;
    ret=fscanf(fp,"%g %g %g",&avg[0],&avg[1],&avg[2]);
    fclose(fp);
    switch (ret) {
        case 3:
            load[2]=avg[2];
        case 2:
            load[1]=avg[1];
        case 1:
            load[0]=avg[0];
            break;
        default:
            return -1;
    }
    return ret;
#else /* ! HAVE_GETLOADAVG && ! LINUX */
    struct statstime rsts;
    rstat("localhost",&rsts);
    load[0]=(rs.avenrun[0]*0.00390625); /* div by 256 */
    load[1]=(rs.avenrun[1]*0.00390625);
    load[2]=(rs.avenrun[2]*0.00390625);
#endif /* HAVE_GETLOADAVG */
}
#endif /* LOAD_LIMIT */
static void sig_user1(int sig)
{
    heavy_load=1;
    return;
}
static void sig_user2(int sig)
{
    heavy_load=0;
    return;
}
static void sig_reaper(int sig)
{
    while (waitpid(-1,NULL,(WNOHANG|WUNTRACED))>0)
        continue;
    return;
}
static void sig_mainterm(int sig)
{
    exit(0);
}
static int main_signals(void)
{
    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;
    act.sa_flags=SA_RESTART;
    act.sa_handler=sig_mainterm;
    sigaction(SIGTERM,&act,NULL);
    act.sa_handler=sig_user1;
    sigaction(SIGUSR1,&act,NULL);
    act.sa_handler=sig_user2;
    sigaction(SIGUSR2,&act,NULL);
    act.sa_handler=SIG_IGN;
    sigaction(SIGPIPE,&act,NULL);
    act.sa_handler=SIG_IGN;
    sigaction(SIGTTOU,&act,NULL);
    act.sa_handler=SIG_IGN;
    sigaction(SIGHUP,&act,NULL);
#ifndef AIX
    act.sa_handler=sig_reaper;
    act.sa_flags=SA_RESTART;
#else /* AIX */
    act.sa_handler=NULL;
    act.sa_flags=(SA_RESTART|SA_NOCLDWAIT);
#endif /* ! AIX */
    sigaction(SIGCHLD,&act,NULL);
    return 0;
}
#ifdef HAVE_REVERSE_DNS
static void dns_query_timeout(int sig)
{
    longjmp(byebye,sig);
}
static void getremotehost(char *host,size_t len)
{
    KBS_SOCKADDR_IN sin;
    socklen_t sinlen;
    struct hostent *hp;
    char buf[128],*p;
    sinlen=sizeof(KBS_SOCKADDR_IN);
    proxy_getpeername(0,(struct sockaddr*)&sin,&sinlen);
    if (!setjmp(byebye)) {
        signal(SIGALRM,dns_query_timeout);
        alarm(5);
        hp=gethostbyaddr(&(KBS_SIN_MEMBER(sin,addr)),sizeof(KBS_SIN_MEMBER(sin,addr)),KBS_SIN_MEMBER(sin,family));
        alarm(0);
    }
    if (hp
#ifdef HAVE_IPV6_SMTH
            &&!strchr(hp->h_name,':')
#endif /* HAVE_IPV6_SMTH */
       )
        snprintf(buf,128,"%s",hp->h_name);
    else
        KBS_SET_FROMHOST(sin,buf);
    if ((p=strstr(buf,"."NAME_BBS_ENGLISH)))
        *p=0;
    snprintf(host,len,"%s",buf);
    return;
}
#endif /* HAVE_REVERSE_DNS */
int check_IP_lists(
#ifndef HAVE_IPV6_SMTH
    unsigned int IP2
#else /* HAVE_IPV6_SMTH */
    struct in6_addr sip
#endif /* ! HAVE_IPV6_SMTH */
)
{
    FILE *fp;
    char buf[1024];
    int i,found,min,ret;
    time_t now;
#ifndef HAVE_IPV6_SMTH
    unsigned int ip[4];
#else /* HAVE_IPV6_SMTH */
    struct in6_addr rip;
#endif /* ! HAVE_IPV6_SMTH */
    found=0;min=0;ret=0;
    if (!initIP) {
        ips=(struct ip_struct*)malloc(MAXLIST*sizeof(struct ip_struct));
        bads=(struct ip_struct*)malloc(MAXLIST*sizeof(struct ip_struct));
        proxies=(struct ip_struct*)malloc(MAXLIST*sizeof(struct ip_struct));
        memset(ips,0,MAXLIST*sizeof(struct ip_struct));
        memset(bads,0,MAXLIST*sizeof(struct ip_struct));
        memset(proxies,0,MAXLIST*sizeof(struct ip_struct));
        if (!ips||!bads||!proxies)
            return -1;
        if ((fp=fopen(".denyIP","r"))) {
            for (i=0;fgets(buf,1024,fp);i++) {
#ifndef HAVE_IPV6_SMTH
                if (!(sscanf(buf,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3])>0))
                    break;
                bads[i].ip[0]=ip[0];
                bads[i].ip[1]=ip[1];
                bads[i].ip[2]=ip[2];
                bads[i].ip[3]=ip[3];
#else /* HAVE_IPV6_SMTH */
                if (!(sscanf(buf,"%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:"
                             "%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX",&rip.s6_addr[0],
                             &rip.s6_addr[1],&rip.s6_addr[2],&rip.s6_addr[3],&rip.s6_addr[4],&rip.s6_addr[5],
                             &rip.s6_addr[6],&rip.s6_addr[7],&rip.s6_addr[8],&rip.s6_addr[9],&rip.s6_addr[10],
                             &rip.s6_addr[11],&rip.s6_addr[12],&rip.s6_addr[13],&rip.s6_addr[14],&rip.s6_addr[15])>0))
                    break;
                ip_cpy(bads[i].ip,rip);
#endif /* ! HAVE_IPV6_SMTH */
            }
            fclose(fp);
        }
        if ((fp=fopen("etc/proxyIP","r"))) {
            for (i=0;fgets(buf,1024,fp);i++) {
#ifndef HAVE_IPV6_SMTH
                if (!(sscanf(buf,"%d.%d.%d.%d",&ip[0],&ip[1],&ip[2],&ip[3])>0))
                    break;
                proxies[i].ip[0]=ip[0];
                proxies[i].ip[1]=ip[1];
                proxies[i].ip[2]=ip[2];
                proxies[i].ip[3]=ip[3];
#else /* HAVE_IPV6_SMTH */
                if (!(sscanf(buf,"%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:"
                             "%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX",&rip.s6_addr[0],
                             &rip.s6_addr[1],&rip.s6_addr[2],&rip.s6_addr[3],&rip.s6_addr[4],&rip.s6_addr[5],
                             &rip.s6_addr[6],&rip.s6_addr[7],&rip.s6_addr[8],&rip.s6_addr[9],&rip.s6_addr[10],
                             &rip.s6_addr[11],&rip.s6_addr[12],&rip.s6_addr[13],&rip.s6_addr[14],&rip.s6_addr[15])>0))
                    break;
                ip_cpy(proxies[i].ip,rip);
#endif /* ! HAVE_IPV6_SMTH */
            }
            fclose(fp);
        }
        initIP=1;
    }
    now=time(NULL);
#ifndef HAVE_IPV6_SMTH
    if (!(ip[0]=(IP2&0xFF)))
        return 0;
    ip[1]=((IP2>>8)&0xFF);
    ip[2]=((IP2>>16)&0xFF);
    ip[3]=((IP2>>24)&0xFF);
    for (i=0;i<MAXLIST;i++) {
        if (!(bads[i].ip[0]))
            break;
        if ((ip[0]==bads[i].ip[0])&&(ip[1]==bads[i].ip[1])
                &&(ip[2]==bads[i].ip[2])&&(ip[3]==bads[i].ip[3]))
            return 1;
    }
    for (i=0;i<MAXLIST;i++) {
        if (!(proxies[i].ip[0]))
            break;
        if ((ip[0]==proxies[i].ip[0])&&(ip[1]==proxies[i].ip[1])
                &&(ip[2]==proxies[i].ip[2])&&(ip[3]==proxies[i].ip[3]))
            return 0;
    }
    for (i=0;i<MAXLIST;i++) {
        if ((double)(now-ips[i].last)>3600)
            ips[i].ip[0]=0;
        if ((ip[0]==ips[i].ip[0])&&(ip[1]==ips[i].ip[1])
                &&(ip[2]==ips[i].ip[2])&&(ip[3]==ips[i].ip[3])) {
            if (!((double)(now-ips[i].last)>CON_THRESHOLD2)) {
                if ((fp=fopen(".IPdenys","a"))) {
                    fprintf(fp,"0 %ld %d.%d.%d.%d %d\n",now,ip[0],ip[1],ip[2],ip[3],ips[i].t);
                    fclose(fp);
                }
                ret=1;
            }
            found=1;
            ips[i].last=now;
            ips[i].t++;
            if (!(ips[i].t<10)&&!((ips[i].t/(double)(ips[i].last-ips[i].first))<CON_THRESHOLD)) {
                ips[i].t=100000;
                if ((fp=fopen(".IPdenys","a"))) {
                    fprintf(fp,"1 %ld %d.%d.%d.%d %d\n",now,ip[0],ip[1],ip[2],ip[3],ips[i].t);
                    fclose(fp);
                }
                ret=1;
            }
            break;
        }
        if (ips[i].last<ips[min].last)
            min=i;
    }
    if (!found) {
        ips[min].ip[0]=ip[0];
        ips[min].ip[1]=ip[1];
        ips[min].ip[2]=ip[2];
        ips[min].ip[3]=ip[3];
        ips[min].first=now;
        ips[min].last=now;
        ips[min].t=1;
    }
#else /* HAVE_IPV6_SMTH */
    memset(&rip,0,sizeof(struct in6_addr));
    for (i=0;i<MAXLIST;i++) {
        if (!ip_cmp(rip,bads[i].ip))
            break;
        if (!ip_cmp(sip,bads[i].ip))
            return 1;
    }
    for (i=0;i<MAXLIST;i++) {
        if (!ip_cmp(rip,proxies[i].ip))
            break;
        if (!ip_cmp(sip,proxies[i].ip))
            return 0;
    }
    for (i=0;i<MAXLIST;i++) {
        if ((double)(now-ips[i].last)>3600)
            memset(&ips[i].ip,0,sizeof(struct in6_addr));
        if (!ip_cmp(ips[i].ip,sip)) {
            if (!((double)(now-ips[i].last)>CON_THRESHOLD2)) {
                if ((fp=fopen(".IPdenys","a"))) {
                    fprintf(fp,"0 %ld %02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:"
                            "%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX %d\n",now,rip.s6_addr[0],
                            rip.s6_addr[1],rip.s6_addr[2],rip.s6_addr[3],rip.s6_addr[4],rip.s6_addr[5],
                            rip.s6_addr[6],rip.s6_addr[7],rip.s6_addr[8],rip.s6_addr[9],rip.s6_addr[10],
                            rip.s6_addr[11],rip.s6_addr[12],rip.s6_addr[13],rip.s6_addr[14],rip.s6_addr[15],ips[i].t);
                    fclose(fp);
                }
                ret=1;
            }
            found=1;
            ips[i].last=now;
            ips[i].t++;
            if (!(ips[i].t<10)&&!((ips[i].t/(double)(ips[i].last-ips[i].first))<CON_THRESHOLD)) {
                ips[i].t=100000;
                if ((fp=fopen(".IPdenys","a"))) {
                    fprintf(fp,"1 %ld %02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:"
                            "%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX:%02hhX%02hhX %d\n",now,rip.s6_addr[0],
                            rip.s6_addr[1],rip.s6_addr[2],rip.s6_addr[3],rip.s6_addr[4],rip.s6_addr[5],
                            rip.s6_addr[6],rip.s6_addr[7],rip.s6_addr[8],rip.s6_addr[9],rip.s6_addr[10],
                            rip.s6_addr[11],rip.s6_addr[12],rip.s6_addr[13],rip.s6_addr[14],rip.s6_addr[15],ips[i].t);
                    fclose(fp);
                }
                ret=1;
            }
            break;
        }
        if (ips[i].last<ips[min].last)
            min=i;
    }
    if (!found) {
        ip_cpy(ips[min].ip,rip);
        ips[min].first=now;
        ips[min].last=now;
        ips[min].t=1;
    }
#endif /* ! HAVE_IPV6_SMTH */
    return ret;
}
Exemple #7
0
static
int get_ipv4_lease(main_server_st* s, struct proc_st* proc)
{

	struct sockaddr_storage tmp, mask, network, rnd;
	unsigned i;
	unsigned max_loops = MAX_IP_TRIES;
	int ret;
	const char* c_network, *c_netmask;
	char buf[64];

	/* Our IP accounting */
	if (proc->config.ipv4_network && proc->config.ipv4_netmask) {
		c_network = proc->config.ipv4_network;
		c_netmask = proc->config.ipv4_netmask;
	} else {
		c_network = s->config->network.ipv4;
		c_netmask = s->config->network.ipv4_netmask;
	}

	if (c_network == NULL || c_netmask == NULL) {
		mslog(s, NULL, LOG_DEBUG, "there is no IPv4 network assigned");
		return 0;
	}

	ret =
	    inet_pton(AF_INET, c_network, SA_IN_P(&network));
	if (ret != 1) {
		mslog(s, NULL, LOG_ERR, "error reading IP: %s", c_network);
		return -1;
	}

	ret =
	    inet_pton(AF_INET, c_netmask, SA_IN_P(&mask));
	if (ret != 1) {
		mslog(s, NULL, LOG_ERR, "error reading mask: %s", c_netmask);
		return -1;
	}

	/* mask the network (just in case it is wrong) */
	for (i=0;i<sizeof(struct in_addr);i++)
		SA_IN_U8_P(&network)[i] &= (SA_IN_U8_P(&mask)[i]);
       	((struct sockaddr_in*)&network)->sin_family = AF_INET;
       	((struct sockaddr_in*)&network)->sin_port = 0;

	if (proc->config.explicit_ipv4) {
		/* if an explicit IP is given for that client, then
		 * do implicit IP accounting. Require the address
		 * to be odd, so we use the next even address as PtP. */
		ret =
		    inet_pton(AF_INET, proc->config.explicit_ipv4, SA_IN_P(&tmp));

		if (ret != 1) {
			mslog(s, NULL, LOG_ERR, "error reading explicit IP: %s", proc->config.explicit_ipv4);
			return -1;
		}

		proc->ipv4 = talloc_zero(proc, struct ip_lease_st);
		if (proc->ipv4 == NULL)
			return ERR_MEM;

        	((struct sockaddr_in*)&tmp)->sin_family = AF_INET;
        	((struct sockaddr_in*)&tmp)->sin_port = 0;
		memcpy(&proc->ipv4->rip, &tmp, sizeof(struct sockaddr_in));
       		proc->ipv4->rip_len = sizeof(struct sockaddr_in);

		if (is_ipv4_ok(s, &proc->ipv4->rip, &network, &mask) == 0) {
			mslog(s, proc, LOG_DEBUG, "cannot assign explicit IP %s; it is in use or invalid", 
			      human_addr((void*)&tmp, sizeof(struct sockaddr_in), buf, sizeof(buf)));
			ret = ERR_NO_IP;
			goto fail;
		}

		/* LIP = network address + 1 */
		memcpy(&proc->ipv4->lip, &network, sizeof(struct sockaddr_in));
		proc->ipv4->lip_len = sizeof(struct sockaddr_in);
		SA_IN_U8_P(&proc->ipv4->lip)[3] |= 1;

		if (ip_cmp(&proc->ipv4->lip, &proc->ipv4->rip) == 0) {
			mslog(s, NULL, LOG_ERR, "cannot assign explicit IP %s; network: %s", proc->config.explicit_ipv4, c_network);
			ret = ERR_NO_IP;
			goto fail;
		}

		return 0;
	}