* Checks received arp data against existing @la. * Updates lle state/performs notification if necessary. */
| 1163 | * Updates lle state/performs notification if necessary. |
| 1164 | */ |
| 1165 | static void |
| 1166 | arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp, |
| 1167 | int bridged, struct llentry *la) |
| 1168 | { |
| 1169 | struct sockaddr sa; |
| 1170 | struct mbuf *m_hold, *m_hold_next; |
| 1171 | uint8_t linkhdr[LLE_MAX_LINKHDR]; |
| 1172 | size_t linkhdrsize; |
| 1173 | int lladdr_off; |
| 1174 | char addrbuf[INET_ADDRSTRLEN]; |
| 1175 | |
| 1176 | LLE_WLOCK_ASSERT(la); |
| 1177 | |
| 1178 | /* the following is not an error when doing bridging */ |
| 1179 | if (!bridged && la->lle_tbl->llt_ifp != ifp) { |
| 1180 | if (log_arp_wrong_iface) |
| 1181 | ARP_LOG(LOG_WARNING, "%s is on %s " |
| 1182 | "but got reply from %*D on %s\n", |
| 1183 | inet_ntoa_r(isaddr, addrbuf), |
| 1184 | la->lle_tbl->llt_ifp->if_xname, |
| 1185 | ifp->if_addrlen, (u_char *)ar_sha(ah), ":", |
| 1186 | ifp->if_xname); |
| 1187 | LLE_WUNLOCK(la); |
| 1188 | return; |
| 1189 | } |
| 1190 | if ((la->la_flags & LLE_VALID) && |
| 1191 | bcmp(ar_sha(ah), la->ll_addr, ifp->if_addrlen)) { |
| 1192 | if (la->la_flags & LLE_STATIC) { |
| 1193 | LLE_WUNLOCK(la); |
| 1194 | if (log_arp_permanent_modify) |
| 1195 | ARP_LOG(LOG_ERR, |
| 1196 | "%*D attempts to modify " |
| 1197 | "permanent entry for %s on %s\n", |
| 1198 | ifp->if_addrlen, |
| 1199 | (u_char *)ar_sha(ah), ":", |
| 1200 | inet_ntoa_r(isaddr, addrbuf), |
| 1201 | ifp->if_xname); |
| 1202 | return; |
| 1203 | } |
| 1204 | if (log_arp_movements) { |
| 1205 | ARP_LOG(LOG_INFO, "%s moved from %*D " |
| 1206 | "to %*D on %s\n", |
| 1207 | inet_ntoa_r(isaddr, addrbuf), |
| 1208 | ifp->if_addrlen, |
| 1209 | (u_char *)la->ll_addr, ":", |
| 1210 | ifp->if_addrlen, (u_char *)ar_sha(ah), ":", |
| 1211 | ifp->if_xname); |
| 1212 | } |
| 1213 | } |
| 1214 | |
| 1215 | /* Calculate full link prepend to use in lle */ |
| 1216 | linkhdrsize = sizeof(linkhdr); |
| 1217 | if (lltable_calc_llheader(ifp, AF_INET, ar_sha(ah), linkhdr, |
| 1218 | &linkhdrsize, &lladdr_off) != 0) |
| 1219 | return; |
| 1220 | |
| 1221 | /* Check if something has changed */ |
| 1222 | if (memcmp(la->r_linkdata, linkhdr, linkhdrsize) != 0 || |
no test coverage detected