bool arp_busy_status(void) { uint8_t status; bool busy; status = MEMORY_READ(8, ARP(STATUS)); status &= 0x01; /* Busy? */ busy = (status == 0x00); return busy; }
char * arp_version(void) { const char *arp_ver; char *buf; size_t ver_len; arp_ver = (const char *)ARP(VERSION); ver_len = 255; if ((buf = (char *)malloc(ver_len + 1)) == NULL) return NULL; memcpy(buf, arp_ver, ver_len); buf[ver_len] = '\0'; return buf; }
/* Retarget a stack that's already been build to a different * destination address, "daddr". "laddr" is supplied for convenience */ static bool_t retarget(struct udp_data *ud, struct sockaddr_in *laddr, struct sockaddr_in *daddr) { uint32_t NOCLOBBER arpaddr; FlowMan_RouteInfo * NOCLOBBER ri = NULL; FlowMan_SAP rsap; Net_IPHostAddr ipaddr; Net_EtherAddr hwaddr; /* route the new dest addr, and make sure we don't need to change * interface */ rsap.tag = FlowMan_PT_UDP; rsap.u.UDP.addr.a = daddr->sin_addr.s_addr; rsap.u.UDP.port = daddr->sin_port; TRY { ri = FlowMan$ActiveRoute(ud->fman, &rsap); } CATCH_FlowMan$NoRoute() { ri = NULL; } ENDTRY; if (!ri) { printf("retarget: no route to host %x\n", ntohl(daddr->sin_addr.s_addr)); return False; } if (strcmp(ri->ifname, ud->curif)) { printf("retarget: route to %x requires going through %s, but stack " "is built to %s\n", ntohl(daddr->sin_addr.s_addr), ri->ifname, ud->curif); free(ri->ifname); free(ri->type); free(ri); return False; } if (ri->gateway) arpaddr = ri->gateway; else arpaddr = daddr->sin_addr.s_addr; TRC(eprintf("retarget: ARPing for %I\n", arpaddr)); { bool_t NOCLOBBER ok = True; TRY { FlowMan$ARP(ud->fman, arpaddr, &hwaddr); } CATCH_Context$NotFound(UNUSED name) { ok = False; } ENDTRY; if(!ok) return False; } TRC(eprintf("Retargeted remote hwaddr: %02x:%02x:%02x:%02x:%02x:%02x%s\n", hwaddr.a[0], hwaddr.a[1], hwaddr.a[2], hwaddr.a[3], hwaddr.a[4], hwaddr.a[5], (ri->gateway)?" (using gateway)":"")); free(ri->ifname); free(ri); Ether$SetDest(ud->eth, &hwaddr); ipaddr.a = daddr->sin_addr.s_addr; IP$SetDest(ud->ip, &ipaddr); UDP$SetTXPort(ud->udp, daddr->sin_port); return True; }