void got_one(void) { struct sockaddr_in from; struct ether_addr hfrom; struct in_addr ifrom; ssize_t result; if ((result = receive_packet(&from, &hfrom)) == -1) { warning("receive_packet failed on %s: %s", ifi->name, strerror(errno)); ifi->errors++; if ((!interface_status(ifi->name)) || (ifi->noifmedia && ifi->errors > 20)) { /* our interface has gone away. */ error("Interface %s no longer appears valid.", ifi->name); } return; } if (result == 0) return; ifrom.s_addr = from.sin_addr.s_addr; do_packet(from.sin_port, ifrom, &hfrom); }
void receive_packet(unsigned int index, unsigned char *packet, unsigned int len, unsigned int from_port, struct iaddr *from, bool was_unicast) { assert(packet); assert(from); assert(from->len == 4 || from->len == 16); bool found = false; unsigned int i = 0; struct interface_info *info; for (info = interfaces; info; info = info->next) { if (i == index) { found = true; break; } ++i; } if (!found) return; if (from->len == 4) { do_packet(info, (struct dhcp_packet *)packet, len, from_port, *from, &info->hw_address); } else if (from->len == 16) { isc_boolean_t was_unicast_isc = was_unicast ? ISC_TRUE : ISC_FALSE; do_packet6(info, (char *)packet, len, from_port, from, was_unicast_isc); } }
static void my_rhandler(connection_t * cptr) { char buf[BUFSIZE * 2]; if (my_read(cptr, buf) <= 0) connection_close(cptr); else do_packet(cptr, buf); }
static void my_rhandler(connection_t * cptr) { char buf[BUFSIZE * 2]; if (!my_read(cptr, buf)) connection_close(cptr); do_packet(buf); }
void got_one(struct protocol *l) { struct sockaddr_in from; struct hardware hfrom; struct iaddr ifrom; ssize_t result; union { unsigned char packbuf[4095]; struct dhcp_packet packet; } u; struct interface_info *ip = l->local; bzero(&u, sizeof(u)); if ((result = receive_packet(ip, u.packbuf, sizeof u, &from, &hfrom)) == -1) { warning("receive_packet failed on %s: %s", ip->name, strerror(errno)); ip->errors++; if ((!interface_status(ip)) || (ip->noifmedia && ip->errors > 20)) { /* our interface has gone away. */ warning("Interface %s no longer appears valid.", ip->name); ip->dead = 1; interfaces_invalidated = 1; close(l->fd); remove_protocol(l); free(ip); } return; } if (result == 0) return; ifrom.len = 4; memcpy(ifrom.iabuf, &from.sin_addr, ifrom.len); do_packet(ip, &u.packet, result, from.sin_port, ifrom, &hfrom); }
void udpsock_handler(struct protocol *protocol) { int sockio; char cbuf[256], ifname[IF_NAMESIZE]; ssize_t len; struct udpsock *udpsock = protocol->local; struct msghdr m; struct cmsghdr *cm; struct iovec iov[1]; struct sockaddr_storage ss; struct sockaddr_in *sin4; struct sockaddr_dl *sdl = NULL; struct interface_info iface; struct iaddr from, addr; unsigned char packetbuf[4095]; struct dhcp_packet *packet = (struct dhcp_packet *)packetbuf; struct hardware hw; struct ifreq ifr; struct subnet *subnet; memset(&hw, 0, sizeof(hw)); iov[0].iov_base = packetbuf; iov[0].iov_len = sizeof(packetbuf); memset(&m, 0, sizeof(m)); m.msg_name = &ss; m.msg_namelen = sizeof(ss); m.msg_iov = iov; m.msg_iovlen = 1; m.msg_control = cbuf; m.msg_controllen = sizeof(cbuf); memset(&iface, 0, sizeof(iface)); if ((len = recvmsg(udpsock->sock, &m, 0)) < 0) { warning("receiving a DHCP message failed: %s", strerror(errno)); return; } if (ss.ss_family != AF_INET) { warning("received DHCP message is not AF_INET"); return; } sin4 = (struct sockaddr_in *)&ss; for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&m); m.msg_controllen != 0 && cm; cm = (struct cmsghdr *)CMSG_NXTHDR(&m, cm)) { if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF) sdl = (struct sockaddr_dl *)CMSG_DATA(cm); } if (sdl == NULL) { warning("could not get the received interface by IP_RECVIF"); return; } if_indextoname(sdl->sdl_index, ifname); if ((sockio = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { warning("socket creation failed: %s", strerror(errno)); return; } strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sockio, SIOCGIFADDR, &ifr, sizeof(ifr)) != 0) { warning("Failed to get address for %s: %s", ifname, strerror(errno)); close(sockio); return; } close(sockio); if (ifr.ifr_addr.sa_family != AF_INET) return; iface.is_udpsock = 1; iface.send_packet = udpsock_send_packet; iface.wfdesc = udpsock->sock; iface.ifp = 𝔦 iface.index = sdl->sdl_index; iface.primary_address = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; strlcpy(iface.name, ifname, sizeof(iface.name)); addr.len = 4; memcpy(&addr.iabuf, &iface.primary_address, addr.len); if ((subnet = find_subnet(addr)) == NULL) return; iface.shared_network = subnet->shared_network ; from.len = 4; memcpy(&from.iabuf, &sin4->sin_addr, from.len); do_packet(&iface, packet, len, sin4->sin_port, from, &hw); }
static int do_stop_packet(const struct radutmp *u) { return do_packet(0, 0, u); }
static int do_accton_packet(uint32_t nasaddr) { return do_packet(1, nasaddr, 0); }