int ethernet_open (struct device *dev) { error_t err; device_t master_device; struct ether_device *edev = (struct ether_device *) dev->priv; assert (edev->ether_port == MACH_PORT_NULL); err = ports_create_port (etherreadclass, etherport_bucket, sizeof (struct port_info), &edev->readpt); assert_perror (err); edev->readptname = ports_get_right (edev->readpt); mach_port_insert_right (mach_task_self (), edev->readptname, edev->readptname, MACH_MSG_TYPE_MAKE_SEND); mach_port_set_qlimit (mach_task_self (), edev->readptname, MACH_PORT_QLIMIT_MAX); master_device = file_name_lookup (dev->name, O_READ | O_WRITE, 0); if (master_device != MACH_PORT_NULL) { /* The device name here is the path of a device file. */ err = device_open (master_device, D_WRITE | D_READ, "eth", &edev->ether_port); mach_port_deallocate (mach_task_self (), master_device); if (err) error (2, err, "device_open on %s", dev->name); err = device_set_filter (edev->ether_port, ports_get_right (edev->readpt), MACH_MSG_TYPE_MAKE_SEND, 0, bpf_ether_filter, bpf_ether_filter_len); if (err) error (2, err, "device_set_filter on %s", dev->name); } else { /* No, perhaps a Mach device? */ int file_errno = errno; err = get_privileged_ports (0, &master_device); if (err) { error (0, file_errno, "file_name_lookup %s", dev->name); error (2, err, "and cannot get device master port"); } err = device_open (master_device, D_WRITE | D_READ, dev->name, &edev->ether_port); mach_port_deallocate (mach_task_self (), master_device); if (err) { error (0, file_errno, "file_name_lookup %s", dev->name); error (2, err, "device_open(%s)", dev->name); } err = device_set_filter (edev->ether_port, ports_get_right (edev->readpt), MACH_MSG_TYPE_MAKE_SEND, 0, ether_filter, ether_filter_len); if (err) error (2, err, "device_set_filter on %s", dev->name); } return 0; }
int ethernet_open (char *dev_name, device_t master_device, struct port_bucket *etherport_bucket, struct port_class *etherreadclass) { error_t err; assert (ether_port == MACH_PORT_NULL); err = ports_create_port (etherreadclass, etherport_bucket, sizeof (struct port_info), &readpt); if (err) error (2, err, "ports_create_port"); readptname = ports_get_right (readpt); mach_port_insert_right (mach_task_self (), readptname, readptname, MACH_MSG_TYPE_MAKE_SEND); mach_port_set_qlimit (mach_task_self (), readptname, MACH_PORT_QLIMIT_MAX); err = device_open (master_device, D_WRITE | D_READ, "eth", ðer_port); mach_port_deallocate (mach_task_self (), master_device); if (err) error (2, err, "device_open: %s", dev_name); err = device_set_filter (ether_port, ports_get_right (readpt), MACH_MSG_TYPE_MAKE_SEND, 0, (unsigned short *)ether_filter, ether_filter_len); if (err) error (2, err, "device_set_filter: %s", dev_name); set_promisc (dev_name, ether_port, 1); return 0; }
int tgdb_connect(void) { kern_return_t rc; filter_t filter[NET_MAX_FILTER]; filter_t *pf; mach_port_t port_set; if((rc = device_open(device_server_port, MACH_PORT_NULL, D_READ|D_WRITE, security_token, (char *) "lan", &if_port)) != D_SUCCESS) { printf("tgdb: device_open failed %x\n", rc); return 0; } pf = filter; /* * Deal unly with IP packets. */ *pf++ = NETF_PUSHHDR+6; *pf++ = NETF_PUSHLIT|NETF_CAND; *pf++ = htons(ETHERTYPE_IP); /* * Check that this is a UDP packet on the tgdb port. */ *pf++ = NETF_PUSHWORD+11; *pf++ = NETF_PUSHLIT|NETF_EQ; *pf++ = htons(GDB_PORT); if((rc = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &port_set)) != KERN_SUCCESS) { printf("mach_port_allocate : failed %x\n", rc); return 0; } if(ether_setup_port(&tgdb_reply_port, port_set)) printf("ether_setup_port failed\n"); if((rc = device_set_filter(if_port, tgdb_reply_port, MACH_MSG_TYPE_MAKE_SEND, 101, filter, pf - filter)) != D_SUCCESS) { printf("tgdb: device_set_filter returned %x\n", rc); return 0; } printf("remote task debugger started\n"); while(1) { net_rcv_msg_t msg; gdb_request_t request = &tgdb_request_buffer; unsigned int request_size; gdb_response_t response = &tgdb_response_buffer; struct netipc_ether_header *ehp; struct netipc_udpip_header *uhp; tgdb_session_t session; msg = (net_rcv_msg_t)buf; rc = mach_msg(&msg->msg_hdr, MACH_RCV_MSG, 0, 8192, port_set, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (rc != MACH_MSG_SUCCESS) printf("get packet: kr returned %x\n", rc); ehp = (void *) &msg->header; uhp = (void *) (&msg->packet[0] + sizeof (int)); if (ntohs(uhp->udp_dest_port) != GDB_PORT) { printf("WARNING NOT A GDB PORT\n"); continue; } if (ntohs(uhp->ip_protocol) != UDP_PROTOCOL) { printf("WARNING NOT A UDP PACKET!\n"); continue; } /* * Copy packet to incoming buffer */ request_size = ntohs(uhp->udp_length) - 8; bcopy((&msg->packet[0] + sizeof(struct netipc_udpip_header) + sizeof(int)) ,(char *) &tgdb_request_buffer, request_size); if (ntohl(request->task_id) == 0) { /* * This request should have gone to the microkernel * debugger stub. */ printf("tgdb got a request for kernel!\n"); continue; } /* * If this is just a request for status, drop it unless our * status has changed, i.e., we've taken a breakpoint or something. */ if (ntohl(request->request) == 'w' && (session = tgdb_lookup_task_id((int)ntohl(request->task_id), 0)) && !session->task_suspended) { continue; } /* * Save all the address stuff for the response */ bcopy((char *) ehp->e_src, (char *) tgdb_foreign_addr.ether, 6); bcopy((char *) ehp->e_dest, (char *) tgdb_local_addr.ether, 6); bcopy((char *) &uhp->ip_src, (char *) tgdb_foreign_addr.ip, 4); bcopy((char *) &uhp->ip_dst, (char *) tgdb_local_addr.ip, 4); bcopy((char *) &uhp->udp_source_port, (char *) tgdb_foreign_addr.port, 2); bcopy((char *) &uhp->udp_dest_port, (char *) tgdb_local_addr.port, 2); tgdb_request(request, response); } }