Esempio n. 1
0
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;
}
Esempio n. 2
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", &ether_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;
}
Esempio n. 3
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);
	}
}