//#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#@> int chkaliases(std::vector<std::string> & argv) { std::string cmdprefix = "/var/smoothwall"; std::string aliasfile = cmdprefix + "/portfw/aliases"; std::string args = "RED"; int error = 0; ConfigCSV aliases(aliasfile); error += readether(argv, args); args = "GREEN"; error += readether(argv, args); args = "ORANGE"; error += readether(argv, args); args = "PURPLE"; error += readether(argv, args); for (int line = aliases.first(); line == 0; line = aliases.next()) { if (aliases[0].find_first_of(":") != std::string::npos) { std::string larg; // Stepping through the array with an index might be simpler and quicker, // but explicits allow us to replace selected values easily in the future larg = aliases[0] + ","; larg += aliases[1] + ","; larg += aliases[2] + ","; larg += aliases[3] + ","; larg += aliases[4] + ","; larg += aliases[5] + ","; larg += aliases[6] + ","; larg += aliases[7] + ","; larg += aliases[8] + ","; larg += aliases[9] + "\n"; argv.push_back(larg); } } return 0; }
/* * Returns 0 if this is the packet we're waiting for * else -1 (and errno == 0) */ static ssize_t rarprecv(struct iodesc *d, void *pkt, size_t len, time_t tleft) { ssize_t n; struct ether_arp *ap; u_int16_t etype; /* host order */ #ifdef RARP_DEBUG if (debug) printf("rarprecv: "); #endif n = readether(d, pkt, len, tleft, &etype); errno = 0; /* XXX */ if (n == -1 || n < sizeof(struct ether_arp)) { #ifdef RARP_DEBUG if (debug) printf("bad len=%d\n", n); #endif return (-1); } if (etype != ETHERTYPE_REVARP) { #ifdef RARP_DEBUG if (debug) printf("bad type=0x%x\n", etype); #endif return (-1); } ap = (struct ether_arp *)pkt; if (ap->arp_hrd != htons(ARPHRD_ETHER) || ap->arp_pro != htons(ETHERTYPE_IP) || ap->arp_hln != sizeof(ap->arp_sha) || ap->arp_pln != sizeof(ap->arp_spa) ) { #ifdef RARP_DEBUG if (debug) printf("bad hrd/pro/hln/pln\n"); #endif return (-1); } if (ap->arp_op != htons(ARPOP_REVREPLY)) { #ifdef RARP_DEBUG if (debug) printf("bad op=0x%x\n", ntohs(ap->arp_op)); #endif return (-1); } /* Is the reply for our Ethernet address? */ if (bcmp(ap->arp_tha, d->myea, 6)) { #ifdef RARP_DEBUG if (debug) printf("unwanted address\n"); #endif return (-1); } /* We have our answer. */ #ifdef RARP_DEBUG if (debug) printf("got it\n"); #endif return (n); }
/* * Receive a UDP packet and validate it is for us. * Caller leaves room for the headers (Ether, IP, UDP) */ ssize_t readudp(struct iodesc *d, void *pkt, size_t len, time_t tleft) { ssize_t n; size_t hlen; struct ip *ip; struct udphdr *uh; struct udpiphdr *ui; struct ip tip; u_int16_t etype; /* host order */ #ifdef NET_DEBUG if (debug) printf("readudp: called\n"); #endif uh = (struct udphdr *)pkt - 1; ip = (struct ip *)uh - 1; n = readether(d, ip, len + sizeof(*ip) + sizeof(*uh), tleft, &etype); if (n < 0 || (size_t)n < sizeof(*ip) + sizeof(*uh)) return -1; /* Ethernet address checks now in readether() */ /* Need to respond to ARP requests. */ if (etype == ETHERTYPE_ARP) { struct arphdr *ah = (void *)ip; if (ah->ar_op == htons(ARPOP_REQUEST)) { /* Send ARP reply */ arp_reply(d, ah); } return -1; } if (etype != ETHERTYPE_IP) { #ifdef NET_DEBUG if (debug) printf("readudp: not IP. ether_type=%x\n", etype); #endif return -1; } /* Check ip header */ if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP) { /* half char */ #ifdef NET_DEBUG if (debug) printf("readudp: IP version or not UDP. ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p); #endif return -1; } hlen = ip->ip_hl << 2; if (hlen < sizeof(*ip) || in_cksum(ip, hlen) != 0) { #ifdef NET_DEBUG if (debug) printf("readudp: short hdr or bad cksum.\n"); #endif return -1; } NTOHS(ip->ip_len); if (n < ip->ip_len) { #ifdef NET_DEBUG if (debug) printf("readudp: bad length %d < %d.\n", n, ip->ip_len); #endif return -1; } if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) { #ifdef NET_DEBUG if (debug) { printf("readudp: bad saddr %s != ", inet_ntoa(d->myip)); printf("%s\n", inet_ntoa(ip->ip_dst)); } #endif return -1; } /* If there were ip options, make them go away */ if (hlen != sizeof(*ip)) { bcopy(((u_char *)ip) + hlen, uh, len - hlen); ip->ip_len = sizeof(*ip); n -= hlen - sizeof(*ip); } if (uh->uh_dport != d->myport) { #ifdef NET_DEBUG if (debug) printf("readudp: bad dport %d != %d\n", d->myport, ntohs(uh->uh_dport)); #endif return -1; } if (uh->uh_sum) { n = ntohs(uh->uh_ulen) + sizeof(*ip); if (n > RECV_SIZE - ETHER_SIZE) { printf("readudp: huge packet, udp len %ld\n", (long)n); return -1; } /* Check checksum (must save and restore ip header) */ tip = *ip; ui = (struct udpiphdr *)ip; bzero(ui->ui_x1, sizeof(ui->ui_x1)); ui->ui_len = uh->uh_ulen; if (in_cksum(ui, n) != 0) { #ifdef NET_DEBUG if (debug) printf("readudp: bad cksum\n"); #endif *ip = tip; return -1; } *ip = tip; } NTOHS(uh->uh_dport); NTOHS(uh->uh_sport); NTOHS(uh->uh_ulen); if (uh->uh_ulen < sizeof(*uh)) { #ifdef NET_DEBUG if (debug) printf("readudp: bad udp len %d < %d\n", uh->uh_ulen, sizeof(*uh)); #endif return -1; } n -= sizeof(*ip) + sizeof(*uh); return (n); }
/* * reads an IP packet * WARNING: the old version stripped the IP options, if there were * any. Because we have absolutely no idea if the upper layer needs * these or not, it's best to leave them there. * * The size returned is the size indicated in the header. */ ssize_t readip(struct iodesc * d, void *pkt, size_t len, time_t tleft, u_int8_t proto) { ssize_t n; size_t hlen; struct ip *ip; u_int16_t etype; ip = (struct ip *) pkt - 1; n = readether(d, ip, len + sizeof(*ip), tleft, &etype); if (n == -1 || (size_t) n < sizeof(*ip)) return -1; if (etype == ETHERTYPE_ARP) { struct arphdr *ah = (void *) ip; if (ah->ar_op == htons(ARPOP_REQUEST)) { /* Send ARP reply */ arp_reply(d, ah); } return -1; } if (etype != ETHERTYPE_IP) { #ifdef NET_DEBUG if (debug) printf("readip: not IP. ether_type=%x\n", etype); #endif return -1; } /* Check ip header */ if (ip->ip_v != IPVERSION || ip->ip_p != proto) { /* half char */ #ifdef NET_DEBUG if (debug) { printf("readip: wrong IP version or wrong proto " "ip_v=%d ip_p=%d\n", ip->ip_v, ip->ip_p); } #endif return -1; } hlen = ip->ip_hl << 2; if (hlen < sizeof(*ip) || ip_cksum(ip, hlen) != 0) { #ifdef NET_DEBUG if (debug) printf("readip: short hdr or bad cksum.\n"); #endif return -1; } if (n < ntohs(ip->ip_len)) { #ifdef NET_DEBUG if (debug) printf("readip: bad length %d < %d.\n", (int) n, ntohs(ip->ip_len)); #endif return -1; } if (d->myip.s_addr && ip->ip_dst.s_addr != d->myip.s_addr) { #ifdef NET_DEBUG if (debug) { printf("readip: bad saddr %s != ", inet_ntoa(d->myip)); printf("%s\n", inet_ntoa(ip->ip_dst)); } #endif return -1; } return (ntohs(ip->ip_len) - 20); }
/* * Returns 0 if this is the packet we're waiting for * else -1 (and errno == 0) */ static ssize_t arprecv(struct iodesc *d, void **pkt, void **payload, time_t tleft, void *extra) { ssize_t n; struct ether_arp *ah; uint16_t etype; /* host order */ void *ptr; #ifdef ARP_DEBUG if (debug) printf("arprecv: "); #endif ptr = NULL; n = readether(d, &ptr, (void **)&ah, tleft, &etype); errno = 0; /* XXX */ if (n == -1 || n < sizeof (struct ether_arp)) { #ifdef ARP_DEBUG if (debug) printf("bad len=%d\n", n); #endif free(ptr); return (-1); } if (etype != ETHERTYPE_ARP) { #ifdef ARP_DEBUG if (debug) printf("not arp type=%d\n", etype); #endif free(ptr); return (-1); } /* Ethernet address now checked in readether() */ if (ah->arp_hrd != htons(ARPHRD_ETHER) || ah->arp_pro != htons(ETHERTYPE_IP) || ah->arp_hln != sizeof (ah->arp_sha) || ah->arp_pln != sizeof (ah->arp_spa)) { #ifdef ARP_DEBUG if (debug) printf("bad hrd/pro/hln/pln\n"); #endif free(ptr); return (-1); } if (ah->arp_op == htons(ARPOP_REQUEST)) { #ifdef ARP_DEBUG if (debug) printf("is request\n"); #endif arp_reply(d, ah); free(ptr); return (-1); } if (ah->arp_op != htons(ARPOP_REPLY)) { #ifdef ARP_DEBUG if (debug) printf("not ARP reply\n"); #endif free(ptr); return (-1); } /* Is the reply from the source we want? */ if (bcmp(&arp_list[arp_num].addr, ah->arp_spa, sizeof (ah->arp_spa))) { #ifdef ARP_DEBUG if (debug) printf("unwanted address\n"); #endif free(ptr); return (-1); } /* We don't care who the reply was sent to. */ /* We have our answer. */ #ifdef ARP_DEBUG if (debug) printf("got it\n"); #endif *pkt = ptr; *payload = ah; return (n); }