示例#1
0
文件: gdb.c 项目: jrcatbagan/umon-old
/* processGDB():
 * This is the function that allows a remote gdb host to connect to
 * the monitor with gdb at the udp level.  The connection command in
 * gdb to do this is:
 *
 *	target remote udp:TARGET_IP:TARGET_PORT
 */
int
processGDB(struct ether_header *ehdr,ushort size)
{
	char	*gdbp;
	struct	ip *ihdr, *ti, *ri;
	struct	Udphdr *uhdr, *tu, *ru;
	struct	ether_header *te;

	/* If SHOW_GDB is set (via ether -vg), then we dump the trace to
	 * the console; otherwise, we use mtrace.
	 */
#if INCLUDE_ETHERVERBOSE
	if (EtherVerbose & SHOW_GDB)
		gdbTrace = printf;
	else
#endif
		gdbTrace = Mtrace;

	ihdr = (struct ip *)(ehdr + 1);
	uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr));
	gdbp = (char *)(uhdr + 1);
	size = ecs(uhdr->uh_ulen) - sizeof(struct Udphdr);

	/* Check for ACK/NAK here:
	 */
	if (size == 1) {
		if ((*gdbp == '+') || (*gdbp == '-')) {
			gdbTrace("GDB_%s\n",*gdbp == '+' ? "ACK" : "NAK");
			return(0);
		}
	}

	/* Copy the incoming udp payload (the gdb command) to gdbIbuf[]
	 * and NULL terminate it...
	 */
	memcpy((char *)gdbIbuf,(char *)gdbp,size);
	gdbIbuf[size] = 0;

	/* Now that we've stored away the GDB command request, we
	 * initially respond with the GDB acknowledgement ('+')...
	 */
	te = EtherCopy(ehdr);
	ti = (struct ip *) (te + 1);
	ri = (struct ip *) (ehdr + 1);
	ti->ip_vhl = ri->ip_vhl;
	ti->ip_tos = ri->ip_tos;
	ti->ip_len = ecs((1 + (sizeof(struct ip) + sizeof(struct Udphdr))));
	ti->ip_id = ipId();
	ti->ip_off = ri->ip_off;
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
		sizeof(struct in_addr));
	memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr),
		sizeof(struct in_addr));
	tu = (struct Udphdr *) (ti + 1);
	ru = (struct Udphdr *) (ri + 1);
	tu->uh_sport = ru->uh_dport;
	tu->uh_dport = ru->uh_sport;
	tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + 1));
	gdbp = (char *)(tu+1);
	*gdbp = '+';

	ipChksum(ti);		/* Compute checksum of ip hdr */
	udpChksum(ti);		/* Compute UDP checksum */

	sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + 
		sizeof(struct Udphdr) + 1);

	/* Wrap the processing of the incoming packet with a set/clear
	 * of the gdbUdp flag so that the other gdb code can act 
	 * accordingly.
	 */
	gdbUdp = 1;
	if (gdb_cmd(gdbIbuf) == 0) {
		gdbUdp = 0;
		return(0);
	}
	gdbUdp = 0;

	/* Add 1 to the gdbRlen to include the NULL termination.
	 */
	gdbRlen++;	


	/* The second respons is only done if gdb_cmd returns non-zero.
	 * It is the response to the gdb command issued by the debugger
	 * on the host.
	 */
	te = EtherCopy(ehdr);
	ti = (struct ip *) (te + 1);
	ri = (struct ip *) (ehdr + 1);
	ti->ip_vhl = ri->ip_vhl;
	ti->ip_tos = ri->ip_tos;
	ti->ip_len = ecs((gdbRlen + (sizeof(struct ip) + sizeof(struct Udphdr))));
	ti->ip_id = ipId();
	ti->ip_off = ri->ip_off;
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr,
		sizeof(struct in_addr));
	memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr),
		sizeof(struct in_addr));

	tu = (struct Udphdr *) (ti + 1);
	ru = (struct Udphdr *) (ri + 1);
	tu->uh_sport = ru->uh_dport;
	tu->uh_dport = ru->uh_sport;
	tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + gdbRlen));
	memcpy((char *)(tu+1),(char *)gdbRbuf,gdbRlen);

	ipChksum(ti);		/* Compute checksum of ip hdr */
	udpChksum(ti);		/* Compute UDP checksum */

	sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + 
		sizeof(struct Udphdr) + gdbRlen);

	return(1);
}
示例#2
0
int
sendSyslog(uchar *syslogsrvr,char *msg, short port, int null)
{
	int	msglen;
	uchar *syslogmsg;
	ushort ip_len, sport;
	struct ether_header *enetp;
	struct ip *ipp;
	struct Udphdr *udpp;
	uchar	binip[8], binenet[8], *enetaddr;

	/* msglen is the length of the message, plus optionally the 
	 * terminating null character (-n option of syslog command)..
	 */
	msglen = strlen(msg) + null;

	/* Convert IP address to binary:
	 */
	if (IpToBin((char *)syslogsrvr,(unsigned char *)binip) < 0)
		return(0);

	/* Get the ethernet address for the IP:
	 */
	enetaddr = ArpEther(binip,binenet,0);
	if (!enetaddr) {
		printf("ARP failed for %s\n",syslogsrvr);
		return(0);
	}

	/* Retrieve an ethernet buffer from the driver and populate the
	 * ethernet level of packet:
	 */
	enetp = (struct ether_header *) getXmitBuffer();
	memcpy((char *)&enetp->ether_shost,(char *)BinEnetAddr,6);
	memcpy((char *)&enetp->ether_dhost,(char *)binenet,6);
	enetp->ether_type = ecs(ETHERTYPE_IP);

	/* Move to the IP portion of the packet and populate it
	 * appropriately:
	 */
	ipp = (struct ip *) (enetp + 1);
	ipp->ip_vhl = IP_HDR_VER_LEN;
	ipp->ip_tos = 0;
	ip_len = sizeof(struct ip) + sizeof(struct Udphdr) + msglen;
	ipp->ip_len = ecs(ip_len);
	ipp->ip_id = ipId();
	ipp->ip_off = 0;
	ipp->ip_ttl = UDP_TTL;
	ipp->ip_p = IP_UDP;
	memcpy((char *)&ipp->ip_src.s_addr,(char *)BinIpAddr,4);
	memcpy((char *)&ipp->ip_dst.s_addr,(char *)binip,4);

	/* Now UDP...
	 */
	sport = port+1;
	udpp = (struct Udphdr *) (ipp + 1);
	udpp->uh_sport = ecs(sport);
	udpp->uh_dport = ecs(port);
	udpp->uh_ulen = ecs((ushort)(ip_len - sizeof(struct ip)));

	/* Finally, the SYSLOG data ...
	 */
	syslogmsg = (uchar *)(udpp+1);
	strcpy((char *)syslogmsg,(char *)msg);

	ipChksum(ipp);			/* Compute csum of ip hdr */
	udpChksum(ipp);			/* Compute UDP checksum */

	sendBuffer(ETHERSIZE + IPSIZE + UDPSIZE + msglen);
	return(0);
}
示例#3
0
/* BOOTPStartup()
 *	The DHCPDISCOVER is issued as an ethernet broadcast.  IF the bootp
 *	flag is non-zero then just do a bootp request (a subset of the 
 *	DHCPDISCOVER stuff).
 */
int
BOOTPStartup(short seconds)
{
	struct	dhcphdr *dhcpdata;
	struct	bootphdr *bootpdata;
	struct	ether_header *te;
	struct	ip *ti;
	struct	Udphdr *tu;
	ushort	uh_ulen;
	int		optlen;

	/* Retrieve an ethernet buffer from the driver and populate the
	 * ethernet level of packet:
	 */
	te = (struct ether_header *) getXmitBuffer();
	memcpy((char *)&te->ether_shost,(char *)BinEnetAddr,6);
	memcpy((char *)&te->ether_dhost,(char *)BroadcastAddr,6);
	te->ether_type = ecs(ETHERTYPE_IP);

	/* Move to the IP portion of the packet and populate it appropriately: */
	ti = (struct ip *) (te + 1);
	ti->ip_vhl = IP_HDR_VER_LEN;
	ti->ip_tos = 0;
	ti->ip_id = 0;
	ti->ip_off = ecs(0x4000);	/* No fragmentation allowed */
	ti->ip_ttl = UDP_TTL;
	ti->ip_p = IP_UDP;
	memset((char *)&ti->ip_src.s_addr,0,4);
	memset((char *)&ti->ip_dst.s_addr,0xff,4);

	/* Now udp... */
	tu = (struct Udphdr *) (ti + 1);
	tu->uh_sport = ecs(DhcpClientPort);
	tu->uh_dport = ecs(DhcpServerPort);

	/* First the stuff that is the same for BOOTP or DHCP... */
	bootpdata = (struct bootphdr *)(tu+1);
	dhcpdata = (struct dhcphdr *)(tu+1);
	dhcpdata->op = DHCPBOOTP_REQUEST;
	dhcpdata->htype = 1;
	dhcpdata->hlen = 6;
	dhcpdata->hops = 0;
	dhcpdata->seconds = ecs(seconds);
	memset((char *)dhcpdata->bootfile,0,
		sizeof(dhcpdata->bootfile));
	memset((char *)dhcpdata->server_hostname,0,
		sizeof(dhcpdata->server_hostname));

	/* For the first request issued, establish a transaction id based
	 * on a crc32 of the mac address.  For each request after that,
	 * just increment.
	 */
	if (!BOOTPTransactionId)
		BOOTPTransactionId = BinEnetAddr[5];
	else
		BOOTPTransactionId++;

	memcpy((char *)&dhcpdata->transaction_id,(char *)&BOOTPTransactionId,4);
	memset((char *)&dhcpdata->client_ip,0,4);
	memset((char *)&dhcpdata->your_ip,0,4);
	memset((char *)&dhcpdata->server_ip,0,4);
	memset((char *)&dhcpdata->router_ip,0,4);
	memcpy((char *)dhcpdata->client_macaddr,(char *)BinEnetAddr,6);
	dhcpdata->flags = 0;

	self_ecs(dhcpdata->flags);

	/* Finally, the DHCP or BOOTP specific stuff...
	 * Based on RFC1534 (Interoperation Between DHCP and BOOTP), any message
	 * received by a DHCP server that contains a 'DHCP_MESSAGETYPE' option
	 * is assumed to have been sent by a DHCP client.  A message without the
	 * DHCP_MESSAGETYPE option is assumed to have been sent by a BOOTP
	 * client.
	 */
	uh_ulen = optlen = 0;
	memset((char *)bootpdata->vsa,0,sizeof(bootpdata->vsa));
	uh_ulen = sizeof(struct Udphdr) + sizeof(struct bootphdr);
	tu->uh_ulen = ecs(uh_ulen);
	ti->ip_len = ecs((sizeof(struct ip) + uh_ulen));

	ipChksum(ti);	/* Compute checksum of ip hdr */
	udpChksum(ti);	/* Compute UDP checksum */

	DHCPState = BOOTPSTATE_REQUEST;
	sendBuffer(BOOTPSIZE);

	return(0);
}