3 * $Id: ipcache.cc,v 1.252 2005/10/23 14:10:45 serassio Exp $
5 * DEBUG: section 14 IP Cache
6 * AUTHOR: Harvest Derived
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
39 typedef struct _ipcache_entry ipcache_entry
;
43 hash_link hash
; /* must be first */
51 struct timeval request_time
;
58 unsigned int negcached
:
61 unsigned int fromhosts
:
79 static dlink_list lru_list
;
81 static FREE ipcacheFreeEntry
;
83 static HLPCB ipcacheHandleReply
;
85 static IDNSCB ipcacheHandleReply
;
87 static IPH dummy_handler
;
88 static int ipcacheExpiredEntry(ipcache_entry
*);
89 static int ipcache_testname(void);
91 static int ipcacheParse(ipcache_entry
*, const char *buf
);
93 static int ipcacheParse(ipcache_entry
*, rfc1035_rr
*, int, const char *error
);
95 static ipcache_entry
*ipcache_get(const char *);
96 static void ipcacheLockEntry(ipcache_entry
*);
97 static void ipcacheStatPrint(ipcache_entry
*, StoreEntry
*);
98 static void ipcacheUnlockEntry(ipcache_entry
*);
99 static void ipcacheRelease(ipcache_entry
*);
101 static ipcache_addrs static_addrs
;
102 static hash_table
*ip_table
= NULL
;
104 static long ipcache_low
= 180;
105 static long ipcache_high
= 200;
107 #if LIBRESOLV_DNS_TTL_HACK
108 extern int _dns_ttl_
;
112 ipcache_testname(void)
115 debug(14, 1) ("Performing DNS Tests...\n");
117 if ((w
= Config
.dns_testname_list
) == NULL
)
120 for (; w
; w
= w
->next
) {
121 if (gethostbyname(w
->key
) != NULL
)
128 /* removes the given ipcache entry */
130 ipcacheRelease(ipcache_entry
* i
)
132 debug(14, 3) ("ipcacheRelease: Releasing entry for '%s'\n", (const char *) i
->hash
.key
);
133 hash_remove_link(ip_table
, (hash_link
*) i
);
134 dlinkDelete(&i
->lru
, &lru_list
);
138 static ipcache_entry
*
139 ipcache_get(const char *name
)
141 if (ip_table
!= NULL
)
142 return (ipcache_entry
*) hash_lookup(ip_table
, name
);
148 ipcacheExpiredEntry(ipcache_entry
* i
)
150 /* all static entries are locked, so this takes care of them too */
155 if (i
->addrs
.count
== 0)
156 if (0 == i
->flags
.negcached
)
159 if (i
->expires
> squid_curtime
)
166 ipcache_purgelru(void *voidnotused
)
169 dlink_node
*prev
= NULL
;
172 eventAdd("ipcache_purgelru", ipcache_purgelru
, NULL
, 10.0, 1);
174 for (m
= lru_list
.tail
; m
; m
= prev
) {
175 if (memInUse(MEM_IPCACHE_ENTRY
) < ipcache_low
)
180 i
= (ipcache_entry
*)m
->data
;
190 debug(14, 9) ("ipcache_purgelru: removed %d entries\n", removed
);
193 /* purges entries added from /etc/hosts (or whatever). */
195 purge_entries_fromhosts(void)
197 dlink_node
*m
= lru_list
.head
;
198 ipcache_entry
*i
= NULL
, *t
;
201 if (i
!= NULL
) { /* need to delay deletion */
202 ipcacheRelease(i
); /* we just override locks */
206 t
= (ipcache_entry
*)m
->data
;
208 if (t
->flags
.fromhosts
)
218 /* create blank ipcache_entry */
219 static ipcache_entry
*
220 ipcacheCreateEntry(const char *name
)
222 static ipcache_entry
*i
;
223 i
= (ipcache_entry
*)memAllocate(MEM_IPCACHE_ENTRY
);
224 i
->hash
.key
= xstrdup(name
);
225 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
230 ipcacheAddEntry(ipcache_entry
* i
)
232 hash_link
*e
= (hash_link
*)hash_lookup(ip_table
, i
->hash
.key
);
235 /* avoid colission */
236 ipcache_entry
*q
= (ipcache_entry
*) e
;
240 hash_join(ip_table
, &i
->hash
);
241 dlinkAdd(i
, &i
->lru
, &lru_list
);
242 i
->lastref
= squid_curtime
;
245 /* walks down the pending list, calling handlers */
247 ipcacheCallback(ipcache_entry
* i
)
249 IPH
*callback
= i
->handler
;
251 i
->lastref
= squid_curtime
;
258 callback
= i
->handler
;
262 if (cbdataReferenceValidDone(i
->handlerData
, &cbdata
)) {
263 dns_error_message
= i
->error_message
;
264 callback(i
->flags
.negcached
? NULL
: &i
->addrs
, cbdata
);
267 ipcacheUnlockEntry(i
);
272 ipcacheParse(ipcache_entry
*i
, const char *inbuf
)
274 LOCAL_ARRAY(char, buf
, DNS_INBUF_SZ
);
279 const char *name
= (const char *)i
->hash
.key
;
280 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
281 i
->flags
.negcached
= 1;
282 safe_free(i
->addrs
.in_addrs
);
283 safe_free(i
->addrs
.bad_mask
);
284 safe_free(i
->error_message
);
288 debug(14, 1) ("ipcacheParse: Got <NULL> reply\n");
289 i
->error_message
= xstrdup("Internal Error");
293 xstrncpy(buf
, inbuf
, DNS_INBUF_SZ
);
294 debug(14, 5) ("ipcacheParse: parsing: {%s}\n", buf
);
295 token
= strtok(buf
, w_space
);
298 debug(14, 1) ("ipcacheParse: expecting result, got '%s'\n", inbuf
);
299 i
->error_message
= xstrdup("Internal Error");
303 if (0 == strcmp(token
, "$fail")) {
304 token
= strtok(NULL
, "\n");
305 assert(NULL
!= token
);
306 i
->error_message
= xstrdup(token
);
310 if (0 != strcmp(token
, "$addr")) {
311 debug(14, 1) ("ipcacheParse: expecting '$addr', got '%s' in response to '%s'\n", inbuf
, name
);
312 i
->error_message
= xstrdup("Internal Error");
316 token
= strtok(NULL
, w_space
);
319 debug(14, 1) ("ipcacheParse: expecting TTL, got '%s' in response to '%s'\n", inbuf
, name
);
320 i
->error_message
= xstrdup("Internal Error");
326 while (NULL
!= (token
= strtok(NULL
, w_space
))) {
336 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(ipcount
, sizeof(struct IN_ADDR
));
337 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(ipcount
, sizeof(unsigned char));
339 for (j
= 0, k
= 0; k
< ipcount
; k
++) {
340 if (safe_inet_addr(A
[k
], &i
->addrs
.in_addrs
[j
]))
343 debug(14, 1) ("ipcacheParse: Invalid IP address '%s' in response to '%s'\n", A
[k
], name
);
346 i
->addrs
.count
= (unsigned char) j
;
349 if (i
->addrs
.count
<= 0) {
350 debug(14, 1) ("ipcacheParse: No addresses in response to '%s'\n", name
);
354 if (ttl
== 0 || ttl
> Config
.positiveDnsTtl
)
355 ttl
= Config
.positiveDnsTtl
;
357 if (ttl
< Config
.negativeDnsTtl
)
358 ttl
= Config
.negativeDnsTtl
;
360 i
->expires
= squid_curtime
+ ttl
;
362 i
->flags
.negcached
= 0;
364 return i
->addrs
.count
;
369 ipcacheParse(ipcache_entry
*i
, rfc1035_rr
* answers
, int nr
, const char *error_message
)
375 const char *name
= (const char *)i
->hash
.key
;
376 i
->expires
= squid_curtime
+ Config
.negativeDnsTtl
;
377 i
->flags
.negcached
= 1;
378 safe_free(i
->addrs
.in_addrs
);
379 safe_free(i
->addrs
.bad_mask
);
380 safe_free(i
->error_message
);
384 debug(14, 3) ("ipcacheParse: Lookup failed '%s' for '%s'\n",
385 error_message
, (const char *)i
->hash
.key
);
386 i
->error_message
= xstrdup(error_message
);
391 debug(14, 3) ("ipcacheParse: No DNS records in response to '%s'\n", name
);
392 i
->error_message
= xstrdup("No DNS records");
398 for (k
= 0; k
< nr
; k
++) {
399 if (answers
[k
].type
!= RFC1035_TYPE_A
)
402 if (answers
[k
]._class
!= RFC1035_CLASS_IN
)
405 if (answers
[k
].rdlength
!= 4) {
406 debug(14, 1)("ipcacheParse: Invalid IP address in response to '%s'\n", name
);
414 debug(14, 1) ("ipcacheParse: No Address records in response to '%s'\n", name
);
415 i
->error_message
= xstrdup("No Address records");
419 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(na
, sizeof(struct IN_ADDR
));
420 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(na
, sizeof(unsigned char));
422 for (j
= 0, k
= 0; k
< nr
; k
++) {
423 if (answers
[k
]._class
!= RFC1035_CLASS_IN
)
426 if (answers
[k
].type
== RFC1035_TYPE_A
) {
427 if (answers
[k
].rdlength
!= 4)
430 xmemcpy(&i
->addrs
.in_addrs
[j
++], answers
[k
].rdata
, 4);
432 debug(14, 3) ("ipcacheParse: #%d %s\n",
434 inet_ntoa(i
->addrs
.in_addrs
[j
- 1]));
435 } else if (answers
[k
].type
!= RFC1035_TYPE_CNAME
)
438 if (ttl
== 0 || (int) answers
[k
].ttl
< ttl
)
439 ttl
= answers
[k
].ttl
;
445 i
->addrs
.count
= (unsigned char) na
;
447 if (ttl
== 0 || ttl
> Config
.positiveDnsTtl
)
448 ttl
= Config
.positiveDnsTtl
;
450 if (ttl
< Config
.negativeDnsTtl
)
451 ttl
= Config
.negativeDnsTtl
;
453 i
->expires
= squid_curtime
+ ttl
;
455 i
->flags
.negcached
= 0;
457 return i
->addrs
.count
;
464 ipcacheHandleReply(void *data
, char *reply
)
466 ipcacheHandleReply(void *data
, rfc1035_rr
* answers
, int na
, const char *error_message
)
469 generic_cbdata
*c
= (generic_cbdata
*)data
;
470 ipcache_entry
*i
= (ipcache_entry
*)c
->data
;
473 IpcacheStats
.replies
++;
474 statHistCount(&statCounter
.dns
.svc_time
,
475 tvSubMsec(i
->request_time
, current_time
));
478 ipcacheParse(i
, reply
);
481 ipcacheParse(i
, answers
, na
, error_message
);
489 ipcache_nbgethostbyname(const char *name
, IPH
* handler
, void *handlerData
)
491 ipcache_entry
*i
= NULL
;
492 const ipcache_addrs
*addrs
= NULL
;
494 assert(handler
!= NULL
);
495 debug(14, 4) ("ipcache_nbgethostbyname: Name '%s'.\n", name
);
496 IpcacheStats
.requests
++;
498 if (name
== NULL
|| name
[0] == '\0') {
499 debug(14, 4) ("ipcache_nbgethostbyname: Invalid name!\n");
500 dns_error_message
= "Invalid hostname";
501 handler(NULL
, handlerData
);
505 if ((addrs
= ipcacheCheckNumeric(name
))) {
506 dns_error_message
= NULL
;
507 handler(addrs
, handlerData
);
511 i
= ipcache_get(name
);
516 } else if (ipcacheExpiredEntry(i
)) {
517 /* hit, but expired -- bummer */
522 debug(14, 4) ("ipcache_nbgethostbyname: HIT for '%s'\n", name
);
524 if (i
->flags
.negcached
)
525 IpcacheStats
.negative_hits
++;
529 i
->handler
= handler
;
531 i
->handlerData
= cbdataReference(handlerData
);
538 debug(14, 5) ("ipcache_nbgethostbyname: MISS for '%s'\n", name
);
539 IpcacheStats
.misses
++;
540 i
= ipcacheCreateEntry(name
);
541 i
->handler
= handler
;
542 i
->handlerData
= cbdataReference(handlerData
);
543 i
->request_time
= current_time
;
544 c
= cbdataAlloc(generic_cbdata
);
548 dnsSubmit(hashKeyStr(&i
->hash
), ipcacheHandleReply
, c
);
551 idnsALookup(hashKeyStr(&i
->hash
), ipcacheHandleReply
, c
);
555 /* initialize the ipcache */
560 debug(14, 3) ("Initializing IP Cache...\n");
561 memset(&IpcacheStats
, '\0', sizeof(IpcacheStats
));
562 memset(&lru_list
, '\0', sizeof(lru_list
));
563 /* test naming lookup */
565 if (!opt_dns_tests
) {
566 debug(14, 4) ("ipcache_init: Skipping DNS name lookup tests.\n");
567 } else if (!ipcache_testname()) {
568 fatal("ipcache_init: DNS name lookup tests failed.");
570 debug(14, 1) ("Successful DNS name lookup tests...\n");
573 memset(&static_addrs
, '\0', sizeof(ipcache_addrs
));
575 static_addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(1, sizeof(struct IN_ADDR
));
576 static_addrs
.bad_mask
= (unsigned char *)xcalloc(1, sizeof(unsigned char));
577 ipcache_high
= (long) (((float) Config
.ipcache
.size
*
578 (float) Config
.ipcache
.high
) / (float) 100);
579 ipcache_low
= (long) (((float) Config
.ipcache
.size
*
580 (float) Config
.ipcache
.low
) / (float) 100);
581 n
= hashPrime(ipcache_high
/ 4);
582 ip_table
= hash_create((HASHCMP
*) strcmp
, n
, hash4
);
583 cachemgrRegister("ipcache",
584 "IP Cache Stats and Contents",
585 stat_ipcache_get
, 0, 1);
586 memDataInit(MEM_IPCACHE_ENTRY
, "ipcache_entry", sizeof(ipcache_entry
), 0);
589 const ipcache_addrs
*
590 ipcache_gethostbyname(const char *name
, int flags
)
592 ipcache_entry
*i
= NULL
;
593 ipcache_addrs
*addrs
;
595 debug(14, 3) ("ipcache_gethostbyname: '%s', flags=%x\n", name
, flags
);
596 IpcacheStats
.requests
++;
597 i
= ipcache_get(name
);
601 } else if (ipcacheExpiredEntry(i
)) {
604 } else if (i
->flags
.negcached
) {
605 IpcacheStats
.negative_hits
++;
606 dns_error_message
= i
->error_message
;
610 i
->lastref
= squid_curtime
;
611 dns_error_message
= i
->error_message
;
615 dns_error_message
= NULL
;
617 if ((addrs
= ipcacheCheckNumeric(name
)))
620 IpcacheStats
.misses
++;
622 if (flags
& IP_LOOKUP_IF_MISS
)
623 ipcache_nbgethostbyname(name
, dummy_handler
, NULL
);
629 ipcacheStatPrint(ipcache_entry
* i
, StoreEntry
* sentry
)
632 storeAppendPrintf(sentry
, " %-32.32s %c%c %6d %6d %2d(%2d)",
633 hashKeyStr(&i
->hash
),
634 i
->flags
.fromhosts
? 'H' : ' ',
635 i
->flags
.negcached
? 'N' : ' ',
636 (int) (squid_curtime
- i
->lastref
),
637 (int) ((i
->flags
.fromhosts
? -1 : i
->expires
- squid_curtime
)),
638 (int) i
->addrs
.count
,
639 (int) i
->addrs
.badcount
);
641 for (k
= 0; k
< (int) i
->addrs
.count
; k
++) {
642 storeAppendPrintf(sentry
, " %15s-%3s", inet_ntoa(i
->addrs
.in_addrs
[k
]),
643 i
->addrs
.bad_mask
[k
] ? "BAD" : "OK ");
646 storeAppendPrintf(sentry
, "\n");
649 /* process objects list */
651 stat_ipcache_get(StoreEntry
* sentry
)
654 assert(ip_table
!= NULL
);
655 storeAppendPrintf(sentry
, "IP Cache Statistics:\n");
656 storeAppendPrintf(sentry
, "IPcache Entries: %d\n",
657 memInUse(MEM_IPCACHE_ENTRY
));
658 storeAppendPrintf(sentry
, "IPcache Requests: %d\n",
659 IpcacheStats
.requests
);
660 storeAppendPrintf(sentry
, "IPcache Hits: %d\n",
662 storeAppendPrintf(sentry
, "IPcache Negative Hits: %d\n",
663 IpcacheStats
.negative_hits
);
664 storeAppendPrintf(sentry
, "IPcache Misses: %d\n",
665 IpcacheStats
.misses
);
666 storeAppendPrintf(sentry
, "\n\n");
667 storeAppendPrintf(sentry
, "IP Cache Contents:\n\n");
668 storeAppendPrintf(sentry
, " %-29.29s %3s %6s %6s %1s\n",
675 for (m
= lru_list
.head
; m
; m
= m
->next
)
676 ipcacheStatPrint((ipcache_entry
*)m
->data
, sentry
);
680 dummy_handler(const ipcache_addrs
* addrsnotused
, void *datanotused
)
686 ipcacheInvalidate(const char *name
)
690 if ((i
= ipcache_get(name
)) == NULL
)
693 i
->expires
= squid_curtime
;
696 * NOTE, don't call ipcacheRelease here becuase we might be here due
697 * to a thread started from a callback.
702 ipcacheInvalidateNegative(const char *name
)
706 if ((i
= ipcache_get(name
)) == NULL
)
709 if (i
->flags
.negcached
)
710 i
->expires
= squid_curtime
;
713 * NOTE, don't call ipcacheRelease here becuase we might be here due
714 * to a thread started from a callback.
719 ipcacheCheckNumeric(const char *name
)
723 /* check if it's already a IP address in text form. */
725 if (!safe_inet_addr(name
, &ip
))
728 static_addrs
.count
= 1;
730 static_addrs
.cur
= 0;
732 static_addrs
.in_addrs
[0].s_addr
= ip
.s_addr
;
734 static_addrs
.bad_mask
[0] = FALSE
;
736 static_addrs
.badcount
= 0;
738 return &static_addrs
;
742 ipcacheLockEntry(ipcache_entry
* i
)
744 if (i
->locks
++ == 0) {
745 dlinkDelete(&i
->lru
, &lru_list
);
746 dlinkAdd(i
, &i
->lru
, &lru_list
);
751 ipcacheUnlockEntry(ipcache_entry
* i
)
753 assert(i
->locks
> 0);
756 if (ipcacheExpiredEntry(i
))
761 ipcacheCycleAddr(const char *name
, ipcache_addrs
* ia
)
768 if ((i
= ipcache_get(name
)) == NULL
)
771 if (i
->flags
.negcached
)
777 for (k
= 0; k
< ia
->count
; k
++) {
778 if (++ia
->cur
== ia
->count
)
781 if (!ia
->bad_mask
[ia
->cur
])
785 if (k
== ia
->count
) {
786 /* All bad, reset to All good */
787 debug(14, 3) ("ipcacheCycleAddr: Changing ALL %s addrs from BAD to OK\n",
790 for (k
= 0; k
< ia
->count
; k
++)
798 debug(14, 3) ("ipcacheCycleAddr: %s now at %s\n", name
,
799 inet_ntoa(ia
->in_addrs
[ia
->cur
]));
803 * Marks the given address as BAD and calls ipcacheCycleAddr to
804 * advance the current pointer to the next OK address.
808 ipcacheMarkBadAddr(const char *name
, struct IN_ADDR addr
)
814 if ((i
= ipcache_get(name
)) == NULL
)
819 for (k
= 0; k
< (int) ia
->count
; k
++)
821 if (ia
->in_addrs
[k
].s_addr
== addr
.s_addr
)
825 if (k
== (int) ia
->count
) /* not found */
828 if (!ia
->bad_mask
[k
])
830 ia
->bad_mask
[k
] = TRUE
;
832 i
->expires
= XMIN(squid_curtime
+ XMAX((time_t)60, Config
.negativeDnsTtl
), i
->expires
);
833 debug(14, 2) ("ipcacheMarkBadAddr: %s [%s]\n", name
, inet_ntoa(addr
));
836 ipcacheCycleAddr(name
, ia
);
841 ipcacheMarkGoodAddr(const char *name
, struct IN_ADDR addr
)
847 if ((i
= ipcache_get(name
)) == NULL
)
852 for (k
= 0; k
< (int) ia
->count
; k
++)
854 if (ia
->in_addrs
[k
].s_addr
== addr
.s_addr
)
858 if (k
== (int) ia
->count
) /* not found */
861 if (!ia
->bad_mask
[k
]) /* already OK */
864 ia
->bad_mask
[k
] = FALSE
;
868 debug(14, 2) ("ipcacheMarkGoodAddr: %s [%s]\n", name
, inet_ntoa(addr
));
872 ipcacheFreeEntry(void *data
)
874 ipcache_entry
*i
= (ipcache_entry
*)data
;
875 safe_free(i
->addrs
.in_addrs
);
876 safe_free(i
->addrs
.bad_mask
);
877 safe_free(i
->hash
.key
);
878 safe_free(i
->error_message
);
879 memFree(i
, MEM_IPCACHE_ENTRY
);
883 ipcacheFreeMemory(void)
885 hashFreeItems(ip_table
, ipcacheFreeEntry
);
886 hashFreeMemory(ip_table
);
890 /* Recalculate IP cache size upon reconfigure */
892 ipcache_restart(void)
894 ipcache_high
= (long) (((float) Config
.ipcache
.size
*
895 (float) Config
.ipcache
.high
) / (float) 100);
896 ipcache_low
= (long) (((float) Config
.ipcache
.size
*
897 (float) Config
.ipcache
.low
) / (float) 100);
898 purge_entries_fromhosts();
902 * adds a "static" entry from /etc/hosts.
903 * returns 0 upon success, 1 if the ip address is invalid
906 ipcacheAddEntryFromHosts(const char *name
, const char *ipaddr
)
912 if (!safe_inet_addr(ipaddr
, &ip
)) {
913 if (strchr(ipaddr
, ':') && strspn(ipaddr
, "0123456789abcdefABCDEF:") == strlen(ipaddr
)) {
914 debug(14, 3) ("ipcacheAddEntryFromHosts: Skipping IPv6 address '%s'\n", ipaddr
);
916 debug(14, 1) ("ipcacheAddEntryFromHosts: Bad IP address '%s'\n",
923 if ((i
= ipcache_get(name
))) {
924 if (1 == i
->flags
.fromhosts
) {
925 ipcacheUnlockEntry(i
);
926 } else if (i
->locks
> 0) {
927 debug(14, 1) ("ipcacheAddEntryFromHosts: can't add static entry"
928 " for locked name '%s'\n", name
);
935 i
= ipcacheCreateEntry(name
);
938 i
->addrs
.badcount
= 0;
940 i
->addrs
.in_addrs
= (struct IN_ADDR
*)xcalloc(1, sizeof(struct IN_ADDR
));
941 i
->addrs
.bad_mask
= (unsigned char *)xcalloc(1, sizeof(unsigned char));
942 i
->addrs
.in_addrs
[0].s_addr
= ip
.s_addr
;
943 i
->addrs
.bad_mask
[0] = FALSE
;
944 i
->flags
.fromhosts
= 1;
952 * The function to return the ip cache statistics to via SNMP
956 snmp_netIpFn(variable_list
* Var
, snint
* ErrP
)
958 variable_list
*Answer
= NULL
;
959 debug(49, 5) ("snmp_netIpFn: Processing request:\n");
960 snmpDebugOid(5, Var
->name
, Var
->name_length
);
961 *ErrP
= SNMP_ERR_NOERROR
;
963 switch (Var
->name
[LEN_SQ_NET
+ 1]) {
966 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
967 memInUse(MEM_IPCACHE_ENTRY
),
972 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
973 IpcacheStats
.requests
,
978 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
984 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
990 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
991 IpcacheStats
.negative_hits
,
996 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
1002 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
1008 Answer
= snmp_var_new_integer(Var
->name
, Var
->name_length
,
1014 *ErrP
= SNMP_ERR_NOSUCHNAME
;
1015 snmp_var_free(Answer
);
1022 #endif /*SQUID_SNMP */