예제 #1
0
파일: hostmon.c 프로젝트: rogerhu/dd-wrt
static struct ethtabent *addethentry(struct ethtab *table,
				     unsigned int linktype, char *ifname,
				     char *addr, struct eth_desc *list)
{
	struct ethtabent *ptemp;

	ptemp = addethnode(table);

	if (ptemp == NULL)
		return NULL;

	ptemp->type = 0;
	memcpy(&(ptemp->un.desc.eth_addr), addr, ETH_ALEN);
	strcpy(ptemp->un.desc.desc, "");

	convmacaddr(addr, ptemp->un.desc.ascaddr);

	ptemp->un.desc.linktype = linktype;
	struct eth_desc *desc = NULL;

	list_for_each_entry(desc, &list->hd_list, hd_list)
		if (!strcasecmp(desc->hd_mac, ptemp->un.desc.ascaddr))
			strcpy(ptemp->un.desc.desc, desc->hd_desc);

	strcpy(ptemp->un.desc.ifname, ifname);

	if (strcmp(ptemp->un.desc.desc, "") == 0)
		ptemp->un.desc.withdesc = 0;
	else
		ptemp->un.desc.withdesc = 1;

	ptemp->un.desc.printed = 0;

	ptemp = addethnode(table);

	if (ptemp == NULL)
		return NULL;

	ptemp->type = 1;
	ptemp->un.figs.inpcount = 0;
	ptemp->un.figs.outpcount = 0;
	ptemp->un.figs.inspanbr = ptemp->un.figs.outspanbr = 0;
	ptemp->un.figs.inippcount = ptemp->un.figs.outippcount = 0;
	ptemp->un.figs.inbcount = ptemp->un.figs.outbcount = 0;
	rate_alloc(&ptemp->un.figs.inrate, 5);
	rate_alloc(&ptemp->un.figs.outrate, 5);

	table->entcount++;

	wmove(table->borderwin, LINES - 3, 1);
	wprintw(table->borderwin, " %u entries ", table->entcount);

	return ptemp;
}
예제 #2
0
파일: tcptable.c 프로젝트: josarlo84/iptraf
void updateentry(struct tcptable *table, struct tcptableent *tableentry,
		 struct tcphdr *transpacket, char *packet, int linkproto,
		 unsigned long packetlength, unsigned int bcount,
		 unsigned int fragofs, int logging, int *revlook, int rvnfd,
		 FILE *logfile)
{
	char msgstring[MSGSTRING_MAX];
	char newmacaddr[18];

	if (tableentry->s_fstat != RESOLVED) {
		tableentry->s_fstat =
		    revname(revlook, &tableentry->saddr, tableentry->s_fqdn,
			    sizeof(tableentry->s_fqdn), rvnfd);
		strcpy(tableentry->oth_connection->d_fqdn, tableentry->s_fqdn);
		tableentry->oth_connection->d_fstat = tableentry->s_fstat;
	}
	if (tableentry->d_fstat != RESOLVED) {
		tableentry->d_fstat =
		    revname(revlook, &tableentry->daddr, tableentry->d_fqdn,
			    sizeof(tableentry->d_fqdn), rvnfd);
		strcpy(tableentry->oth_connection->s_fqdn, tableentry->d_fqdn);
		tableentry->oth_connection->s_fstat = tableentry->d_fstat;
	}
	tableentry->pcount++;
	tableentry->bcount += bcount;
	tableentry->psize = packetlength;
	tableentry->spanbr += bcount;

	if (options.mac) {
		memset(newmacaddr, 0, sizeof(newmacaddr));


		/* change updateentry to take struct pkt to remove this */
		if (linkproto == ARPHRD_ETHER) {
			convmacaddr((char *) (((struct ethhdr *) packet)->
					      h_source), newmacaddr);
		} else if (linkproto == ARPHRD_FDDI) {
			convmacaddr((char *) (((struct fddihdr *) packet)->
					      saddr), newmacaddr);
		}

		if (tableentry->smacaddr[0] != '\0') {
			if (strcmp(tableentry->smacaddr, newmacaddr) != 0) {
				snprintf(msgstring, MSGSTRING_MAX,
					 "TCP; %s; from %s:%s to %s:%s: new source MAC address %s (previously %s)",
					 tableentry->ifname, tableentry->s_fqdn,
					 tableentry->s_sname,
					 tableentry->d_fqdn,
					 tableentry->d_sname, newmacaddr,
					 tableentry->smacaddr);
				writelog(logging, logfile, msgstring);
				strcpy(tableentry->smacaddr, newmacaddr);
			}
		} else
			strcpy(tableentry->smacaddr, newmacaddr);
	}

	/*
	 * If this is not the first TCP fragment, skip interpretation of the
	 * TCP header.
	 */

	if ((ntohs(fragofs) & 0x1fff) != 0) {
		tableentry->lastupdate =
		    tableentry->oth_connection->lastupdate = time(NULL);
		return;
	}
	/*
	 * At this point, we have a TCP header, and we proceed to process it.
	 */

	if (tableentry->pcount == 1) {
		if ((transpacket->syn) || (transpacket->rst))
			tableentry->partial = 0;
		else
			tableentry->partial = 1;
	}
	tableentry->win = ntohs(transpacket->window);

	tableentry->stat = 0;

	if (transpacket->syn)
		tableentry->stat |= FLAG_SYN;

	if (transpacket->ack) {
		tableentry->stat |= FLAG_ACK;

		/*
		 * The following sequences are used when the ACK is in response to
		 * a FIN (see comments for FIN below).  If the opposite direction
		 * already has its indicator set to 1 (FIN sent, not ACKed), and
		 * the incoming ACK has the same sequence number as the previously
		 * stored FIN's ack number (i.e. the ACK in response to the opposite
		 * flow's FIN), the opposite direction's state is set to 2 (FIN sent
		 * and ACKed).
		 */

		if ((tableentry->oth_connection->finsent == 1)
		    && (ntohl(transpacket->seq) ==
			tableentry->oth_connection->finack)) {
			tableentry->oth_connection->finsent = 2;

			if (logging) {
				writetcplog(logging, logfile, tableentry,
					    tableentry->psize,
					    "FIN acknowleged");
			}
		}
	}
	/*
	 * The closing sequence is similar, but not identical to the TCP close
	 * sequence described in the RFC.  This sequence is primarily cosmetic.
	 *
	 * When a FIN is sent in a direction, a state indicator is set to 1,
	 * to indicate a FIN sent, but not ACKed yet.  For comparison later,
	 * the acknowlegement number is also saved in the entry.  See comments
	 * in ACK above.
	 */

	if (transpacket->fin) {

		/*
		 * First, we check if the opposite direction has no counts, in which
		 * case we simply mark the entire connection available for reuse.
		 * This is in case packets from a machine pass an interface, but
		 * on the return, completely bypasses any interface on our machine.
		 *
		 * Q: Could such a situation really happen in practice?  I managed to
		 * do it but under *really* ridiculous circumstances.
		 *
		 * A: (as of version 2.5.0, June 2001): Yes this DOES happen in
		 * practice.  Unidirectional satellite feeds can send data straight
		 * to a remote network using you as your upstream.
		 */

		if (tableentry->oth_connection->pcount == 0)
			addtoclosedlist(table, tableentry);
		else {

			/*
			 * That aside, mark the direction as being done, and make it
			 * ready for a complete close upon receipt of an ACK.  We save
			 * the acknowlegement number for identification of the proper
			 * ACK packet when it arrives in the other direction.
			 */

			tableentry->finsent = 1;
			tableentry->finack = ntohl(transpacket->ack_seq);
		}
		if (logging) {
			char flowrate[64];
			sprintf(msgstring,
				"FIN sent; %lu packets, %lu bytes, %s",
				tableentry->pcount, tableentry->bcount,
				tcplog_flowrate_msg(tableentry, flowrate, sizeof(flowrate)));

			writetcplog(logging, logfile, tableentry,
				    tableentry->psize, msgstring);
		}
	}
	if (transpacket->rst) {
		tableentry->stat |= FLAG_RST;
		if (!(tableentry->inclosed))
			addtoclosedlist(table, tableentry);

		if (logging) {
			char flowrate1[64];
			char flowrate2[64];
			snprintf(msgstring, MSGSTRING_MAX,
				 "Connection reset; %lu packets, %lu bytes, %s; opposite direction %lu packets, %lu bytes; %s",
				 tableentry->pcount, tableentry->bcount,
				 tcplog_flowrate_msg(tableentry, flowrate1, sizeof(flowrate1)),
				 tableentry->oth_connection->pcount,
				 tableentry->oth_connection->bcount,
				 tcplog_flowrate_msg(tableentry->oth_connection, flowrate2, sizeof(flowrate2)));
			writetcplog(logging, logfile, tableentry,
				    tableentry->psize, msgstring);
		}
	}
	if (transpacket->psh)
		tableentry->stat |= FLAG_PSH;

	if (transpacket->urg)
		tableentry->stat |= FLAG_URG;

	tableentry->lastupdate = tableentry->oth_connection->lastupdate =
	    time(NULL);
	/*
	 * Shall we add this entry to the closed entry list?  If both
	 * directions have their state indicators set to 2, or one direction
	 * is set to 2, and the other 1, that's it.
	 */

	if ((!tableentry->inclosed)
	    &&
	    (((tableentry->finsent == 2)
	      && ((tableentry->oth_connection->finsent == 1)
		  || (tableentry->oth_connection->finsent == 2)))
	     || ((tableentry->oth_connection->finsent == 2)
		 && ((tableentry->finsent == 1)
		     || (tableentry->finsent == 2)))))
		addtoclosedlist(table, tableentry);

}
예제 #3
0
파일: othptab.c 프로젝트: josarlo84/iptraf
void printothpentry(struct othptable *table, struct othptabent *entry,
		    unsigned int target_row, int logging, FILE * logfile)
{
	char protname[SHORTSTRING_MAX];
	char description[SHORTSTRING_MAX];
	char additional[MSGSTRING_MAX];
	char msgstring[MSGSTRING_MAX];
	char scratchpad[MSGSTRING_MAX];
	char *startstr;

	char *packet_type;

	struct in_addr uninitialized_var(saddr);

	char rarp_mac_addr[18];

	unsigned int unknown = 0;

	struct protoent *protptr;

	wmove(table->borderwin, table->obmaxy - 1, 1);
	if ((table->lastvisible == table->tail) && (table->htstat != TIND)
	    && (table->count >= table->oimaxy)) {
		wprintw(table->borderwin, " Bottom ");
		table->htstat = TIND;
	} else if ((table->firstvisible == table->head)
		   && (table->htstat != HIND)) {
		wprintw(table->borderwin, " Top ");
		table->htstat = HIND;
	}
	if (!(entry->is_ip)) {
		wmove(table->othpwin, target_row, 0);
		scrollok(table->othpwin, 0);
		wattrset(table->othpwin, UNKNATTR);
		wprintw(table->othpwin, "%*c", COLS - 2, ' ');
		scrollok(table->othpwin, 1);
		wmove(table->othpwin, target_row, 1);

		switch (entry->protocol) {
		case ETH_P_ARP:
			sprintf(msgstring, "ARP ");
			switch (ntohs(entry->un.arp.opcode)) {
			case ARPOP_REQUEST:
				strcat(msgstring, "request for ");
				memcpy(&(saddr.s_addr),
				       entry->un.arp.dest_ip_address, 4);
				break;
			case ARPOP_REPLY:
				strcat(msgstring, "reply from ");
				memcpy(&(saddr.s_addr),
				       entry->un.arp.src_ip_address, 4);
				break;
			}

			inet_ntop(AF_INET, &saddr, scratchpad, sizeof(scratchpad));
			strcat(msgstring, scratchpad);
			wattrset(table->othpwin, ARPATTR);
			break;
		case ETH_P_RARP:
			sprintf(msgstring, "RARP ");
			memset(rarp_mac_addr, 0, sizeof(rarp_mac_addr));
			switch (ntohs(entry->un.rarp.opcode)) {
			case ARPOP_RREQUEST:
				strcat(msgstring, "request for ");
				convmacaddr(entry->un.rarp.dest_mac_address,
					    rarp_mac_addr);
				break;
			case ARPOP_RREPLY:
				strcat(msgstring, "reply from ");
				convmacaddr(entry->un.rarp.src_mac_address,
					    rarp_mac_addr);
				break;
			}

			sprintf(scratchpad, "%s", rarp_mac_addr);
			strcat(msgstring, scratchpad);
			wattrset(table->othpwin, ARPATTR);
			break;
		default:
			packet_type = packetlookup(entry->protocol);
			if (packet_type == NULL)
				sprintf(msgstring, "Non-IP (0x%x)",
					entry->protocol);
			else
				sprintf(msgstring, "Non-IP (%s)", packet_type);

			wattrset(table->othpwin, UNKNATTR);
		}

		strcpy(protname, msgstring);
		sprintf(scratchpad, " (%u bytes)", entry->pkt_length);
		strcat(msgstring, scratchpad);

		if ((entry->linkproto == ARPHRD_ETHER)
		    || (entry->linkproto == ARPHRD_FDDI)) {
			sprintf(scratchpad, " from %s to %s on %s",
				entry->smacaddr, entry->dmacaddr, entry->iface);

			strcat(msgstring, scratchpad);
		}
		startstr = msgstring + table->strindex;
		waddnstr(table->othpwin, startstr, COLS - 4);
		writeothplog(logging, logfile, protname, "", "", 0, 0, entry);
		return;
	}
	strcpy(additional, "");
	strcpy(description, "");

	switch (entry->protocol) {
	case IPPROTO_UDP:
		wattrset(table->othpwin, UDPATTR);
		strcpy(protname, "UDP");
		break;
	case IPPROTO_ICMP:
		wattrset(table->othpwin, STDATTR);
		strcpy(protname, "ICMP");
		break;
	case IPPROTO_OSPFIGP:
		wattrset(table->othpwin, OSPFATTR);
		strcpy(protname, "OSPF");
		break;
	case IPPROTO_IGP:
		wattrset(table->othpwin, IGPATTR);
		strcpy(protname, "IGP");
		break;
	case IPPROTO_IGMP:
		wattrset(table->othpwin, IGMPATTR);
		strcpy(protname, "IGMP");
		break;
	case IPPROTO_IGRP:
		wattrset(table->othpwin, IGRPATTR);
		strcpy(protname, "IGRP");
		break;
	case IPPROTO_GRE:
		wattrset(table->othpwin, GREATTR);
		strcpy(protname, "GRE");
		break;
	case IPPROTO_ICMPV6:
		wattrset(table->othpwin, ICMPV6ATTR);
		strcpy(protname, "ICMPv6");
		break;
	case IPPROTO_IPV6:
		wattrset(table->othpwin, IPV6ATTR);
		strcpy(protname, "IPv6 tun");
		break;
	default:
		wattrset(table->othpwin, UNKNIPATTR);
		protptr = getprotobynumber(entry->protocol);
		if (protptr != NULL) {
			sprintf(protname, "%s", protptr->p_aliases[0]);
		} else {
			sprintf(protname, "IP protocol");
			unknown = 1;
		}
	}

	if (!(entry->fragment)) {
		if (entry->protocol == IPPROTO_ICMP) {
			switch (entry->un.icmp.type) {
			case ICMP_ECHOREPLY:
				strcpy(description, "echo rply");
				break;
			case ICMP_ECHO:
				strcpy(description, "echo req");
				break;
			case ICMP_DEST_UNREACH:
				strcpy(description, "dest unrch");
				switch (entry->un.icmp.code) {
				case ICMP_NET_UNREACH:
					strcpy(additional, "ntwk");
					break;
				case ICMP_HOST_UNREACH:
					strcpy(additional, "host");
					break;
				case ICMP_PROT_UNREACH:
					strcpy(additional, "proto");
					break;
				case ICMP_PORT_UNREACH:
					strcpy(additional, "port");
					break;
				case ICMP_FRAG_NEEDED:
					strcpy(additional, "DF set");
					break;
				case ICMP_SR_FAILED:
					strcpy(additional, "src rte fail");
					break;
				case ICMP_NET_UNKNOWN:
					strcpy(additional, "net unkn");
					break;
				case ICMP_HOST_UNKNOWN:
					strcpy(additional, "host unkn");
					break;
				case ICMP_HOST_ISOLATED:
					strcpy(additional, "src isltd");
					break;
				case ICMP_NET_ANO:
					strcpy(additional, "net comm denied");
					break;
				case ICMP_HOST_ANO:
					strcpy(additional, "host comm denied");
					break;
				case ICMP_NET_UNR_TOS:
					strcpy(additional, "net unrch for TOS");
					break;
				case ICMP_HOST_UNR_TOS:
					strcpy(additional,
					       "host unrch for TOS");
					break;
				case ICMP_PKT_FILTERED:
					strcpy(additional, "pkt fltrd");
					break;
				case ICMP_PREC_VIOLATION:
					strcpy(additional, "prec violtn");
					break;
				case ICMP_PREC_CUTOFF:
					strcpy(additional, "prec cutoff");
					break;
				}

				break;
			case ICMP_SOURCE_QUENCH:
				strcpy(description, "src qnch");
				break;
			case ICMP_REDIRECT:
				strcpy(description, "redirct");
				break;
			case ICMP_TIME_EXCEEDED:
				strcpy(description, "time excd");
				break;
			case ICMP_PARAMETERPROB:
				strcpy(description, "param prob");
				break;
			case ICMP_TIMESTAMP:
				strcpy(description, "timestmp req");
				break;
			case ICMP_INFO_REQUEST:
				strcpy(description, "info req");
				break;
			case ICMP_INFO_REPLY:
				strcpy(description, "info rep");
				break;
			case ICMP_ADDRESS:
				strcpy(description, "addr mask req");
				break;
			case ICMP_ADDRESSREPLY:
				strcpy(description, "addr mask rep");
				break;
			default:
				strcpy(description, "bad/unkn");
				break;
			}
		} else if (entry->protocol == IPPROTO_ICMPV6) {
			switch (entry->un.icmp6.type) {
			case ICMP6_DST_UNREACH:
				strcpy(description, "dest unrch");
				switch (entry->un.icmp6.code) {
				case ICMP6_DST_UNREACH_NOROUTE:
					strcpy(additional, "no route");
					break;
				case ICMP6_DST_UNREACH_ADMIN:
					strcpy(additional, "admin");
					break;
#ifdef ICMP6_DST_UNREACH_NOTNEIGHBOR
				case ICMP6_DST_UNREACH_NOTNEIGHBOR:
					strcpy(additional, "not neigh");
#else
				case ICMP6_DST_UNREACH_BEYONDSCOPE:
					strcpy(additional, "not beyondsp");
#endif
					break;
				case ICMP6_DST_UNREACH_ADDR:
					strcpy(additional, "unreach addr");
					break;
				case ICMP6_DST_UNREACH_NOPORT:
					strcpy(additional, "no port");
					break;
				}
				break;
			case ICMP6_PACKET_TOO_BIG:
				strcpy(description, "pkt too big");
				break;
			case ICMP6_TIME_EXCEEDED:
				strcpy(description, "time exceeded");
				break;
			case ICMP6_PARAM_PROB:
				strcpy(description, "param prob");
				break;
			case ICMP6_ECHO_REQUEST:
				strcpy(description, "echo req");
				break;
			case ICMP6_ECHO_REPLY:
				strcpy(description, "echo rply");
				break;
			case ND_ROUTER_SOLICIT:
				strcpy(description, "router sol");
				break;
			case ND_ROUTER_ADVERT:
				strcpy(description, "router adv");
				break;
#ifdef ICMP6_MEMBERSHIP_QUERY
			case ICMP6_MEMBERSHIP_QUERY:
				strcpy(description, "mbrship query");
				break;
#endif
#ifdef ICMP6_MEMBERSHIP_REPORT
			case ICMP6_MEMBERSHIP_REPORT:
				strcpy(description, "mbrship report");
				break;
#endif
#ifdef ICMP6_MEMBERSHIP_REDUCTION
			case ICMP6_MEMBERSHIP_REDUCTION:
				strcpy(description, "mbrship reduc");
				break;
#endif
			case ND_NEIGHBOR_SOLICIT:
				strcpy(description, "neigh sol");
				break;
			case ND_NEIGHBOR_ADVERT:
				strcpy(description, "neigh adv");
				break;
			case ND_REDIRECT:
				strcpy(description, "redirect");
				break;
			default:
				strcpy(description, "bad/unkn");
				break;
			}
		} else if (entry->protocol == IPPROTO_OSPFIGP) {
			switch (entry->un.ospf.type) {
			case OSPF_TYPE_HELLO:
				strcpy(description, "hlo");
				break;
			case OSPF_TYPE_DB:
				strcpy(description, "DB desc");
				break;
			case OSPF_TYPE_LSR:
				strcpy(description, "LSR");
				break;
			case OSPF_TYPE_LSU:
				strcpy(description, "LSU");
				break;
			case OSPF_TYPE_LSA:
				strcpy(description, "LSA");
				break;
			}
			sprintf(additional, "a=%lu r=%s", entry->un.ospf.area,
				entry->un.ospf.routerid);
		}
	} else
		strcpy(description, "fragment");

	strcpy(msgstring, protname);
	strcat(msgstring, " ");

	if (strcmp(description, "") != 0) {
		strcat(msgstring, description);
		strcat(msgstring, " ");
	}
	if (strcmp(additional, "") != 0) {
		sprintf(scratchpad, "(%s) ", additional);
		strcat(msgstring, scratchpad);
	}
	if (unknown) {
		sprintf(scratchpad, "%u ", entry->protocol);
		strcat(msgstring, scratchpad);
	}
	sprintf(scratchpad, "(%u bytes) ", entry->pkt_length);
	strcat(msgstring, scratchpad);

	if ((entry->protocol == IPPROTO_UDP) && (!(entry->fragment))) {
		sprintf(scratchpad, "from %.40s:%s to %.40s:%s", entry->s_fqdn,
			entry->un.udp.s_sname, entry->d_fqdn,
			entry->un.udp.d_sname);
	} else {
		sprintf(scratchpad, "from %.40s to %.40s", entry->s_fqdn,
			entry->d_fqdn);
	}

	strcat(msgstring, scratchpad);

	if (((entry->smacaddr)[0] != '\0') && options.mac) {
		snprintf(scratchpad, MSGSTRING_MAX, " (src HWaddr %s)",
			 entry->smacaddr);
		strcat(msgstring, scratchpad);
	}
	strcat(msgstring, " on ");
	strcat(msgstring, entry->iface);

	scrollok(table->othpwin, 0);
	mvwprintw(table->othpwin, target_row, 0, "%*c", COLS - 2, ' ');
	scrollok(table->othpwin, 1);
	wmove(table->othpwin, target_row, 1);
	startstr = msgstring + table->strindex;
	waddnstr(table->othpwin, startstr, COLS - 4);

	if (logging)
		writeothplog(logging, logfile, protname, description,
			     additional, 1, options.mac, entry);
}
예제 #4
0
파일: othptab.c 프로젝트: josarlo84/iptraf
struct othptabent *add_othp_entry(struct othptable *table, struct pkt_hdr *pkt,
				  struct sockaddr_storage *saddr,
				  struct sockaddr_storage *daddr,
				  int is_ip,
				  int protocol,
				  char *packet2,
				  char *ifname, int *rev_lookup, int rvnfd,
				  int logging, FILE *logfile, int fragment)
{
	struct othptabent *new_entry;
	struct othptabent *temp;

	new_entry = xmallocz(sizeof(struct othptabent));

	new_entry->is_ip = is_ip;
	new_entry->fragment = fragment;

	if (options.mac || !is_ip) {
		if (pkt->pkt_hatype == ARPHRD_ETHER) {
			convmacaddr((char *) pkt->ethhdr->h_source, new_entry->smacaddr);
			convmacaddr((char *) pkt->ethhdr->h_dest, new_entry->dmacaddr);
		} else if (pkt->pkt_hatype == ARPHRD_FDDI) {
			convmacaddr((char *) pkt->fddihdr->saddr, new_entry->smacaddr);
			convmacaddr((char *) pkt->fddihdr->daddr, new_entry->dmacaddr);
		}
	}

	if (is_ip) {
		sockaddr_copy(&new_entry->saddr, saddr);
		sockaddr_copy(&new_entry->daddr, daddr);

		revname(rev_lookup, saddr, new_entry->s_fqdn,
			sizeof(new_entry->s_fqdn), rvnfd);
		revname(rev_lookup, daddr, new_entry->d_fqdn,
			sizeof(new_entry->d_fqdn), rvnfd);

		if (!fragment) {
			if (protocol == IPPROTO_ICMP) {
				new_entry->un.icmp.type =
				    ((struct icmphdr *) packet2)->type;
				new_entry->un.icmp.code =
				    ((struct icmphdr *) packet2)->code;
			} else if (protocol == IPPROTO_ICMPV6) {
				new_entry->un.icmp6.type =
				    ((struct icmp6_hdr *) packet2)->icmp6_type;
				new_entry->un.icmp6.code =
				    ((struct icmp6_hdr *) packet2)->icmp6_code;
			} else if (protocol == IPPROTO_UDP) {
				servlook(ntohs(((struct udphdr *) packet2)->source),
					 IPPROTO_UDP, new_entry->un.udp.s_sname,
					 10);
				servlook(ntohs(((struct udphdr *) packet2)->dest),
					 IPPROTO_UDP, new_entry->un.udp.d_sname,
					 10);
			} else if (protocol == IPPROTO_OSPFIGP) {
				new_entry->un.ospf.type =
				    ((struct ospfhdr *) packet2)->ospf_type;
				new_entry->un.ospf.area =
				    ntohl(((struct ospfhdr *) packet2)->
					  ospf_areaid.s_addr);
				inet_ntop(AF_INET,
					  &((struct ospfhdr *)packet2)->ospf_routerid,
					  new_entry->un.ospf.routerid,
					  sizeof(new_entry->un.ospf.routerid));
			}
		}
	} else {
		new_entry->linkproto = pkt->pkt_hatype;

		if (protocol == ETH_P_ARP) {
			new_entry->un.arp.opcode =
			    ((struct arp_hdr *) packet2)->ar_op;
			memcpy(&(new_entry->un.arp.src_ip_address),
			       &(((struct arp_hdr *) packet2)->ar_sip), 4);
			memcpy(&(new_entry->un.arp.dest_ip_address),
			       &(((struct arp_hdr *) packet2)->ar_tip), 4);
		} else if (protocol == ETH_P_RARP) {
			new_entry->un.rarp.opcode =
			    ((struct arphdr *) packet2)->ar_op;
			memcpy(&(new_entry->un.rarp.src_mac_address),
			       &(((struct arp_hdr *) packet2)->ar_sha), 6);
			memcpy(&(new_entry->un.rarp.dest_mac_address),
			       &(((struct arp_hdr *) packet2)->ar_tha), 6);
		}
	}

	new_entry->protocol = protocol;
	strcpy(new_entry->iface, ifname);

	new_entry->pkt_length = pkt->pkt_len;

	if (table->head == NULL) {
		new_entry->prev_entry = NULL;
		table->head = new_entry;
		table->firstvisible = new_entry;
	}
	/*
	 * Max number of entries in the lower window is 512.  Upon reaching
	 * this figure, oldest entries are thrown out.
	 */

	if (table->count == 512) {
		if (table->firstvisible == table->head) {
			wscrl(table->othpwin, 1);
			printothpentry(table, table->lastvisible->next_entry,
				       table->oimaxy - 1, logging, logfile);
			table->firstvisible = table->firstvisible->next_entry;
			table->lastvisible = table->lastvisible->next_entry;
		}
		temp = table->head;
		table->head = table->head->next_entry;
		table->head->prev_entry = NULL;
		free(temp);
	} else
		table->count++;

	if (table->tail != NULL) {
		new_entry->prev_entry = table->tail;
		table->tail->next_entry = new_entry;
	}
	table->tail = new_entry;
	new_entry->next_entry = NULL;

	table->lastpos++;
	new_entry->index = table->lastpos;

	if (table->count <= table->oimaxy) {
		table->lastvisible = new_entry;
		printothpentry(table, new_entry, table->count - 1, logging,
			       logfile);
	} else if (table->lastvisible == table->tail->prev_entry) {
		wscrl(table->othpwin, 1);
		table->firstvisible = table->firstvisible->next_entry;
		table->lastvisible = table->tail;
		printothpentry(table, new_entry, table->oimaxy - 1, logging,
			       logfile);
	}
	return new_entry;
}
예제 #5
0
void printothpentry(struct othptable *table, struct othptabent *entry,
                    unsigned int target_row, int logging, FILE * logfile)
{
    char protname[SHORTSTRING_MAX];
    char description[SHORTSTRING_MAX];
    char additional[MSGSTRING_MAX];
    char msgstring[MSGSTRING_MAX];
    char scratchpad[MSGSTRING_MAX];
    char sp_buf[SHORTSTRING_MAX];
    char *startstr;

    char *packet_type;

    struct in_addr saddr;
    char rarp_mac_addr[15];

    unsigned int unknown = 0;

    struct protoent *protptr;
    sprintf(sp_buf, "%%%dc", COLS - 2);

    wmove(table->borderwin, table->obmaxy - 1, 1);
    if ((table->lastvisible == table->tail) && (table->htstat != TIND) &&
            (table->count >= table->oimaxy)) {
        wprintw(table->borderwin, " Bottom ");
        table->htstat = TIND;
    } else if ((table->firstvisible == table->head)
               && (table->htstat != HIND)) {
        wprintw(table->borderwin, " Top ");
        table->htstat = HIND;
    }
    if (!(entry->is_ip)) {
        wmove(table->othpwin, target_row, 0);
        scrollok(table->othpwin, 0);
        wattrset(table->othpwin, UNKNATTR);
        wprintw(table->othpwin, sp_buf, ' ');
        scrollok(table->othpwin, 1);
        wmove(table->othpwin, target_row, 1);

        switch (entry->protocol) {
        case ETH_P_ARP:
            sprintf(msgstring, "ARP ");
            switch (ntohs(entry->un.arp.opcode)) {
            case ARPOP_REQUEST:
                strcat(msgstring, "request for ");
                memcpy(&(saddr.s_addr), entry->un.arp.dest_ip_address, 4);
                break;
            case ARPOP_REPLY:
                strcat(msgstring, "reply from ");
                memcpy(&(saddr.s_addr), entry->un.arp.src_ip_address, 4);
                break;
            }

            sprintf(scratchpad, inet_ntoa(saddr));
            strcat(msgstring, scratchpad);
            wattrset(table->othpwin, ARPATTR);
            break;
        case ETH_P_RARP:
            sprintf(msgstring, "RARP ");
            memset(rarp_mac_addr, 0, 15);
            switch (ntohs(entry->un.rarp.opcode)) {
            case ARPOP_RREQUEST:
                strcat(msgstring, "request for ");
                convmacaddr(entry->un.rarp.dest_mac_address,
                            rarp_mac_addr);
                break;
            case ARPOP_RREPLY:
                strcat(msgstring, "reply from ");
                convmacaddr(entry->un.rarp.src_mac_address, rarp_mac_addr);
                break;
            }

            sprintf(scratchpad, rarp_mac_addr);
            strcat(msgstring, scratchpad);
            wattrset(table->othpwin, ARPATTR);
            break;
        default:
            packet_type = packetlookup(entry->protocol);
            if (packet_type == NULL)
                sprintf(msgstring, "Non-IP (0x%x)", entry->protocol);
            else
                sprintf(msgstring, "Non-IP (%s)", packet_type);

            wattrset(table->othpwin, UNKNATTR);
        }

        strcpy(protname, msgstring);
        sprintf(scratchpad, " (%u bytes)", entry->pkt_length);
        strcat(msgstring, scratchpad);

        if ((entry->linkproto == LINK_ETHERNET) ||
                (entry->linkproto == LINK_PLIP) ||
                (entry->linkproto == LINK_FDDI)) {
            sprintf(scratchpad, " from %s to %s on %s",
                    entry->smacaddr, entry->dmacaddr, entry->iface);

            strcat(msgstring, scratchpad);
        }
        startstr = msgstring + table->strindex;
        waddnstr(table->othpwin, startstr, COLS - 4);
        writeothplog(logging, logfile, protname, "", "", 0, 0, entry);
        return;
    }
    strcpy(additional, "");
    strcpy(description, "");

    switch (entry->protocol) {
    case IPPROTO_UDP:
        wattrset(table->othpwin, UDPATTR);
        strcpy(protname, "UDP");
        break;
    case IPPROTO_ICMP:
        wattrset(table->othpwin, STDATTR);
        strcpy(protname, "ICMP");
        break;
    case IPPROTO_OSPFIGP:
        wattrset(table->othpwin, OSPFATTR);
        strcpy(protname, "OSPF");
        break;
    case IPPROTO_IGP:
        wattrset(table->othpwin, IGPATTR);
        strcpy(protname, "IGP");
        break;
    case IPPROTO_IGMP:
        wattrset(table->othpwin, IGMPATTR);
        strcpy(protname, "IGMP");
        break;
    case IPPROTO_IGRP:
        wattrset(table->othpwin, IGRPATTR);
        strcpy(protname, "IGRP");
        break;
    case IPPROTO_GRE:
        wattrset(table->othpwin, GREATTR);
        strcpy(protname, "GRE");
        break;
    default:
        wattrset(table->othpwin, UNKNIPATTR);
        protptr = getprotobynumber(entry->protocol);
        if (protptr != NULL) {
            sprintf(protname, protptr->p_aliases[0]);
        } else {
            sprintf(protname, "IP protocol");
            unknown = 1;
        }
    }

    if (!(entry->fragment)) {
        if (entry->protocol == IPPROTO_ICMP) {
            switch (entry->un.icmp.type) {
            case ICMP_ECHOREPLY:
                strcpy(description, "echo rply");
                break;
            case ICMP_ECHO:
                strcpy(description, "echo req");
                break;
            case ICMP_DEST_UNREACH:
                strcpy(description, "dest unrch");
                switch (entry->un.icmp.code) {
                case ICMP_NET_UNREACH:
                    strcpy(additional, "ntwk");
                    break;
                case ICMP_HOST_UNREACH:
                    strcpy(additional, "host");
                    break;
                case ICMP_PROT_UNREACH:
                    strcpy(additional, "proto");
                    break;
                case ICMP_PORT_UNREACH:
                    strcpy(additional, "port");
                    break;
                case ICMP_FRAG_NEEDED:
                    strcpy(additional, "DF set");
                    break;
                case ICMP_SR_FAILED:
                    strcpy(additional, "src rte fail");
                    break;
                case ICMP_NET_UNKNOWN:
                    strcpy(additional, "net unkn");
                    break;
                case ICMP_HOST_UNKNOWN:
                    strcpy(additional, "host unkn");
                    break;
                case ICMP_HOST_ISOLATED:
                    strcpy(additional, "src isltd");
                    break;
                case ICMP_NET_ANO:
                    strcpy(additional, "net comm denied");
                    break;
                case ICMP_HOST_ANO:
                    strcpy(additional, "host comm denied");
                    break;
                case ICMP_NET_UNR_TOS:
                    strcpy(additional, "net unrch for TOS");
                    break;
                case ICMP_HOST_UNR_TOS:
                    strcpy(additional, "host unrch for TOS");
                    break;
                case ICMP_PKT_FILTERED:
                    strcpy(additional, "pkt fltrd");
                    break;
                case ICMP_PREC_VIOLATION:
                    strcpy(additional, "prec violtn");
                    break;
                case ICMP_PREC_CUTOFF:
                    strcpy(additional, "prec cutoff");
                    break;
                }

                break;
            case ICMP_SOURCE_QUENCH:
                strcpy(description, "src qnch");
                break;
            case ICMP_REDIRECT:
                strcpy(description, "redirct");
                break;
            case ICMP_TIME_EXCEEDED:
                strcpy(description, "time excd");
                break;
            case ICMP_PARAMETERPROB:
                strcpy(description, "param prob");
                break;
            case ICMP_TIMESTAMP:
                strcpy(description, "timestmp req");
                break;
            case ICMP_INFO_REQUEST:
                strcpy(description, "info req");
                break;
            case ICMP_INFO_REPLY:
                strcpy(description, "info rep");
                break;
            case ICMP_ADDRESS:
                strcpy(description, "addr mask req");
                break;
            case ICMP_ADDRESSREPLY:
                strcpy(description, "addr mask rep");
                break;
            default:
                strcpy(description, "bad/unkn");
                break;
            }

        } else if (entry->protocol == IPPROTO_OSPFIGP) {
            switch (entry->un.ospf.type) {
            case OSPF_TYPE_HELLO:
                strcpy(description, "hlo");
                break;
            case OSPF_TYPE_DB:
                strcpy(description, "DB desc");
                break;
            case OSPF_TYPE_LSR:
                strcpy(description, "LSR");
                break;
            case OSPF_TYPE_LSU:
                strcpy(description, "LSU");
                break;
            case OSPF_TYPE_LSA:
                strcpy(description, "LSA");
                break;
            }
            sprintf(additional, "a=%lu r=%s", entry->un.ospf.area,
                    entry->un.ospf.routerid);
        }
    } else
        strcpy(description, "fragment");

    strcpy(msgstring, protname);
    strcat(msgstring, " ");

    if (strcmp(description, "") != 0) {
        strcat(msgstring, description);
        strcat(msgstring, " ");
    }
    if (strcmp(additional, "") != 0) {
        sprintf(scratchpad, "(%s) ", additional);
        strcat(msgstring, scratchpad);
    }
    if (unknown) {
        sprintf(scratchpad, "%u ", entry->protocol);
        strcat(msgstring, scratchpad);
    }
    sprintf(scratchpad, "(%u bytes) ", entry->pkt_length);
    strcat(msgstring, scratchpad);

    if ((entry->protocol == IPPROTO_UDP) && (!(entry->fragment))) {
        sprintf(scratchpad, "from %.25s:%s to %.25s:%s",
                entry->s_fqdn, entry->un.udp.s_sname,
                entry->d_fqdn, entry->un.udp.d_sname);
    } else {
        sprintf(scratchpad, "from %.25s to %.25s", entry->s_fqdn,
                entry->d_fqdn);
    }

    strcat(msgstring, scratchpad);

    if (((entry->smacaddr)[0] != '\0') && (table->mac)) {
        snprintf(scratchpad, MSGSTRING_MAX, " (src HWaddr %s)",
                 entry->smacaddr);
        strcat(msgstring, scratchpad);
    }
    strcat(msgstring, " on ");
    strcat(msgstring, entry->iface);

    wmove(table->othpwin, target_row, 0);
    scrollok(table->othpwin, 0);
    wprintw(table->othpwin, sp_buf, ' ');
    scrollok(table->othpwin, 1);
    wmove(table->othpwin, target_row, 1);
    startstr = msgstring + table->strindex;
    waddnstr(table->othpwin, startstr, COLS - 4);

    if (logging)
        writeothplog(logging, logfile, protname, description, additional,
                     1, table->mac, entry);
}
예제 #6
0
struct othptabent *add_othp_entry(struct othptable *table,
                                  struct tcptable *tcptab,
                                  unsigned long saddr, unsigned long daddr,
                                  int is_ip, int protocol,
                                  unsigned short linkproto, char *packet,
                                  char *packet2, unsigned int br,
                                  char *ifname, int *rev_lookup, int rvnfd,
                                  unsigned int tm, int logging,
                                  FILE * logfile, int servnames,
                                  int fragment, int *nomem)
{
    struct othptabent *new_entry;
    struct othptabent *temp;
    struct in_addr isaddr, idaddr;

    new_entry = malloc(sizeof(struct othptabent));

    if (new_entry == NULL) {
        printnomem();
        *nomem = 1;
        return NULL;
    }
    bzero(new_entry, sizeof(struct othptabent));

    new_entry->is_ip = is_ip;
    new_entry->fragment = fragment;

    if ((table->mac) || (!is_ip)) {
        if ((linkproto == LINK_ETHERNET) || (linkproto == LINK_PLIP)) {
            convmacaddr(((struct ethhdr *) packet)->h_source,
                        new_entry->smacaddr);
            convmacaddr(((struct ethhdr *) packet)->h_dest,
                        new_entry->dmacaddr);
        } else if (linkproto == LINK_FDDI) {
            convmacaddr(((struct fddihdr *) packet)->saddr,
                        new_entry->smacaddr);
            convmacaddr(((struct fddihdr *) packet)->daddr,
                        new_entry->dmacaddr);
        } else if (linkproto == LINK_TR) {
            convmacaddr(((struct trh_hdr *) packet)->saddr,
                        new_entry->smacaddr);
            convmacaddr(((struct trh_hdr *) packet)->daddr,
                        new_entry->dmacaddr);
        }
    }

    if (is_ip) {
        new_entry->saddr = isaddr.s_addr = saddr;
        new_entry->daddr = idaddr.s_addr = daddr;

        revname(rev_lookup, &isaddr, new_entry->s_fqdn, rvnfd);
        revname(rev_lookup, &idaddr, new_entry->d_fqdn, rvnfd);

        if (!fragment) {
            if (protocol == IPPROTO_ICMP) {
                new_entry->un.icmp.type =
                    ((struct icmphdr *) packet2)->type;
                new_entry->un.icmp.code =
                    ((struct icmphdr *) packet2)->code;
            } else if (protocol == IPPROTO_UDP) {
                servlook(servnames, ((struct udphdr *) packet2)->source,
                         IPPROTO_UDP, new_entry->un.udp.s_sname, 10);
                servlook(servnames, ((struct udphdr *) packet2)->dest,
                         IPPROTO_UDP, new_entry->un.udp.d_sname, 10);
            } else if (protocol == IPPROTO_OSPFIGP) {
                new_entry->un.ospf.type =
                    ((struct ospfhdr *) packet2)->ospf_type;
                new_entry->un.ospf.area =
                    ntohl(((struct ospfhdr *) packet2)->ospf_areaid.
                          s_addr);
                strcpy(new_entry->un.ospf.routerid,
                       inet_ntoa(((struct ospfhdr *)
                                  packet2)->ospf_routerid));
            }
        }
    } else {
        new_entry->linkproto = linkproto;

        if (protocol == ETH_P_ARP) {
            new_entry->un.arp.opcode = ((struct arp_hdr *) packet2)->ar_op;
            memcpy(&(new_entry->un.arp.src_ip_address),
                   &(((struct arp_hdr *) packet2)->ar_sip), 4);
            memcpy(&(new_entry->un.arp.dest_ip_address),
                   &(((struct arp_hdr *) packet2)->ar_tip), 4);
        } else if (protocol == ETH_P_RARP) {
            new_entry->un.rarp.opcode = ((struct arphdr *) packet2)->ar_op;
            memcpy(&(new_entry->un.rarp.src_mac_address),
                   &(((struct arp_hdr *) packet2)->ar_sha), 6);
            memcpy(&(new_entry->un.rarp.dest_mac_address),
                   &(((struct arp_hdr *) packet2)->ar_tha), 6);
        }
    }

    new_entry->protocol = protocol;
    strcpy(new_entry->iface, ifname);

    new_entry->pkt_length = br;

    if (table->head == NULL) {
        new_entry->prev_entry = NULL;
        table->head = new_entry;
        table->firstvisible = new_entry;
    }
    /*
     * Max number of entries in the lower window is 512.  Upon reaching
     * this figure, oldest entries are thrown out.
     */

    if (table->count == 512) {
        if (table->firstvisible == table->head) {
            wscrl(table->othpwin, 1);
            printothpentry(table, table->lastvisible->next_entry,
                           table->oimaxy - 1, logging, logfile);
            table->firstvisible = table->firstvisible->next_entry;
            table->lastvisible = table->lastvisible->next_entry;
        }
        temp = table->head;
        table->head = table->head->next_entry;
        table->head->prev_entry = NULL;
        free(temp);
    } else
        table->count++;

    if (table->tail != NULL) {
        new_entry->prev_entry = table->tail;
        table->tail->next_entry = new_entry;
    }
    table->tail = new_entry;
    new_entry->next_entry = NULL;

    table->lastpos++;
    new_entry->index = table->lastpos;

    if (table->count <= table->oimaxy) {
        table->lastvisible = new_entry;
        printothpentry(table, new_entry, table->count - 1, logging,
                       logfile);
    } else if (table->lastvisible == table->tail->prev_entry) {
        wscrl(table->othpwin, 1);
        table->firstvisible = table->firstvisible->next_entry;
        table->lastvisible = table->tail;
        printothpentry(table, new_entry, table->oimaxy - 1, logging,
                       logfile);
    }
    return new_entry;
}