| File: | src/usr.sbin/dvmrpd/kmroute.c |
| Warning: | line 97, column 7 Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: kmroute.c,v 1.3 2019/06/28 13:32:47 deraadt Exp $ */ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 2005, 2006 Esben Norby <norby@openbsd.org> |
| 5 | * |
| 6 | * Permission to use, copy, modify, and distribute this software for any |
| 7 | * purpose with or without fee is hereby granted, provided that the above |
| 8 | * copyright notice and this permission notice appear in all copies. |
| 9 | * |
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 17 | */ |
| 18 | |
| 19 | #include <sys/types.h> |
| 20 | #include <sys/socket.h> |
| 21 | #include <netinet/in.h> |
| 22 | #include <arpa/inet.h> |
| 23 | #include <netinet/ip_mroute.h> |
| 24 | |
| 25 | #include <err.h> |
| 26 | #include <errno(*__errno()).h> |
| 27 | #include <stdlib.h> |
| 28 | #include <string.h> |
| 29 | |
| 30 | #include "igmp.h" |
| 31 | #include "dvmrpd.h" |
| 32 | #include "dvmrp.h" |
| 33 | #include "dvmrpe.h" |
| 34 | #include "log.h" |
| 35 | |
| 36 | extern struct dvmrpd_conf *conf; |
| 37 | char *mroute_ptr; /* packet buffer */ |
| 38 | |
| 39 | void main_imsg_compose_rde(int, pid_t, void *, u_int16_t); |
| 40 | |
| 41 | int |
| 42 | kmr_init(int fd) |
| 43 | { |
| 44 | struct iface *iface; |
| 45 | struct route_report rr; |
| 46 | |
| 47 | LIST_FOREACH(iface, &conf->iface_list, entry)for((iface) = ((&conf->iface_list)->lh_first); (iface )!= ((void *)0); (iface) = ((iface)->entry.le_next)) { |
| 48 | log_debug("kmr_init: interface %s", iface->name); |
| 49 | |
| 50 | rr.net.s_addr = iface->addr.s_addr & iface->mask.s_addr; |
| 51 | rr.mask = iface->mask; |
| 52 | rr.nexthop.s_addr = 0; |
| 53 | rr.metric = iface->metric; |
| 54 | rr.ifindex = iface->ifindex; |
| 55 | main_imsg_compose_rde(IMSG_ROUTE_REPORT, -1, &rr, sizeof(rr)); |
| 56 | |
| 57 | mrt_add_vif(conf->mroute_socket, iface); |
| 58 | } |
| 59 | |
| 60 | if ((mroute_ptr = calloc(1, IBUF_READ_SIZE65535)) == NULL((void *)0)) |
| 61 | fatal("kmr_init"); |
| 62 | |
| 63 | return (0); |
| 64 | } |
| 65 | |
| 66 | void |
| 67 | kmr_shutdown(void) |
| 68 | { |
| 69 | struct iface *iface; |
| 70 | |
| 71 | kmr_mfc_decouple(); |
| 72 | kmroute_clear(); |
| 73 | |
| 74 | LIST_FOREACH(iface, &conf->iface_list, entry)for((iface) = ((&conf->iface_list)->lh_first); (iface )!= ((void *)0); (iface) = ((iface)->entry.le_next)) { |
| 75 | log_debug("kmr_shutdown: interface %s", iface->name); |
| 76 | |
| 77 | mrt_del_vif(conf->mroute_socket, iface); |
| 78 | } |
| 79 | |
| 80 | free(mroute_ptr); |
| 81 | } |
| 82 | |
| 83 | void |
| 84 | kmr_recv_msg(int fd, short event, void *bula) |
| 85 | { |
| 86 | struct mfc mfc; |
| 87 | struct igmpmsg kernel_msg; |
| 88 | char *buf; |
| 89 | ssize_t r; |
| 90 | |
| 91 | if (event != EV_READ0x02) |
| 92 | return; |
| 93 | |
| 94 | /* setup buffer */ |
| 95 | buf = mroute_ptr; |
| 96 | |
| 97 | if ((r = recvfrom(fd, buf, IBUF_READ_SIZE65535, 0, NULL((void *)0), NULL((void *)0))) == -1) { |
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r' | |
| 98 | if (errno(*__errno()) != EAGAIN35 && errno(*__errno()) != EINTR4) |
| 99 | log_debug("kmr_recv_msg: error receiving packet"); |
| 100 | return; |
| 101 | } |
| 102 | |
| 103 | memcpy(&kernel_msg, buf, sizeof(kernel_msg)); |
| 104 | |
| 105 | /* we are only interested in kernel messages */ |
| 106 | if (kernel_msg.im_mbz != 0) |
| 107 | return; |
| 108 | |
| 109 | switch (kernel_msg.im_msgtype) { |
| 110 | case IGMPMSG_NOCACHE1: |
| 111 | /* verify that dst is a multicast group */ |
| 112 | if (!IN_MULTICAST(ntohl(kernel_msg.im_dst.s_addr))(((u_int32_t)((__uint32_t)(__builtin_constant_p(kernel_msg.im_dst .s_addr) ? (__uint32_t)(((__uint32_t)(kernel_msg.im_dst.s_addr ) & 0xff) << 24 | ((__uint32_t)(kernel_msg.im_dst.s_addr ) & 0xff00) << 8 | ((__uint32_t)(kernel_msg.im_dst. s_addr) & 0xff0000) >> 8 | ((__uint32_t)(kernel_msg .im_dst.s_addr) & 0xff000000) >> 24) : __swap32md(kernel_msg .im_dst.s_addr))) & ((u_int32_t)(0xf0000000))) == ((u_int32_t )(0xe0000000)))) { |
| 113 | log_debug("kmr_recv_msg: kernel providing garbage!"); |
| 114 | return; |
| 115 | } |
| 116 | |
| 117 | /* send MFC entry to RDE */ |
| 118 | mfc.origin = kernel_msg.im_src; |
| 119 | mfc.group = kernel_msg.im_dst; |
| 120 | mfc.ifindex = kernel_msg.im_vif; |
| 121 | main_imsg_compose_rde(IMSG_MFC_ADD, 0, &mfc, sizeof(mfc)); |
| 122 | break; |
| 123 | case IGMPMSG_WRONGVIF2: |
| 124 | case IGMPMSG_WHOLEPKT3: |
| 125 | case IGMPMSG_BW_UPCALL4: |
| 126 | default: |
| 127 | log_debug("kmr_recv_msg: unhandled msg type %d!", |
| 128 | kernel_msg.im_msgtype); |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | void |
| 133 | kmr_mfc_couple(void) |
| 134 | { |
| 135 | log_info("kernel multicast forwarding cache coupled"); |
| 136 | } |
| 137 | |
| 138 | void |
| 139 | kmr_mfc_decouple(void) |
| 140 | { |
| 141 | log_info("kernel multicast forwarding cache decoupled"); |
| 142 | } |
| 143 | |
| 144 | void |
| 145 | kmroute_clear(void) |
| 146 | { |
| 147 | |
| 148 | } |
| 149 | |
| 150 | int |
| 151 | mrt_init(int fd) |
| 152 | { |
| 153 | int flag = 1; |
| 154 | |
| 155 | if (setsockopt(fd, IPPROTO_IP0, MRT_INIT100, &flag, |
| 156 | sizeof(flag)) == -1) { |
| 157 | log_warn("mrt_init: error setting MRT_INIT"); |
| 158 | return (-1); |
| 159 | } |
| 160 | |
| 161 | return (0); |
| 162 | } |
| 163 | |
| 164 | int |
| 165 | mrt_done(int fd) |
| 166 | { |
| 167 | int flag = 0; |
| 168 | |
| 169 | if (setsockopt(fd, IPPROTO_IP0, MRT_DONE101, &flag, |
| 170 | sizeof(flag)) == -1) { |
| 171 | log_warn("mrt_done: error setting MRT_DONE"); |
| 172 | return (-1); |
| 173 | } |
| 174 | |
| 175 | return (0); |
| 176 | } |
| 177 | |
| 178 | int |
| 179 | mrt_add_vif(int fd, struct iface *iface) |
| 180 | { |
| 181 | struct vifctl vc; |
| 182 | |
| 183 | vc.vifc_vifi = iface->ifindex; |
| 184 | vc.vifc_flags = 0; |
| 185 | vc.vifc_threshold = 1; |
| 186 | vc.vifc_rate_limit = 0; |
| 187 | vc.vifc_lcl_addr.s_addr = iface->addr.s_addr; |
| 188 | vc.vifc_rmt_addr.s_addr = 0; |
| 189 | |
| 190 | if (setsockopt(fd, IPPROTO_IP0, MRT_ADD_VIF102, &vc, |
| 191 | sizeof(vc)) == -1) { |
| 192 | log_warn("mrt_add_vif: error adding VIF"); |
| 193 | return (-1); |
| 194 | } |
| 195 | |
| 196 | return (0); |
| 197 | } |
| 198 | |
| 199 | void |
| 200 | mrt_del_vif(int fd, struct iface *iface) |
| 201 | { |
| 202 | vifi_t vifi; |
| 203 | |
| 204 | vifi = iface->ifindex; |
| 205 | |
| 206 | if (setsockopt(fd, IPPROTO_IP0, MRT_DEL_VIF103, &vifi, |
| 207 | sizeof(vifi)) == -1) |
| 208 | log_warn("mrt_del_vif: error deleting VIF"); |
| 209 | } |
| 210 | |
| 211 | int |
| 212 | mrt_add_mfc(int fd, struct mfc *mfc) |
| 213 | { |
| 214 | struct mfcctl mc; |
| 215 | int i; |
| 216 | |
| 217 | log_debug("mrt_add_mfc: interface %d, group %s", mfc->ifindex, |
| 218 | inet_ntoa(mfc->group)); |
| 219 | |
| 220 | mc.mfcc_origin = mfc->origin; |
| 221 | mc.mfcc_mcastgrp = mfc->group; |
| 222 | mc.mfcc_parent = mfc->ifindex; |
| 223 | |
| 224 | for (i = 0; i < MAXVIFS32; i++) { |
| 225 | mc.mfcc_ttls[i] = mfc->ttls[i]; |
| 226 | } |
| 227 | |
| 228 | if (setsockopt(fd, IPPROTO_IP0, MRT_ADD_MFC104, &mc, sizeof(mc)) |
| 229 | == -1) { |
| 230 | log_warnx("mrt_add_mfc: error adding group %s to interface %d", |
| 231 | inet_ntoa(mfc->group), mfc->ifindex); |
| 232 | return (-1); |
| 233 | } |
| 234 | |
| 235 | return (0); |
| 236 | } |
| 237 | |
| 238 | int |
| 239 | mrt_del_mfc(int fd, struct mfc *mfc) |
| 240 | { |
| 241 | struct mfcctl mc; |
| 242 | |
| 243 | log_debug("mrt_del_mfc: group %s", inet_ntoa(mfc->group)); |
| 244 | |
| 245 | mc.mfcc_origin = mfc->origin; |
| 246 | mc.mfcc_mcastgrp = mfc->group; |
| 247 | |
| 248 | if (setsockopt(fd, IPPROTO_IP0, MRT_DEL_MFC105, &mc, sizeof(mc)) |
| 249 | == -1) { |
| 250 | log_warnx("mrt_del_mfc: error deleting group %s ", |
| 251 | inet_ntoa(mfc->group)); |
| 252 | return (-1); |
| 253 | } |
| 254 | |
| 255 | return (0); |
| 256 | } |