⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acl.c

📁 -
💻 C
📖 第 1 页 / 共 5 页
字号:
aclHostDomainCompare(const void *data, splayNode * n){    const char *h = data;    char *d = n->data;    int l1;    int l2;    if (matchDomainName(d, h))	return 0;    l1 = strlen(h);    l2 = strlen(d);    /* h != d */    while (xtolower(h[l1]) == xtolower(d[l2])) {	if (l1 == 0)	    break;	if (l2 == 0)	    break;	l1--;	l2--;    }    /* a '.' is a special case */    if ((h[l1] == '.') || (l1 == 0))	return -1;		/* domain(h) < d */    if ((d[l2] == '.') || (l2 == 0))	return 1;		/* domain(h) > d */    return (xtolower(h[l1]) - xtolower(d[l2]));}/* compare two network specs *  * NOTE: this is very similar to aclIpNetworkCompare and it's not yet * clear whether this OK. The problem could be with when a network * is a subset of the other networks: *  * 128.1.2.0/255.255.255.128 == 128.1.2.0/255.255.255.0 ? *  * Currently only the first address of the first network is used. *//* compare an address and a network spec */static intaclIpNetworkCompare(const void *a, splayNode * n){    struct in_addr A = *(struct in_addr *) a;    acl_ip_data *q = n->data;    struct in_addr B = q->addr1;    struct in_addr C = q->addr2;    int rc = 0;    A.s_addr &= q->mask.s_addr;	/* apply netmask */    if (C.s_addr == 0) {	/* single address check */	if (ntohl(A.s_addr) > ntohl(B.s_addr))	    rc = 1;	else if (ntohl(A.s_addr) < ntohl(B.s_addr))	    rc = -1;	else	    rc = 0;    } else {			/* range address check */	if (ntohl(A.s_addr) > ntohl(C.s_addr))	    rc = 1;	else if (ntohl(A.s_addr) < ntohl(B.s_addr))	    rc = -1;	else	    rc = 0;    }    return rc;}static voidaclDumpIpListWalkee(void *node, void *state){    acl_ip_data *ip = node;    MemBuf mb;    wordlist **W = state;    memBufDefInit(&mb);    memBufPrintf(&mb, "%s", inet_ntoa(ip->addr1));    if (ip->addr2.s_addr != any_addr.s_addr)	memBufPrintf(&mb, "-%s", inet_ntoa(ip->addr2));    if (ip->mask.s_addr != no_addr.s_addr)	memBufPrintf(&mb, "/%s", inet_ntoa(ip->mask));    wordlistAdd(W, mb.buf);    memBufClean(&mb);}static wordlist *aclDumpIpList(void *data){    wordlist *w = NULL;    splay_walk(data, aclDumpIpListWalkee, &w);    return w;}static voidaclDumpDomainListWalkee(void *node, void *state){    char *domain = node;    wordlistAdd(state, domain);}static wordlist *aclDumpDomainList(void *data){    wordlist *w = NULL;    splay_walk(data, aclDumpDomainListWalkee, &w);    return w;}static wordlist *aclDumpTimeSpecList(acl_time_data * t){    wordlist *W = NULL;    char buf[128];    while (t != NULL) {	snprintf(buf, sizeof(buf), "%c%c%c%c%c%c%c %02d:%02d-%02d:%02d",	    t->weekbits & ACL_SUNDAY ? 'S' : '-',	    t->weekbits & ACL_MONDAY ? 'M' : '-',	    t->weekbits & ACL_TUESDAY ? 'T' : '-',	    t->weekbits & ACL_WEDNESDAY ? 'W' : '-',	    t->weekbits & ACL_THURSDAY ? 'H' : '-',	    t->weekbits & ACL_FRIDAY ? 'F' : '-',	    t->weekbits & ACL_SATURDAY ? 'A' : '-',	    t->start / 60,	    t->start % 60,	    t->stop / 60,	    t->stop % 60);	wordlistAdd(&W, buf);	t = t->next;    }    return W;}static wordlist *aclDumpRegexList(relist * data){    wordlist *W = NULL;    while (data != NULL) {	wordlistAdd(&W, data->pattern);	data = data->next;    }    return W;}static wordlist *aclDumpIntlistList(intlist * data){    wordlist *W = NULL;    char buf[32];    while (data != NULL) {	snprintf(buf, sizeof(buf), "%d", data->i);	wordlistAdd(&W, buf);	data = data->next;    }    return W;}static wordlist *aclDumpIntRangeList(intrange * data){    wordlist *W = NULL;    char buf[32];    while (data != NULL) {	if (data->i == data->j)	    snprintf(buf, sizeof(buf), "%d", data->i);	else	    snprintf(buf, sizeof(buf), "%d-%d", data->i, data->j);	wordlistAdd(&W, buf);	data = data->next;    }    return W;}static wordlist *aclDumpProtoList(intlist * data){    wordlist *W = NULL;    while (data != NULL) {	wordlistAdd(&W, ProtocolStr[data->i]);	data = data->next;    }    return W;}static wordlist *aclDumpMethodList(intlist * data){    wordlist *W = NULL;    while (data != NULL) {	wordlistAdd(&W, RequestMethodStr[data->i]);	data = data->next;    }    return W;}wordlist *aclDumpGeneric(const acl * a){    debug(28, 3) ("aclDumpGeneric: %s type %d\n", a->name, a->type);    switch (a->type) {    case ACL_SRC_IP:    case ACL_DST_IP:    case ACL_MY_IP:	return aclDumpIpList(a->data);	break;    case ACL_SRC_DOMAIN:    case ACL_DST_DOMAIN:	return aclDumpDomainList(a->data);	break;#if SQUID_SNMP    case ACL_SNMP_COMMUNITY:#endif#if USE_IDENT    case ACL_IDENT:#endif    case ACL_PROXY_AUTH:	return wordlistDup(a->data);	break;    case ACL_TIME:	return aclDumpTimeSpecList(a->data);	break;    case ACL_URL_REGEX:    case ACL_URLPATH_REGEX:    case ACL_BROWSER:    case ACL_SRC_DOM_REGEX:    case ACL_DST_DOM_REGEX:	return aclDumpRegexList(a->data);	break;    case ACL_SRC_ASN:    case ACL_DST_ASN:	return aclDumpIntlistList(a->data);	break;    case ACL_URL_PORT:	return aclDumpIntRangeList(a->data);	break;    case ACL_PROTO:	return aclDumpProtoList(a->data);	break;    case ACL_METHOD:	return aclDumpMethodList(a->data);	break;#if USE_ARP_ACL    case ACL_SRC_ARP:	return aclDumpArpList(a->data);	break;#endif    case ACL_NONE:    default:	debug(28, 1) ("aclDumpGeneric: no case for ACL type %d\n", a->type);	break;    }    return NULL;}#if USE_ARP_ACL/* ==== BEGIN ARP ACL SUPPORT ============================================= *//* * From:    dale@server.ctam.bitmcnit.bryansk.su (Dale) * To:      wessels@nlanr.net * Subject: Another Squid patch... :) * Date:    Thu, 04 Dec 1997 19:55:01 +0300 * ============================================================================ *  * Working on setting up a proper firewall for a network containing some * Win'95 computers at our Univ, I've discovered that some smart students * avoid the restrictions easily just changing their IP addresses in Win'95 * Contol Panel... It has been getting boring, so I took Squid-1.1.18 * sources and added a new acl type for hard-wired access control: *  * acl <name> arp <Ethernet address> ... *  * For example, *  * acl students arp 00:00:21:55:ed:22 00:00:21:ff:55:38 * * NOTE: Linux code by David Luyer <luyer@ucs.uwa.edu.au>. *       Original (BSD-specific) code no longer works. */#include <sys/sysctl.h>#ifdef _SQUID_LINUX_#include <net/if_arp.h>#include <sys/ioctl.h>#else#include <net/if_dl.h>#endif#include <net/route.h>#include <net/if.h>#include <netinet/if_ether.h>/* * Decode an ascii representation (asc) of an ethernet adress, and place * it in eth[6]. */static intdecode_eth(const char *asc, char *eth){    int a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0;    if (sscanf(asc, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6) {	debug(28, 0) ("decode_eth: Invalid ethernet address '%s'\n", asc);	return 0;		/* This is not valid address */    }    eth[0] = (u_char) a1;    eth[1] = (u_char) a2;    eth[2] = (u_char) a3;    eth[3] = (u_char) a4;    eth[4] = (u_char) a5;    eth[5] = (u_char) a6;    return 1;}static acl_arp_data *aclParseArpData(const char *t){    LOCAL_ARRAY(char, eth, 256);    acl_arp_data *q = xcalloc(1, sizeof(acl_arp_data));    debug(28, 5) ("aclParseArpData: %s\n", t);    if (sscanf(t, "%[0-9a-fA-F:]", eth) != 1) {	debug(28, 0) ("aclParseArpData: Bad ethernet address: '%s'\n", t);	safe_free(q);	return NULL;    }    if (!decode_eth(eth, q->eth)) {	debug(28, 0) ("%s line %d: %s\n",	    cfg_filename, config_lineno, config_input_line);	debug(28, 0) ("aclParseArpData: Ignoring invalid ARP acl entry: can't parse '%s'\n", eth);	safe_free(q);	return NULL;    }    return q;}/*******************//* aclParseArpList *//*******************/static voidaclParseArpList(void *curlist){    char *t = NULL;    splayNode **Top = curlist;    acl_arp_data *q = NULL;    while ((t = strtokFile())) {	if ((q = aclParseArpData(t)) == NULL)	    continue;	*Top = splay_insert(q, *Top, aclArpCompare);    }}/***************//* aclMatchArp *//***************/#ifdef _SQUID_LINUX_static intaclMatchArp(void *dataptr, struct in_addr c){    struct arpreq arpReq;    struct sockaddr_in ipAddr;    splayNode **Top = dataptr;    ipAddr.sin_family = AF_INET;    ipAddr.sin_port = 0;    ipAddr.sin_addr = c;    memcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in));    arpReq.arp_dev[0] = '\0';    arpReq.arp_flags = 0;    /* any AF_INET socket will do... gives back hardware type, device, etc */    if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) == -1) {	debug(28, 1) ("ARP query failed - %d", errno);	return 0;    } else if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) {	debug(28, 1) ("Non-ethernet interface returned from ARP query - %d",	    arpReq.arp_ha.sa_family);	/* update here and MAC address parsing to handle non-ethernet */	return 0;    } else	*Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, aclArpCompare);    debug(28, 3) ("aclMatchArp: '%s' %s\n",	inet_ntoa(c), splayLastResult ? "NOT found" : "found");    return !splayLastResult;}static intaclArpCompare(const void *data, splayNode * n){    const unsigned short *d1 = data;    const unsigned short *d2 = n->data;    if (d1[0] != d2[0])	return (d1[0] > d2[0]) ? 1 : -1;    if (d1[1] != d2[1])	return (d1[1] > d2[1]) ? 1 : -1;    if (d1[2] != d2[2])	return (d1[2] > d2[2]) ? 1 : -1;    return 0;}#elsestatic intaclMatchArp(void *dataptr, struct in_addr c){    WRITE ME;}static intaclArpCompare(const void *data, splayNode * n){    WRITE ME;}/*********************************************************************** This is from the pre-splay-tree code for BSD* I suspect the Linux approach will work on most O/S and be much* better - <luyer@ucs.uwa.edu.au>***********************************************************************static intcheckARP(u_long ip, char *eth){    int mib[6] =    {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO};    size_t needed;    char *buf, *next, *lim;    struct rt_msghdr *rtm;    struct sockaddr_inarp *sin;    struct sockaddr_dl *sdl;    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {	debug(28, 0) ("Can't estimate ARP table size!\n");	return 0;    }    if ((buf = xmalloc(needed)) == NULL) {	debug(28, 0) ("Can't allocate temporary ARP table!\n");	return 0;    }    if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {	debug(28, 0) ("Can't retrieve ARP table!\n");	xfree(buf);	return 0;    }    lim = buf + needed;    for (next = buf; next < lim; next += rtm->rtm_msglen) {	rtm = (struct rt_msghdr *) next;	sin = (struct sockaddr_inarp *) (rtm + 1);	sdl = (struct sockaddr_dl *) (sin + 1);	if (sin->sin_addr.s_addr == ip) {	    if (sdl->sdl_alen)		if (!memcmp(LLADDR(sdl), eth, 6)) {		    xfree(buf);		    return 1;		}	    break;	}    }    xfree(buf);    return 0;}**********************************************************************/#endifstatic voidaclDumpArpListWalkee(void *node, void *state){    acl_arp_data *arp = node;    wordlist **W = state;    static char buf[24];    while (*W != NULL)	W = &(*W)->next;    snprintf(buf, sizeof(buf), "%02x:%02x:02x:02x:02x:02x",	arp->eth[0], arp->eth[1], arp->eth[2], arp->eth[3],	arp->eth[4], arp->eth[5]);    wordlistAdd(state, buf);}static wordlist *aclDumpArpList(void *data){    wordlist *w = NULL;    splay_walk(data, aclDumpArpListWalkee, &w);    return w;}/* ==== END ARP ACL SUPPORT =============================================== */#endif /* USE_ARP_ACL */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -