1 /*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22 /*
23 * This file should be merged into net/if.c. The 'if_pcount' integer
24 * field must be added to 'struct ifnet' in net/if.h.
25 */
26
27 /*
28 * Set/clear promiscuous mode on interface 'ifp' based on the truth value`
29 * of pswitch. The calls are reference counted so that only the first
30 * 'on' request actually has an effect, as does the final 'off' request.
31 * Results are undefined if the 'off' and 'on' requests are not matched.
32 * This code works only with the BSD drivers.
33 */
34 int
ifpromisc(ifp,pswitch)35 ifpromisc(ifp, pswitch)
36 struct ifnet *ifp;
37 int pswitch;
38 {
39 /*
40 * If the device is not configured up, we cannot put it in
41 * promiscuous mode.
42 */
43 if ((ifp->if_flags & IFF_UP) == 0)
44 return ENETDOWN;
45
46 if (pswitch) {
47 if (ifp->if_pcount++ != 0)
48 return 0;
49 /* turn on driver */
50 ifp->if_flags |= IFF_PROMISC;
51 } else {
52 if (--ifp->if_pcount > 0)
53 return 0;
54 /* turn off driver */
55 ifp->if_flags &= ~IFF_PROMISC;
56 }
57 /*
58 * Clear the running bit -- this tricks the driver's ioctl
59 * into reinitilizing the interface so that the promiscuous
60 * bit will have its effect.
61 */
62 ifp->if_flags &=~ IFF_RUNNING;
63 return (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)0);
64 }
65