/* 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); }
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); }
/* 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); }