Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 1 | /* source: xio-interface.c */ |
Gerhard Rieger | d34493c | 2016-07-22 08:54:31 +0200 | [diff] [blame] | 2 | /* Copyright Gerhard Rieger and contributors (see file CHANGES) */ |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 3 | /* Published under the GNU General Public License V.2, see file COPYING */ |
| 4 | |
| 5 | /* this file contains the source for opening addresses of raw socket type */ |
| 6 | |
| 7 | #include "xiosysincludes.h" |
| 8 | |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 9 | #if _WITH_INTERFACE |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 10 | |
| 11 | #include "xioopen.h" |
| 12 | #include "xio-socket.h" |
Gerhard Rieger | b5640dd | 2023-09-30 15:18:39 +0200 | [diff] [blame] | 13 | #include "xio-ascii.h" |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 14 | |
| 15 | #include "xio-interface.h" |
| 16 | |
| 17 | |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 18 | static int xioopen_interface(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc); |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 19 | |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 20 | /*0 const struct optdesc opt_interface_addr = { "interface-addr", "address", OPT_INTERFACE_ADDR, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/ |
| 21 | /*0 const struct optdesc opt_interface_netmask = { "interface-netmask", "netmask", OPT_INTERFACE_NETMASK, GROUP_INTERFACE, PH_FD, TYPE_STRING, OFUNC_SPEC };*/ |
Gerhard Rieger | c82e3df | 2023-11-05 19:39:01 +0100 | [diff] [blame] | 22 | const struct optdesc opt_iff_up = { "iff-up", "up", OPT_IFF_UP, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_UP }; |
| 23 | const struct optdesc opt_iff_broadcast = { "iff-broadcast", NULL, OPT_IFF_BROADCAST, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_BROADCAST }; |
| 24 | const struct optdesc opt_iff_debug = { "iff-debug" , NULL, OPT_IFF_DEBUG, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_DEBUG }; |
| 25 | const struct optdesc opt_iff_loopback = { "iff-loopback" , "loopback", OPT_IFF_LOOPBACK, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_LOOPBACK }; |
| 26 | const struct optdesc opt_iff_pointopoint = { "iff-pointopoint", "pointopoint",OPT_IFF_POINTOPOINT, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_POINTOPOINT }; |
| 27 | const struct optdesc opt_iff_notrailers = { "iff-notrailers", "notrailers", OPT_IFF_NOTRAILERS, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_NOTRAILERS }; |
| 28 | const struct optdesc opt_iff_running = { "iff-running", "running", OPT_IFF_RUNNING, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_RUNNING }; |
| 29 | const struct optdesc opt_iff_noarp = { "iff-noarp", "noarp", OPT_IFF_NOARP, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_NOARP }; |
| 30 | const struct optdesc opt_iff_promisc = { "iff-promisc", "promisc", OPT_IFF_PROMISC, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_PROMISC }; |
| 31 | const struct optdesc opt_iff_allmulti = { "iff-allmulti", "allmulti", OPT_IFF_ALLMULTI, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_ALLMULTI }; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 32 | #ifdef IFF_MASTER |
Gerhard Rieger | c82e3df | 2023-11-05 19:39:01 +0100 | [diff] [blame] | 33 | const struct optdesc opt_iff_master = { "iff-master", "master", OPT_IFF_MASTER, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_MASTER }; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 34 | #endif |
| 35 | #ifdef IFF_SLAVE |
Gerhard Rieger | c82e3df | 2023-11-05 19:39:01 +0100 | [diff] [blame] | 36 | const struct optdesc opt_iff_slave = { "iff-slave", "slave", OPT_IFF_SLAVE, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_SLAVE }; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 37 | #endif |
Gerhard Rieger | c82e3df | 2023-11-05 19:39:01 +0100 | [diff] [blame] | 38 | const struct optdesc opt_iff_multicast = { "iff-multicast", NULL, OPT_IFF_MULTICAST, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_MULTICAST }; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 39 | #ifdef IFF_PORTSEL |
Gerhard Rieger | c82e3df | 2023-11-05 19:39:01 +0100 | [diff] [blame] | 40 | const struct optdesc opt_iff_portsel = { "iff-portsel", "portsel", OPT_IFF_PORTSEL, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_PORTSEL }; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 41 | #endif |
| 42 | #ifdef IFF_AUTOMEDIA |
Gerhard Rieger | c82e3df | 2023-11-05 19:39:01 +0100 | [diff] [blame] | 43 | const struct optdesc opt_iff_automedia = { "iff-automedia", "automedia", OPT_IFF_AUTOMEDIA, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(para.interface.iff_opts), IFF_AUTOMEDIA }; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 44 | #endif |
Gerhard Rieger | c82e3df | 2023-11-05 19:39:01 +0100 | [diff] [blame] | 45 | /*const struct optdesc opt_iff_dynamic = { "iff-dynamic", "dynamic", OPT_IFF_DYNAMIC, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(short), IFF_DYNAMIC };*/ |
Gerhard Rieger | b5640dd | 2023-09-30 15:18:39 +0200 | [diff] [blame] | 46 | #ifdef PACKET_AUXDATA |
Gerhard Rieger | 1c1a910 | 2023-10-01 19:53:55 +0200 | [diff] [blame] | 47 | const struct optdesc opt_retrieve_vlan = { "retrieve-vlan", NULL, OPT_RETRIEVE_VLAN, GROUP_INTERFACE, PH_LATE, TYPE_CONST, OFUNC_SPEC }; |
Gerhard Rieger | b5640dd | 2023-09-30 15:18:39 +0200 | [diff] [blame] | 48 | #endif |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 49 | #if LATER |
| 50 | const struct optdesc opt_route = { "route", NULL, OPT_ROUTE, GROUP_INTERFACE, PH_INIT, TYPE_STRING, OFUNC_SPEC }; |
| 51 | #endif |
| 52 | |
| 53 | #if WITH_INTERFACE |
| 54 | const struct addrdesc xioaddr_interface = { "INTERFACE", 3, xioopen_interface, GROUP_FD|GROUP_SOCKET|GROUP_INTERFACE, PF_PACKET, 0, 0 HELP(":<interface>") }; |
| 55 | #endif /* WITH_INTERFACE */ |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 56 | |
| 57 | |
| 58 | static |
| 59 | int _xioopen_interface(const char *ifname, |
| 60 | struct opt *opts, int xioflags, xiofile_t *xxfd, |
Gerhard Rieger | 2cddaf2 | 2023-06-14 11:41:44 +0200 | [diff] [blame] | 61 | groups_t groups, int pf) { |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 62 | xiosingle_t *sfd = &xxfd->stream; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 63 | union sockaddr_union us = {{0}}; |
| 64 | socklen_t uslen; |
| 65 | int socktype = SOCK_RAW; |
| 66 | unsigned int ifidx; |
| 67 | bool needbind = false; |
| 68 | char *bindstring = NULL; |
| 69 | struct sockaddr_ll sall = { 0 }; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 70 | int rc; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 71 | |
| 72 | if (ifindex(ifname, &ifidx, -1) < 0) { |
| 73 | Error1("unknown interface \"%s\"", ifname); |
| 74 | ifidx = 0; /* desparate attempt to continue */ |
| 75 | } |
| 76 | |
Gerhard Rieger | d605ab5 | 2023-11-06 21:23:27 +0100 | [diff] [blame] | 77 | if (sfd->howtoend == END_UNSPEC) |
| 78 | sfd->howtoend = END_INTERFACE; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 79 | retropt_int(opts, OPT_SO_TYPE, &socktype); |
| 80 | |
| 81 | retropt_socket_pf(opts, &pf); |
| 82 | |
| 83 | /* ...res_opts[] */ |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 84 | if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; |
| 85 | applyopts(sfd, -1, opts, PH_INIT); |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 86 | |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 87 | sfd->salen = sizeof(sfd->peersa); |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 88 | if (pf == PF_UNSPEC) { |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 89 | pf = sfd->peersa.soa.sa_family; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 90 | } |
| 91 | |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 92 | sfd->dtype = XIODATA_RECVFROM_SKIPIP; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 93 | |
| 94 | if (retropt_string(opts, OPT_BIND, &bindstring)) { |
| 95 | needbind = true; |
| 96 | } |
| 97 | /*!!! parse by ':' */ |
Gerhard Rieger | a8a8626 | 2010-01-04 12:59:56 +0100 | [diff] [blame] | 98 | us.ll.sll_family = pf; |
| 99 | us.ll.sll_protocol = htons(ETH_P_ALL); |
| 100 | us.ll.sll_ifindex = ifidx; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 101 | uslen = sizeof(sall); |
| 102 | needbind = true; |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 103 | sfd->peersa = (union sockaddr_union)us; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 104 | |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 105 | rc = |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 106 | _xioopen_dgram_sendto(needbind?&us:NULL, uslen, |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 107 | opts, xioflags, sfd, groups, pf, socktype, 0, 0); |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 108 | if (rc < 0) |
| 109 | return rc; |
| 110 | |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 111 | strncpy(sfd->para.interface.name, ifname, IFNAMSIZ); |
| 112 | _xiointerface_get_iff(sfd->fd, ifname, &sfd->para.interface.save_iff); |
| 113 | _xiointerface_apply_iff(sfd->fd, ifname, sfd->para.interface.iff_opts); |
Gerhard Rieger | 40350ec | 2023-07-27 21:18:23 +0200 | [diff] [blame] | 114 | if (_interface_retrieve_vlan(sfd, opts) < 0) |
| 115 | return STAT_NORETRY; |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 116 | |
| 117 | #ifdef PACKET_IGNORE_OUTGOING |
Gerhard Rieger | 11d1e9e | 2023-10-26 19:12:38 +0200 | [diff] [blame] | 118 | /* Raw socket might also provide packets that are outbound - we are not |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 119 | interested in these and disable this "feature" in kernel if possible */ |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 120 | if (Setsockopt(sfd->fd, SOL_PACKET, PACKET_IGNORE_OUTGOING, &one, sizeof(one)) < 0) { |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 121 | Warn2("setsockopt(%d, SOL_PACKET, PACKET_IGNORE_OUTGOING, {1}): %s", |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 122 | sfd->fd, strerror(errno)); |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 123 | } |
Gerhard Rieger | 11d1e9e | 2023-10-26 19:12:38 +0200 | [diff] [blame] | 124 | #endif /*defined(PACKET_IGNORE_OUTGOING) */ |
| 125 | |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 126 | return 0; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 127 | } |
| 128 | |
Gerhard Rieger | 40350ec | 2023-07-27 21:18:23 +0200 | [diff] [blame] | 129 | |
| 130 | int _interface_retrieve_vlan(struct single *sfd, struct opt *opts) { |
| 131 | #if HAVE_STRUCT_TPACKET_AUXDATA |
| 132 | if (retropt_bool(opts, OPT_RETRIEVE_VLAN, |
| 133 | &sfd->para.socket.retrieve_vlan) |
| 134 | == 0) { |
| 135 | if (!xioparms.experimental) { |
| 136 | Warn1("option %s is experimental", opts->desc->defname); |
| 137 | } |
| 138 | } |
| 139 | if (sfd->para.socket.retrieve_vlan) { |
| 140 | if (_interface_setsockopt_auxdata(sfd->fd, 1) < 0) { |
| 141 | return -1; |
| 142 | } |
| 143 | } |
| 144 | #endif /* HAVE_STRUCT_TPACKET_AUXDATA */ |
| 145 | return 0; |
| 146 | } |
| 147 | |
Gerhard Rieger | b5640dd | 2023-09-30 15:18:39 +0200 | [diff] [blame] | 148 | int _interface_setsockopt_auxdata(int fd, int auxdata) { |
| 149 | #ifdef PACKET_AUXDATA |
| 150 | /* Linux strips VLAN tag off incoming packets and makes it available per |
| 151 | ancillary data as auxdata. Apply option packet-auxdata if you want the |
| 152 | VLAN tag to be restored by Socat in the received packet */ |
| 153 | if (auxdata) { |
| 154 | int rc; |
Gerhard Rieger | 40350ec | 2023-07-27 21:18:23 +0200 | [diff] [blame] | 155 | Info1("setsockopt(fd=%d, level=SOL_PACKET, optname=PACKET_AUXDATA)", fd); |
Gerhard Rieger | b5640dd | 2023-09-30 15:18:39 +0200 | [diff] [blame] | 156 | rc = Setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, &auxdata, sizeof(auxdata)); |
| 157 | if (rc < 0) { |
| 158 | Error3("setsockopt(%d, SOL_PACKET, PACKET_AUXDATA, , {%d}): %s", |
| 159 | fd, auxdata, strerror(errno)); |
| 160 | } |
| 161 | } |
| 162 | #endif /* defined(PACKET_AUXDATA) */ |
| 163 | return 0; |
| 164 | } |
| 165 | |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 166 | static |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 167 | int xioopen_interface( |
| 168 | int argc, |
| 169 | const char *argv[], |
| 170 | struct opt *opts, |
| 171 | int xioflags, |
| 172 | xiofile_t *xxfd, |
| 173 | const struct addrdesc *addrdesc) |
| 174 | { |
| 175 | xiosingle_t *sfd = &xxfd->stream; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 176 | int result; |
| 177 | |
| 178 | if (argc != 2) { |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 179 | xio_syntax(argv[0], 1, argc-1, addrdesc->syntax); |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 180 | return STAT_NORETRY; |
| 181 | } |
| 182 | |
| 183 | if ((result = |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 184 | _xioopen_interface(argv[1], opts, xioflags, xxfd, addrdesc->groups, |
| 185 | addrdesc->arg1)) |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 186 | != STAT_OK) { |
| 187 | return result; |
| 188 | } |
| 189 | |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 190 | sfd->dtype = XIOREAD_RECV|XIOWRITE_SENDTO; |
| 191 | if (addrdesc->arg1 == PF_INET) { |
| 192 | sfd->dtype |= XIOREAD_RECV_SKIPIP; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 193 | } |
| 194 | |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 195 | sfd->para.socket.la.soa.sa_family = sfd->peersa.soa.sa_family; |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 196 | |
Gerhard Rieger | 50b199d | 2023-07-13 09:06:35 +0200 | [diff] [blame] | 197 | _xio_openlate(sfd, opts); |
Gerhard Rieger | de91089 | 2008-09-20 23:37:56 +0200 | [diff] [blame] | 198 | return STAT_OK; |
| 199 | } |
| 200 | |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 201 | |
| 202 | /* Retrieves the interface flags related to sockfd */ |
| 203 | int _xiointerface_get_iff( |
| 204 | int sockfd, |
| 205 | const char *name, |
| 206 | short *save_iff) |
| 207 | { |
| 208 | struct ifreq ifr; |
| 209 | |
| 210 | memset(&ifr, 0, sizeof(ifr)); |
| 211 | strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); |
| 212 | if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { |
| 213 | Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s", |
| 214 | sockfd, ifr.ifr_name, strerror(errno)); |
| 215 | } |
| 216 | *save_iff = ifr.ifr_flags; |
| 217 | return 0; |
| 218 | } |
| 219 | |
| 220 | /* Applies the interface flags to the socket FD. |
| 221 | Used by INTERFACE and TUN |
| 222 | */ |
| 223 | int _xiointerface_set_iff( |
| 224 | int sockfd, |
| 225 | const char *name, |
| 226 | short new_iff) |
| 227 | { |
| 228 | struct ifreq ifr; |
| 229 | |
| 230 | memset(&ifr, 0, sizeof(ifr)); |
| 231 | strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); |
| 232 | if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { |
| 233 | Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s", |
| 234 | sockfd, ifr.ifr_name, strerror(errno)); |
| 235 | } |
| 236 | ifr.ifr_flags = new_iff; |
| 237 | if (Ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { |
| 238 | Error4("ioctl(%d, SIOCSIFFLAGS, {\"%s\", %hd}: %s", |
| 239 | sockfd, ifr.ifr_name, ifr.ifr_flags, strerror(errno)); |
| 240 | } |
| 241 | return 0; |
| 242 | } |
| 243 | |
| 244 | /* Applies the interface flags to the socket FD |
| 245 | Used by INTERFACE and TUN |
| 246 | */ |
| 247 | int _xiointerface_apply_iff( |
| 248 | int sockfd, |
| 249 | const char *name, |
| 250 | short iff_opts[2]) |
| 251 | { |
| 252 | struct ifreq ifr; |
| 253 | |
| 254 | memset(&ifr, 0, sizeof(ifr)); |
| 255 | strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); |
| 256 | if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { |
| 257 | Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s", |
| 258 | sockfd, ifr.ifr_name, strerror(errno)); |
| 259 | } |
| 260 | Debug2("\"%s\": system set flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags); |
| 261 | ifr.ifr_flags |= iff_opts[0]; |
| 262 | ifr.ifr_flags &= ~iff_opts[1]; |
| 263 | Debug2("\"%s\": xio merged flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags); |
| 264 | if (Ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { |
| 265 | Error4("ioctl(%d, SIOCSIFFLAGS, {\"%s\", %hd}: %s", |
| 266 | sockfd, ifr.ifr_name, ifr.ifr_flags, strerror(errno)); |
| 267 | } |
| 268 | ifr.ifr_flags = 0; |
| 269 | if (Ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { |
| 270 | Error3("ioctl(%d, SIOCGIFFLAGS, {\"%s\"}: %s", |
| 271 | sockfd, ifr.ifr_name, strerror(errno)); |
| 272 | } |
| 273 | Debug2("\"%s\": resulting flags: 0x%hx", ifr.ifr_name, ifr.ifr_flags); |
| 274 | return 0; |
| 275 | } |
| 276 | |
Gerhard Rieger | b5640dd | 2023-09-30 15:18:39 +0200 | [diff] [blame] | 277 | |
| 278 | #if HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA |
| 279 | /* Converts the ancillary message in *cmsg into a form useable for further |
| 280 | processing. Knows the specifics of common message types. |
| 281 | On PACKET_AUXDATA it stored the ancillary data in the XFD. |
| 282 | For other types: |
| 283 | returns the number of resulting syntax elements in *num, |
| 284 | returns a sequence of \0 terminated type strings in *typbuff, |
| 285 | returns a sequence of \0 terminated name strings in *nambuff, |
| 286 | returns a sequence of \0 terminated value strings in *valbuff, |
| 287 | the respective len parameters specify the available space in the buffers |
| 288 | returns STAT_OK or other STAT_* |
| 289 | */ |
| 290 | int |
| 291 | xiolog_ancillary_packet(struct single *sfd, |
| 292 | struct cmsghdr *cmsg, int *num, |
| 293 | char *typbuff, int typlen, |
| 294 | char *nambuff, int namlen, |
| 295 | char *envbuff, int envlen, |
| 296 | char *valbuff, int vallen) { |
| 297 | #if LATER |
| 298 | const char *cmsgtype, *cmsgname, *cmsgenvn; |
| 299 | size_t msglen; |
| 300 | #endif |
| 301 | struct tpacket_auxdata *auxp; |
| 302 | int rc = STAT_OK; |
| 303 | |
| 304 | *num = 0; |
| 305 | |
| 306 | #if defined(CMSG_DATA) |
| 307 | |
| 308 | #if LATER |
| 309 | msglen = cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg); |
| 310 | #endif |
| 311 | switch (cmsg->cmsg_type) { |
| 312 | #if HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TPID |
| 313 | case PACKET_AUXDATA: |
| 314 | #if LATER |
| 315 | cmsgname = "packet_auxdata"; |
| 316 | cmsgtype = "auxdata"; |
| 317 | cmsgenvn = "AUXDATA"; |
| 318 | #endif |
| 319 | auxp = (struct tpacket_auxdata *)CMSG_DATA(cmsg); |
| 320 | Info8("%s(): Ancillary message: PACKET_AUXDATA: status="F_uint32_t", len="F_uint32_t", snaplen="F_uint32_t", mac="F_uint16_t", net="F_uint16_t", vlan_tci="F_uint16_t", vlan_tpid="F_uint16_t"", __func__, auxp->tp_status, auxp->tp_len, auxp->tp_snaplen, auxp->tp_mac, auxp->tp_net, auxp->tp_vlan_tci, auxp->tp_vlan_tpid); |
| 321 | sfd->para.socket.ancill_data_packet_auxdata = *auxp; |
| 322 | sfd->para.socket.ancill_flag.packet_auxdata = 1; |
| 323 | snprintf(typbuff, typlen, "PACKET.%u", cmsg->cmsg_type); |
| 324 | nambuff[0] = '\0'; strncat(nambuff, "vlan", namlen-1); |
| 325 | snprintf(strchr(valbuff, '\0')-1/*def \n*/, vallen-strlen(valbuff)+1, ", %d", auxp->tp_vlan_tci); |
| 326 | break; |
| 327 | #endif /* HAVE_STRUCT_TPACKET_AUXDATA_TP_VLAN_TPID */ |
| 328 | default: /* binary data */ |
| 329 | Warn1("xiolog_ancillary_packet(): INTERNAL: cmsg_type=%d not handled", cmsg->cmsg_type); |
| 330 | return rc; |
| 331 | } |
| 332 | return rc; |
| 333 | |
| 334 | #else /* !defined(CMSG_DATA) */ |
| 335 | |
| 336 | return STAT_NORETRY; |
| 337 | |
| 338 | #endif /* !defined(CMSG_DATA) */ |
| 339 | } |
| 340 | #endif /* HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA */ |
| 341 | |
Gerhard Rieger | 47af17d | 2023-10-26 19:08:26 +0200 | [diff] [blame] | 342 | #endif /* _WITH_INTERFACE */ |