Annotation of embedaddon/pimd/kern.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (c) 1998-2001
! 3: * University of Southern California/Information Sciences Institute.
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: * 1. Redistributions of source code must retain the above copyright
! 10: * notice, this list of conditions and the following disclaimer.
! 11: * 2. Redistributions in binary form must reproduce the above copyright
! 12: * notice, this list of conditions and the following disclaimer in the
! 13: * documentation and/or other materials provided with the distribution.
! 14: * 3. Neither the name of the project nor the names of its contributors
! 15: * may be used to endorse or promote products derived from this software
! 16: * without specific prior written permission.
! 17: *
! 18: * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
! 19: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 20: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 21: * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
! 22: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 23: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 24: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 25: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 26: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 27: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 28: * SUCH DAMAGE.
! 29: */
! 30: /*
! 31: * Part of this program has been derived from mrouted.
! 32: * The mrouted program is covered by the license in the accompanying file
! 33: * named "LICENSE.mrouted".
! 34: *
! 35: * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
! 36: * Leland Stanford Junior University.
! 37: *
! 38: */
! 39:
! 40: #include "defs.h"
! 41:
! 42: #ifdef RAW_OUTPUT_IS_RAW
! 43: int curttl = 0;
! 44: #endif
! 45:
! 46: /*
! 47: * XXX: in Some BSD's there is only MRT_ASSERT, but in Linux there are
! 48: * both MRT_ASSERT and MRT_PIM
! 49: */
! 50: #ifndef MRT_PIM
! 51: #define MRT_PIM MRT_ASSERT
! 52: #endif
! 53:
! 54: #ifdef __linux__ /* Currently only available on Linux */
! 55: # ifndef MRT_TABLE
! 56: # define MRT_TABLE (MRT_BASE + 9)
! 57: # endif
! 58: #endif
! 59:
! 60: /*
! 61: * Open/init the multicast routing in the kernel and sets the
! 62: * MRT_PIM (aka MRT_ASSERT) flag in the kernel.
! 63: */
! 64: void k_init_pim(int socket)
! 65: {
! 66: int v = 1;
! 67:
! 68: #ifdef MRT_TABLE /* Currently only available on Linux */
! 69: if (mrt_table_id != 0) {
! 70: logit(LOG_INFO, 0, "Initializing multicast routing table id %u", mrt_table_id);
! 71: if (setsockopt(socket, IPPROTO_IP, MRT_TABLE, &mrt_table_id, sizeof(mrt_table_id)) < 0) {
! 72: logit(LOG_WARNING, errno, "Cannot set multicast routing table id");
! 73: logit(LOG_ERR, 0, "Make sure your kernel has CONFIG_IP_MROUTE_MULTIPLE_TABLES=y");
! 74: }
! 75: }
! 76: #endif
! 77:
! 78: if (setsockopt(socket, IPPROTO_IP, MRT_INIT, (char *)&v, sizeof(int)) < 0) {
! 79: if (errno == EADDRINUSE)
! 80: logit(LOG_ERR, 0, "Another multicast routing application is already running.");
! 81: else
! 82: logit(LOG_ERR, errno, "Cannot enable multicast routing in kernel");
! 83: }
! 84:
! 85: if (setsockopt(socket, IPPROTO_IP, MRT_PIM, (char *)&v, sizeof(int)) < 0)
! 86: logit(LOG_ERR, errno, "Cannot set PIM flag in kernel");
! 87: }
! 88:
! 89:
! 90: /*
! 91: * Stops the multicast routing in the kernel and resets the
! 92: * MRT_PIM (aka MRT_ASSERT) flag in the kernel.
! 93: */
! 94: void k_stop_pim(int socket)
! 95: {
! 96: int v = 0;
! 97:
! 98: if (setsockopt(socket, IPPROTO_IP, MRT_PIM, (char *)&v, sizeof(int)) < 0)
! 99: logit(LOG_ERR, errno, "Cannot reset PIM flag in kernel");
! 100:
! 101: if (setsockopt(socket, IPPROTO_IP, MRT_DONE, (char *)NULL, 0) < 0)
! 102: logit(LOG_ERR, errno, "Cannot disable multicast routing in kernel");
! 103: }
! 104:
! 105:
! 106: /*
! 107: * Set the socket sending buffer. `bufsize` is the preferred size,
! 108: * `minsize` is the smallest acceptable size.
! 109: */
! 110: void k_set_sndbuf(int socket, int bufsize, int minsize)
! 111: {
! 112: int delta = bufsize / 2;
! 113: int iter = 0;
! 114:
! 115: /*
! 116: * Set the socket buffer. If we can't set it as large as we
! 117: * want, search around to try to find the highest acceptable
! 118: * value. The highest acceptable value being smaller than
! 119: * minsize is a fatal error.
! 120: */
! 121: if (setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, sizeof(bufsize)) < 0) {
! 122: bufsize -= delta;
! 123: while (1) {
! 124: iter++;
! 125: if (delta > 1)
! 126: delta /= 2;
! 127:
! 128: if (setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, sizeof(bufsize)) < 0) {
! 129: bufsize -= delta;
! 130: } else {
! 131: if (delta < 1024)
! 132: break;
! 133: bufsize += delta;
! 134: }
! 135: }
! 136: if (bufsize < minsize) {
! 137: logit(LOG_ERR, 0, "OS-allowed send buffer size %u < app min %u",
! 138: bufsize, minsize);
! 139: /*NOTREACHED*/
! 140: }
! 141: }
! 142:
! 143: IF_DEBUG(DEBUG_KERN) {
! 144: logit(LOG_DEBUG, 0, "Got %d byte send buffer size in %d iterations",
! 145: bufsize, iter);
! 146: }
! 147: }
! 148:
! 149:
! 150: /*
! 151: * Set the socket receiving buffer. `bufsize` is the preferred size,
! 152: * `minsize` is the smallest acceptable size.
! 153: */
! 154: void k_set_rcvbuf(int socket, int bufsize, int minsize)
! 155: {
! 156: int delta = bufsize / 2;
! 157: int iter = 0;
! 158:
! 159: /*
! 160: * Set the socket buffer. If we can't set it as large as we
! 161: * want, search around to try to find the highest acceptable
! 162: * value. The highest acceptable value being smaller than
! 163: * minsize is a fatal error.
! 164: */
! 165: if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize)) < 0) {
! 166: bufsize -= delta;
! 167: while (1) {
! 168: iter++;
! 169: if (delta > 1)
! 170: delta /= 2;
! 171:
! 172: if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize)) < 0) {
! 173: bufsize -= delta;
! 174: } else {
! 175: if (delta < 1024)
! 176: break;
! 177: bufsize += delta;
! 178: }
! 179: }
! 180:
! 181: if (bufsize < minsize) {
! 182: logit(LOG_ERR, 0, "OS-allowed recv buffer size %u < app min %u", bufsize, minsize);
! 183: /*NOTREACHED*/
! 184: }
! 185: }
! 186:
! 187: IF_DEBUG(DEBUG_KERN) {
! 188: logit(LOG_DEBUG, 0, "Got %d byte recv buffer size in %d iterations",
! 189: bufsize, iter);
! 190: }
! 191: }
! 192:
! 193:
! 194: /*
! 195: * Set/reset the IP_HDRINCL option. My guess is we don't need it for raw
! 196: * sockets, but having it here won't hurt. Well, unless you are running
! 197: * an older version of FreeBSD (older than 2.2.2). If the multicast
! 198: * raw packet is bigger than 208 bytes, then IP_HDRINCL triggers a bug
! 199: * in the kernel and "panic". The kernel patch for netinet/ip_raw.c
! 200: * coming with this distribution fixes it.
! 201: */
! 202: void k_hdr_include(int socket, int val)
! 203: {
! 204: #ifdef IP_HDRINCL
! 205: if (setsockopt(socket, IPPROTO_IP, IP_HDRINCL, (char *)&val, sizeof(val)) < 0)
! 206: logit(LOG_ERR, errno, "Failed %s IP_HDRINCL on socket %d",
! 207: ENABLINGSTR(val), socket);
! 208: #endif
! 209: }
! 210:
! 211:
! 212: /*
! 213: * Set the default TTL for the multicast packets outgoing from this
! 214: * socket.
! 215: * TODO: Does it affect the unicast packets?
! 216: */
! 217: void k_set_ttl(int socket __attribute__((unused)), int t)
! 218: {
! 219: #ifdef RAW_OUTPUT_IS_RAW
! 220: curttl = t;
! 221: #else
! 222: uint8_t ttl;
! 223:
! 224: ttl = t;
! 225: if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) < 0)
! 226: logit(LOG_ERR, errno, "Failed setting IP_MULTICAST_TTL %u on socket %d", ttl, socket);
! 227: #endif
! 228: }
! 229:
! 230:
! 231: /*
! 232: * Set/reset the IP_MULTICAST_LOOP. Set/reset is specified by "flag".
! 233: */
! 234: void k_set_loop(int socket, int flag)
! 235: {
! 236: uint8_t loop;
! 237:
! 238: loop = flag;
! 239: if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, sizeof(loop)) < 0)
! 240: logit(LOG_ERR, errno, "Failed %s IP_MULTICAST_LOOP on socket %d",
! 241: ENABLINGSTR(flag), socket);
! 242: }
! 243:
! 244:
! 245: /*
! 246: * Set the IP_MULTICAST_IF option on local interface ifa.
! 247: */
! 248: void k_set_if(int socket, uint32_t ifa)
! 249: {
! 250: struct in_addr adr;
! 251:
! 252: adr.s_addr = ifa;
! 253: if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&adr, sizeof(adr)) < 0) {
! 254: if (errno == EADDRNOTAVAIL || errno == EINVAL)
! 255: return;
! 256:
! 257: logit(LOG_ERR, errno, "Failed setting IP_MULTICAST_IF option on %s",
! 258: inet_fmt(adr.s_addr, s1, sizeof(s1)));
! 259: }
! 260: }
! 261:
! 262:
! 263: /*
! 264: * Set Router Alert IP option, RFC2113
! 265: */
! 266: void k_set_router_alert(int socket)
! 267: {
! 268: char router_alert[4]; /* Router Alert IP Option */
! 269:
! 270: router_alert[0] = IPOPT_RA; /* Router Alert */
! 271: router_alert[1] = 4; /* 4 bytes */
! 272: router_alert[2] = 0;
! 273: router_alert[3] = 0;
! 274:
! 275: if (setsockopt(socket, IPPROTO_IP, IP_OPTIONS, router_alert, sizeof(router_alert) )< 0)
! 276: logit(LOG_ERR, errno, "setsockopt IP_OPTIONS IPOPT_RA");
! 277: }
! 278:
! 279:
! 280: /*
! 281: * Join a multicast group on virtual interface 'v'.
! 282: */
! 283: void k_join(int socket, uint32_t grp, struct uvif *v)
! 284: {
! 285: #ifdef __linux__
! 286: struct ip_mreqn mreq;
! 287: #else
! 288: struct ip_mreq mreq;
! 289: #endif /* __linux__ */
! 290:
! 291: #ifdef __linux__
! 292: mreq.imr_ifindex = v->uv_ifindex;
! 293: mreq.imr_address.s_addr = v->uv_lcl_addr;
! 294: #else
! 295: mreq.imr_interface.s_addr = v->uv_lcl_addr;
! 296: #endif /* __linux__ */
! 297: mreq.imr_multiaddr.s_addr = grp;
! 298:
! 299: if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
! 300: (char *)&mreq, sizeof(mreq)) < 0) {
! 301: #ifdef __linux__
! 302: logit(LOG_WARNING, errno,
! 303: "Cannot join group %s on interface %s (ifindex %d)",
! 304: inet_fmt(grp, s1, sizeof(s1)), inet_fmt(v->uv_lcl_addr, s2, sizeof(s2)), v->uv_ifindex);
! 305: #else
! 306: logit(LOG_WARNING, errno,
! 307: "Cannot join group %s on interface %s",
! 308: inet_fmt(grp, s1, sizeof(s1)), inet_fmt(v->uv_lcl_addr, s2, sizeof(s2)));
! 309: #endif /* __linux__ */
! 310: }
! 311: }
! 312:
! 313:
! 314: /*
! 315: * Leave a multicast group on virtual interface 'v'.
! 316: */
! 317: void k_leave(int socket, uint32_t grp, struct uvif *v)
! 318: {
! 319: #ifdef __linux__
! 320: struct ip_mreqn mreq;
! 321: #else
! 322: struct ip_mreq mreq;
! 323: #endif /* __linux__ */
! 324:
! 325: #ifdef __linux__
! 326: mreq.imr_ifindex = v->uv_ifindex;
! 327: mreq.imr_address.s_addr = v->uv_lcl_addr;
! 328: #else
! 329: mreq.imr_interface.s_addr = v->uv_lcl_addr;
! 330: #endif /* __linux__ */
! 331: mreq.imr_multiaddr.s_addr = grp;
! 332:
! 333: if (setsockopt(socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) {
! 334: #ifdef __linux__
! 335: logit(LOG_WARNING, errno,
! 336: "Cannot leave group %s on interface %s (ifindex %d)",
! 337: inet_fmt(grp, s1, sizeof(s1)), inet_fmt(v->uv_lcl_addr, s2, sizeof(s2)), v->uv_ifindex);
! 338: #else
! 339: logit(LOG_WARNING, errno,
! 340: "Cannot leave group %s on interface %s",
! 341: inet_fmt(grp, s1, sizeof(s1)), inet_fmt(v->uv_lcl_addr, s2, sizeof(s2)));
! 342: #endif /* __linux__ */
! 343: }
! 344: }
! 345:
! 346: /*
! 347: * Fill struct vifctl using corresponding fields from struct uvif.
! 348: */
! 349: static void uvif_to_vifctl(struct vifctl *vc, struct uvif *v)
! 350: {
! 351: /* XXX: we don't support VIFF_TUNNEL; VIFF_SRCRT is obsolete */
! 352: vc->vifc_flags = 0;
! 353: if (v->uv_flags & VIFF_REGISTER)
! 354: vc->vifc_flags |= VIFF_REGISTER;
! 355: vc->vifc_threshold = v->uv_threshold;
! 356: vc->vifc_rate_limit = v->uv_rate_limit;
! 357: vc->vifc_lcl_addr.s_addr = v->uv_lcl_addr;
! 358: vc->vifc_rmt_addr.s_addr = v->uv_rmt_addr;
! 359: }
! 360:
! 361: /*
! 362: * Add a virtual interface in the kernel.
! 363: */
! 364: void k_add_vif(int socket, vifi_t vifi, struct uvif *v)
! 365: {
! 366: struct vifctl vc;
! 367:
! 368: vc.vifc_vifi = vifi;
! 369: uvif_to_vifctl(&vc, v);
! 370: if (setsockopt(socket, IPPROTO_IP, MRT_ADD_VIF, (char *)&vc, sizeof(vc)) < 0)
! 371: logit(LOG_ERR, errno, "Failed adding VIF %d (MRT_ADD_VIF) for iface %s",
! 372: vifi, v->uv_name);
! 373: }
! 374:
! 375:
! 376: /*
! 377: * Delete a virtual interface in the kernel.
! 378: */
! 379: void k_del_vif(int socket, vifi_t vifi, struct uvif *v __attribute__((unused)))
! 380: {
! 381: /*
! 382: * Unfortunately Linux MRT_DEL_VIF API differs a bit from the *BSD one. It
! 383: * expects to receive a pointer to struct vifctl that corresponds to the VIF
! 384: * we're going to delete. *BSD systems on the other hand exepect only the
! 385: * index of that VIF.
! 386: */
! 387: #ifdef __linux__
! 388: struct vifctl vc;
! 389:
! 390: vc.vifc_vifi = vifi;
! 391: uvif_to_vifctl(&vc, v); /* 'v' is used only on Linux systems. */
! 392:
! 393: if (setsockopt(socket, IPPROTO_IP, MRT_DEL_VIF, (char *)&vc, sizeof(vc)) < 0)
! 394: #else /* *BSD et al. */
! 395: if (setsockopt(socket, IPPROTO_IP, MRT_DEL_VIF, (char *)&vifi, sizeof(vifi)) < 0)
! 396: #endif /* !__linux__ */
! 397: {
! 398: if (errno == EADDRNOTAVAIL || errno == EINVAL)
! 399: return;
! 400:
! 401: logit(LOG_ERR, errno, "Failed removing VIF %d (MRT_DEL_VIF)", vifi);
! 402: }
! 403: }
! 404:
! 405:
! 406: /*
! 407: * Delete all MFC entries for particular routing entry from the kernel.
! 408: */
! 409: int k_del_mfc(int socket, uint32_t source, uint32_t group)
! 410: {
! 411: struct mfcctl mc;
! 412:
! 413: memset(&mc, 0, sizeof(mc));
! 414: mc.mfcc_origin.s_addr = source;
! 415: mc.mfcc_mcastgrp.s_addr = group;
! 416:
! 417: if (setsockopt(socket, IPPROTO_IP, MRT_DEL_MFC, (char *)&mc, sizeof(mc)) < 0) {
! 418: logit(LOG_WARNING, errno, "Failed removing MFC entry src %s, grp %s",
! 419: inet_fmt(mc.mfcc_origin.s_addr, s1, sizeof(s1)),
! 420: inet_fmt(mc.mfcc_mcastgrp.s_addr, s2, sizeof(s2)));
! 421:
! 422: return FALSE;
! 423: }
! 424:
! 425: logit(LOG_INFO, 0, "Removed MFC entry src %s, grp %s",
! 426: inet_fmt(mc.mfcc_origin.s_addr, s1, sizeof(s1)),
! 427: inet_fmt(mc.mfcc_mcastgrp.s_addr, s2, sizeof(s2)));
! 428:
! 429: return TRUE;
! 430: }
! 431:
! 432:
! 433: /*
! 434: * Install/modify a MFC entry in the kernel
! 435: */
! 436: int k_chg_mfc(int socket, uint32_t source, uint32_t group, vifi_t iif, vifbitmap_t oifs, uint32_t rp_addr __attribute__((unused)))
! 437: {
! 438: char input[IFNAMSIZ], output[MAXVIFS * (IFNAMSIZ + 2)] = "";
! 439: vifi_t vifi;
! 440: struct uvif *v;
! 441: struct mfcctl mc;
! 442:
! 443: memset(&mc, 0, sizeof(mc));
! 444: mc.mfcc_origin.s_addr = source;
! 445: mc.mfcc_mcastgrp.s_addr = group;
! 446: mc.mfcc_parent = iif;
! 447: /*
! 448: * draft-ietf-pim-sm-v2-new-05.txt section 4.2 mentions iif is removed
! 449: * at the packet forwarding phase
! 450: */
! 451: VIFM_CLR(mc.mfcc_parent, oifs);
! 452:
! 453: for (vifi = 0, v = uvifs; vifi < numvifs; vifi++, v++) {
! 454: if (VIFM_ISSET(vifi, oifs)) {
! 455: mc.mfcc_ttls[vifi] = v->uv_threshold;
! 456: if (output[0] != 0)
! 457: strlcat(output, ", ", sizeof(output));
! 458: strlcat(output, v->uv_name, sizeof(output));
! 459: } else {
! 460: mc.mfcc_ttls[vifi] = 0;
! 461: }
! 462: }
! 463: strlcpy(input, uvifs[iif].uv_name, sizeof(input));
! 464:
! 465: #ifdef PIM_REG_KERNEL_ENCAP
! 466: mc.mfcc_rp_addr.s_addr = rp_addr;
! 467: #endif
! 468: if (setsockopt(socket, IPPROTO_IP, MRT_ADD_MFC, (char *)&mc, sizeof(mc)) < 0) {
! 469: logit(LOG_WARNING, errno, "Failed adding MFC entry src %s grp %s from %s to %s",
! 470: inet_fmt(mc.mfcc_origin.s_addr, s1, sizeof(s1)),
! 471: inet_fmt(mc.mfcc_mcastgrp.s_addr, s2, sizeof(s2)),
! 472: input, output);
! 473:
! 474: return FALSE;
! 475: }
! 476:
! 477: logit(LOG_INFO, 0, "Added kernel MFC entry src %s grp %s from %s to %s",
! 478: inet_fmt(mc.mfcc_origin.s_addr, s1, sizeof(s1)),
! 479: inet_fmt(mc.mfcc_mcastgrp.s_addr, s2, sizeof(s2)),
! 480: input, output);
! 481:
! 482: return TRUE;
! 483: }
! 484:
! 485:
! 486: /*
! 487: * Get packet counters for particular interface
! 488: * XXX: TODO: currently not used, but keep just in case we need it later.
! 489: */
! 490: int k_get_vif_count(vifi_t vifi, struct vif_count *retval)
! 491: {
! 492: struct sioc_vif_req vreq;
! 493:
! 494: memset(&vreq, 0, sizeof(vreq));
! 495: vreq.vifi = vifi;
! 496: if (ioctl(udp_socket, SIOCGETVIFCNT, (char *)&vreq) < 0) {
! 497: logit(LOG_WARNING, errno, "Failed reading kernel packet count (SIOCGETVIFCNT) on vif %d", vifi);
! 498:
! 499: retval->icount =
! 500: retval->ocount =
! 501: retval->ibytes =
! 502: retval->obytes = 0xffffffff;
! 503:
! 504: return 1;
! 505: }
! 506:
! 507: retval->icount = vreq.icount;
! 508: retval->ocount = vreq.ocount;
! 509: retval->ibytes = vreq.ibytes;
! 510: retval->obytes = vreq.obytes;
! 511:
! 512: return 0;
! 513: }
! 514:
! 515:
! 516: /*
! 517: * Gets the number of packets, bytes, and number op packets arrived
! 518: * on wrong if in the kernel for particular (S,G) entry.
! 519: */
! 520: int k_get_sg_cnt(int socket, uint32_t source, uint32_t group, struct sg_count *retval)
! 521: {
! 522: struct sioc_sg_req sgreq;
! 523:
! 524: memset(&sgreq, 0, sizeof(sgreq));
! 525: sgreq.src.s_addr = source;
! 526: sgreq.grp.s_addr = group;
! 527: if ((ioctl(socket, SIOCGETSGCNT, (char *)&sgreq) < 0) || (sgreq.wrong_if == 0xffffffff)) {
! 528: /* XXX: ipmulti-3.5 has bug in ip_mroute.c, get_sg_cnt():
! 529: * the return code is always 0, so this is why we need to check
! 530: * the wrong_if value.
! 531: */
! 532: logit(LOG_WARNING, errno, "Failed reading kernel count (SIOCGETSGCNT) for (S,G) on (%s, %s)",
! 533: inet_fmt(source, s1, sizeof(s1)), inet_fmt(group, s2, sizeof(s2)));
! 534: retval->pktcnt = retval->bytecnt = retval->wrong_if = ~0;
! 535:
! 536: return 1;
! 537: }
! 538:
! 539: retval->pktcnt = sgreq.pktcnt;
! 540: retval->bytecnt = sgreq.bytecnt;
! 541: retval->wrong_if = sgreq.wrong_if;
! 542:
! 543: return 0;
! 544: }
! 545:
! 546: /**
! 547: * Local Variables:
! 548: * version-control: t
! 549: * indent-tabs-mode: t
! 550: * c-file-style: "ellemtel"
! 551: * c-basic-offset: 4
! 552: * End:
! 553: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>