Back to index

glibc  2.9
setipv4sourcefilter.c
Go to the documentation of this file.
00001 /* Set IPv4 source filter.  Linux version.
00002    Copyright (C) 2004 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <alloca.h>
00022 #include <errno.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <netinet/in.h>
00026 #include <sys/socket.h>
00027 
00028 
00029 int
00030 setipv4sourcefilter (int s, struct in_addr interface, struct in_addr group,
00031                    uint32_t fmode, uint32_t numsrc,
00032                    const struct in_addr *slist)
00033 {
00034   /* We have to create an struct ip_msfilter object which we can pass
00035      to the kernel.  */
00036   size_t needed = IP_MSFILTER_SIZE (numsrc);
00037   int use_alloca = __libc_use_alloca (needed);
00038 
00039   struct ip_msfilter *imsf;
00040   if (use_alloca)
00041     imsf = (struct ip_msfilter *) alloca (needed);
00042   else
00043     {
00044       imsf = (struct ip_msfilter *) malloc (needed);
00045       if (imsf == NULL)
00046        return -1;
00047     }
00048 
00049   imsf->imsf_multiaddr = group;
00050   imsf->imsf_interface = interface;
00051   imsf->imsf_fmode = fmode;
00052   imsf->imsf_numsrc = numsrc;
00053   memcpy (imsf->imsf_slist, slist, numsrc * sizeof (struct in_addr));
00054 
00055   int result = __setsockopt (s, SOL_IP, IP_MSFILTER, imsf, needed);
00056 
00057   if (! use_alloca)
00058     {
00059       int save_errno = errno;
00060       free (imsf);
00061       __set_errno (save_errno);
00062     }
00063 
00064   return result;
00065 }