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

📄 asn.c

📁 -
💻 C
字号:
/* * $Id: asn.c,v 1.56.2.1 1999/02/12 19:38:22 wessels Exp $ * * DEBUG: section 53    AS Number handling * AUTHOR: Duane Wessels, Kostas Anagnostakis * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"#define WHOIS_PORT 43/* BEGIN of definitions for radix tree entries *//* int in memory with length */typedef u_char m_int[1 + sizeof(unsigned int)];#define store_m_int(i, m) \    (i = htonl(i), m[0] = sizeof(m_int), xmemcpy(m+1, &i, sizeof(unsigned int)))#define get_m_int(i, m) \    (xmemcpy(&i, m+1, sizeof(unsigned int)), ntohl(i))/* END of definitions for radix tree entries *//* Head for ip to asn radix tree */struct radix_node_head *AS_tree_head;/* * Structure for as number information. it could be simply  * an intlist but it's coded as a structure for future * enhancements (e.g. expires) */struct _as_info {    intlist *as_number;    time_t expires;		/* NOTUSED */};struct _ASState {    StoreEntry *entry;    request_t *request;    int as_number;    off_t seen;    off_t offset;};typedef struct _ASState ASState;typedef struct _as_info as_info;/* entry into the radix tree */struct _rtentry {    struct radix_node e_nodes[2];    as_info *e_info;    m_int e_addr;    m_int e_mask;};typedef struct _rtentry rtentry;static int asnAddNet(char *, int);static void asnCacheStart(int as);static STCB asHandleReply;static int destroyRadixNode(struct radix_node *rn, void *w);static int printRadixNode(struct radix_node *rn, void *w);static void asnAclInitialize(acl * acls);static void asStateFree(void *data);static void destroyRadixNodeInfo(as_info *);static OBJH asnStats;extern struct radix_node *rn_lookup(void *, void *, void *);/* PUBLIC */intasnMatchIp(void *data, struct in_addr addr){    unsigned long lh;    struct radix_node *rn;    as_info *e;    m_int m_addr;    intlist *a = NULL;    intlist *b = NULL;    lh = ntohl(addr.s_addr);    debug(53, 3) ("asnMatchIp: Called for %s.\n", inet_ntoa(addr));    if (AS_tree_head == NULL)	return 0;    if (addr.s_addr == no_addr.s_addr)	return 0;    if (addr.s_addr == any_addr.s_addr)	return 0;    store_m_int(lh, m_addr);    rn = rn_match(m_addr, AS_tree_head);    if (rn == NULL) {	debug(53, 3) ("asnMatchIp: Address not in as db.\n");	return 0;    }    debug(53, 3) ("asnMatchIp: Found in db!\n");    e = ((rtentry *) rn)->e_info;    assert(e);    for (a = (intlist *) data; a; a = a->next)	for (b = e->as_number; b; b = b->next)	    if (a->i == b->i) {		debug(53, 5) ("asnMatchIp: Found a match!\n");		return 1;	    }    debug(53, 5) ("asnMatchIp: AS not in as db.\n");    return 0;}static voidasnAclInitialize(acl * acls){    acl *a;    intlist *i;    debug(53, 3) ("asnAclInitialize\n");    for (a = acls; a; a = a->next) {	if (a->type != ACL_DST_ASN && a->type != ACL_SRC_ASN)	    continue;	for (i = a->data; i; i = i->next)	    asnCacheStart(i->i);    }}/* initialize the radix tree structure */voidasnInit(void){    extern int max_keylen;    static int inited = 0;    max_keylen = 40;    if (0 == inited++)	rn_init();    rn_inithead((void **) &AS_tree_head, 8);    asnAclInitialize(Config.aclList);    cachemgrRegister("asndb", "AS Number Database", asnStats, 0, 1);}voidasnFreeMemory(void){    rn_walktree(AS_tree_head, destroyRadixNode, AS_tree_head);    destroyRadixNode((struct radix_node *) 0, (void *) AS_tree_head);}static voidasnStats(StoreEntry * sentry){    storeAppendPrintf(sentry, "Address    \tAS Numbers\n");    rn_walktree(AS_tree_head, printRadixNode, sentry);}/* PRIVATE */static voidasnCacheStart(int as){    LOCAL_ARRAY(char, asres, 4096);    StoreEntry *e;    request_t *req;    ASState *asState = xcalloc(1, sizeof(ASState));    cbdataAdd(asState, cbdataXfree, 0);    debug(53, 3) ("asnCacheStart: AS %d\n", as);    snprintf(asres, 4096, "whois://%s/!gAS%d", Config.as_whois_server, as);    asState->as_number = as;    req = urlParse(METHOD_GET, asres);    assert(NULL != req);    asState->request = requestLink(req);    if ((e = storeGetPublic(asres, METHOD_GET)) == NULL) {	e = storeCreateEntry(asres, asres, null_request_flags, METHOD_GET);	storeClientListAdd(e, asState);	fwdStart(-1, e, asState->request, no_addr, no_addr);    } else {	storeLockObject(e);	storeClientListAdd(e, asState);    }    asState->entry = e;    asState->seen = 0;    asState->offset = 0;    storeClientCopy(e,	asState->seen,	asState->offset,	4096,	memAllocate(MEM_4K_BUF),	asHandleReply,	asState);}static voidasHandleReply(void *data, char *buf, ssize_t size){    ASState *asState = data;    StoreEntry *e = asState->entry;    char *s;    char *t;    debug(53, 3) ("asHandleReply: Called with size=%d\n", size);    if (EBIT_TEST(e->flags, ENTRY_ABORTED)) {	memFree(buf, MEM_4K_BUF);	asStateFree(asState);	return;    }    if (size == 0 && e->mem_obj->inmem_hi > 0) {	memFree(buf, MEM_4K_BUF);	asStateFree(asState);	return;    } else if (size < 0) {	debug(53, 1) ("asHandleReply: Called with size=%d\n", size);	memFree(buf, MEM_4K_BUF);	asStateFree(asState);	return;    }    s = buf;    while (s - buf < size && *s != '\0') {	while (*s && xisspace(*s))	    s++;	for (t = s; *t; t++) {	    if (xisspace(*t))		break;	}	if (*t == '\0') {	    /* oof, word should continue on next block */	    break;	}	*t = '\0';	debug(53, 3) ("asHandleReply: AS# %s (%d)\n", s, asState->as_number);	asnAddNet(s, asState->as_number);	s = t + 1;    }    asState->seen = asState->offset + size;    asState->offset += (s - buf);    debug(53, 3) ("asState->seen = %d, asState->offset = %d\n",	asState->seen, asState->offset);    if (e->store_status == STORE_PENDING) {	debug(53, 3) ("asHandleReply: store_status == STORE_PENDING: %s\n", storeUrl(e));	storeClientCopy(e,	    asState->seen,	    asState->offset,	    SM_PAGE_SIZE,	    buf,	    asHandleReply,	    asState);    } else if (asState->seen < e->mem_obj->inmem_hi) {	debug(53, 3) ("asHandleReply: asState->seen < e->mem_obj->inmem_hi %s\n", storeUrl(e));	storeClientCopy(e,	    asState->seen,	    asState->offset,	    SM_PAGE_SIZE,	    buf,	    asHandleReply,	    asState);    } else {	debug(53, 3) ("asHandleReply: Done: %s\n", storeUrl(e));	memFree(buf, MEM_4K_BUF);	asStateFree(asState);    }}static voidasStateFree(void *data){    ASState *asState = data;    debug(53, 3) ("asnStateFree: %s\n", storeUrl(asState->entry));    storeUnregister(asState->entry, asState);    storeUnlockObject(asState->entry);    requestUnlink(asState->request);    cbdataFree(asState);}/* add a network (addr, mask) to the radix tree, with matching AS * number */static intasnAddNet(char *as_string, int as_number){    rtentry *e = xmalloc(sizeof(rtentry));    struct radix_node *rn;    char dbg1[32], dbg2[32];    intlist **Tail = NULL;    intlist *q = NULL;    as_info *asinfo = NULL;    struct in_addr in_a, in_m;    long mask, addr;    char *t;    int bitl;    t = strchr(as_string, '/');    if (t == NULL) {	debug(53, 3) ("asnAddNet: failed, invalid response from whois server.\n");	return 0;    }    *t = '\0';    addr = inet_addr(as_string);    bitl = atoi(t + 1);    if (bitl < 0)	bitl = 0;    if (bitl > 32)	bitl = 32;    mask = bitl ? 0xfffffffful << (32 - bitl) : 0;    in_a.s_addr = addr;    in_m.s_addr = mask;    xstrncpy(dbg1, inet_ntoa(in_a), 32);    xstrncpy(dbg2, inet_ntoa(in_m), 32);    addr = ntohl(addr);    /*mask = ntohl(mask); */    debug(53, 3) ("asnAddNet: called for %s/%s\n", dbg1, dbg2);    memset(e, '\0', sizeof(rtentry));    store_m_int(addr, e->e_addr);    store_m_int(mask, e->e_mask);    rn = rn_lookup(e->e_addr, e->e_mask, AS_tree_head);    if (rn != NULL) {	asinfo = ((rtentry *) rn)->e_info;	if (intlistFind(asinfo->as_number, as_number)) {	    debug(53, 3) ("asnAddNet: Ignoring repeated network '%s/%d' for AS %d\n",		dbg1, bitl, as_number);	} else {	    debug(53, 3) ("asnAddNet: Warning: Found a network with multiple AS numbers!\n");	    for (Tail = &asinfo->as_number; *Tail; Tail = &(*Tail)->next);	    q = xcalloc(1, sizeof(intlist));	    q->i = as_number;	    *(Tail) = q;	    e->e_info = asinfo;	}    } else {	q = xcalloc(1, sizeof(intlist));	q->i = as_number;	asinfo = xmalloc(sizeof(asinfo));	asinfo->as_number = q;	rn = rn_addroute(e->e_addr, e->e_mask, AS_tree_head, e->e_nodes);	rn = rn_match(e->e_addr, AS_tree_head);	assert(rn != NULL);	e->e_info = asinfo;    }    if (rn == 0) {	xfree(e);	debug(53, 3) ("asnAddNet: Could not add entry.\n");	return 0;    }    e->e_info = asinfo;    return 1;}static intdestroyRadixNode(struct radix_node *rn, void *w){    struct radix_node_head *rnh = (struct radix_node_head *) w;    if (rn && !(rn->rn_flags & RNF_ROOT)) {	rtentry *e = (rtentry *) rn;	rn = rn_delete(rn->rn_key, rn->rn_mask, rnh);	if (rn == 0)	    debug(53, 3) ("destroyRadixNode: internal screwup\n");	destroyRadixNodeInfo(e->e_info);	xfree(rn);    }    return 1;}static voiddestroyRadixNodeInfo(as_info * e_info){    intlist *prev = NULL;    intlist *data = e_info->as_number;    while (data) {	prev = data;	data = data->next;	xfree(prev);    }    xfree(data);}intmask_len(int mask){    int len = 32;    while ((mask & 1) == 0) {	len--;	mask >>= 1;    }    return len;}static intprintRadixNode(struct radix_node *rn, void *w){    StoreEntry *sentry = w;    rtentry *e = (rtentry *) rn;    intlist *q;    as_info *asinfo;    struct in_addr addr;    struct in_addr mask;    assert(e);    assert(e->e_info);    (void) get_m_int(addr.s_addr, e->e_addr);    (void) get_m_int(mask.s_addr, e->e_mask);    storeAppendPrintf(sentry, "%15s/%d\t",	inet_ntoa(addr), mask_len(ntohl(mask.s_addr)));    asinfo = e->e_info;    assert(asinfo->as_number);    for (q = asinfo->as_number; q; q = q->next)	storeAppendPrintf(sentry, " %d", q->i);    storeAppendPrintf(sentry, "\n");    return 0;}

⌨️ 快捷键说明

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