コード例 #1
0
ファイル: core-cdev.c プロジェクト: mikeberkelaar/grhardened
static void complete_transaction(struct fw_card *card, int rcode,
				 void *payload, size_t length, void *data)
{
	struct outbound_transaction_event *e = data;
	struct fw_cdev_event_response *rsp = &e->response;
	struct client *client = e->client;
	unsigned long flags;

	if (length < rsp->length)
		rsp->length = length;
	if (rcode == RCODE_COMPLETE)
		memcpy(rsp->data, payload, rsp->length);

	spin_lock_irqsave(&client->lock, flags);
	/*
	 * 1. If called while in shutdown, the idr tree must be left untouched.
	 *    The idr handle will be removed and the client reference will be
	 *    dropped later.
	 * 2. If the call chain was release_client_resource ->
	 *    release_transaction -> complete_transaction (instead of a normal
	 *    conclusion of the transaction), i.e. if this resource was already
	 *    unregistered from the idr, the client reference will be dropped
	 *    by release_client_resource and we must not drop it here.
	 */
	if (!client->in_shutdown &&
	    idr_find(&client->resource_idr, e->r.resource.handle)) {
		idr_remove(&client->resource_idr, e->r.resource.handle);
		/* Drop the idr's reference */
		client_put(client);
	}
	spin_unlock_irqrestore(&client->lock, flags);

	rsp->type = FW_CDEV_EVENT_RESPONSE;
	rsp->rcode = rcode;

	/*
	 * In the case that sizeof(*rsp) doesn't align with the position of the
	 * data, and the read is short, preserve an extra copy of the data
	 * to stay compatible with a pre-2.6.27 bug.  Since the bug is harmless
	 * for short reads and some apps depended on it, this is both safe
	 * and prudent for compatibility.
	 */
	if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data))
		queue_event(client, &e->event, rsp, sizeof(*rsp),
			    rsp->data, rsp->length);
	else
		queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length,
			    NULL, 0);

	/* Drop the transaction callback's reference */
	client_put(client);
}
コード例 #2
0
ファイル: core-cdev.c プロジェクト: mikeberkelaar/grhardened
static int release_client_resource(struct client *client, u32 handle,
				   client_resource_release_fn_t release,
				   struct client_resource **resource)
{
	struct client_resource *r;

	spin_lock_irq(&client->lock);
	if (client->in_shutdown)
		r = NULL;
	else
		r = idr_find(&client->resource_idr, handle);
	if (r && r->release == release)
		idr_remove(&client->resource_idr, handle);
	spin_unlock_irq(&client->lock);

	if (!(r && r->release == release))
		return -EINVAL;

	if (resource)
		*resource = r;
	else
		r->release(client, r);

	client_put(client);

	return 0;
}
コード例 #3
0
ファイル: core-cdev.c プロジェクト: mikeberkelaar/grhardened
static int fw_device_op_release(struct inode *inode, struct file *file)
{
	struct client *client = file->private_data;
	struct event *e, *next_e;

	mutex_lock(&client->device->client_list_mutex);
	list_del(&client->link);
	mutex_unlock(&client->device->client_list_mutex);

	if (client->iso_context)
		fw_iso_context_destroy(client->iso_context);

	if (client->buffer.pages)
		fw_iso_buffer_destroy(&client->buffer, client->device->card);

	/* Freeze client->resource_idr and client->event_list */
	spin_lock_irq(&client->lock);
	client->in_shutdown = true;
	spin_unlock_irq(&client->lock);

	idr_for_each(&client->resource_idr, shutdown_resource, client);
	idr_remove_all(&client->resource_idr);
	idr_destroy(&client->resource_idr);

	list_for_each_entry_safe(e, next_e, &client->event_list, link)
		kfree(e);

	client_put(client);

	return 0;
}
コード例 #4
0
ファイル: core-cdev.c プロジェクト: mikeberkelaar/grhardened
static int shutdown_resource(int id, void *p, void *data)
{
	struct client_resource *r = p;
	struct client *client = data;

	r->release(client, r);
	client_put(client);

	return 0;
}
コード例 #5
0
int main(int argc, char *argv[])
{
  int confd;
  struct sockaddr_in server_addr;

  if(argc < 5)
  {
    printf("input format is :\nput [-h hostname] [-p portname] local_filename remote_filename\nget [-h hostname] [-p portname] remote_filename local_filename\n");
    exit(1);
  }
  if(!strcmp(argv[1],"put"))//输出提示。
   printf("%s hostname:%s,portname:%s,local_filename:%s,remote_filename:%s\n",argv[1],argv[2],argv[3],argv[4],argv[5]);
 else
   printf("%s hostname:%s,portname:%s,local_filename:%s,remote_filename:%s\n",argv[1],argv[2],argv[3],argv[5],argv[4]);


  server_addr.sin_family = PF_INET;//PF_INET(协议族)
  server_addr.sin_addr.s_addr = inet_addr(argv[2]);//主机字节顺序转换成网络字节顺序
  server_addr.sin_port = htons(atoi(argv[3]));//该函数把一个用数字和点表示的IP地址的字符串转换成一个无符号长整型
  bzero(&server_addr.sin_zero,8);  //sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节
 
  if ((confd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
  {
    perror("socket fail\n");
    exit(1);
  }


  if (connect(confd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
  {
    perror("connect fail");
    exit(1);
  }

  if (!strcmp(argv[1], "put"))
  {
   client_put(confd,argv[4],argv[5]);
  }
  else if (!strcmp(argv[1], "get"))
  {
   client_get(confd,argv[5],argv[4]);
  }
  else
  {
    printf("input format error\n");
  }

  close(confd);//关闭连接

  return 0;

}
コード例 #6
0
ファイル: client.c プロジェクト: raviteja-ksva/tftp-client
int main (int argc, char **argv)
{
	int sock, len2, len;
	char opcode, filename[196], mode[12] = "octet"; // default is octet
	struct hostent *host;
	struct sockaddr_in server;
	char* host_addr = "127.0.0.1";
	FILE *fp;

	if (argc < 2)
	{
		printf("invalid format of command\n");
		printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
		return 0;
	}

	argv++;
	argc--;

	if (strcmp(argv[0], "-h") == 0)
	{
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		host_addr = argv[1];
		argv+=2;
		argc-=2;
	}
	if (strcmp(argv[0], "-P")==0){
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		port = atoi(argv[1]);

		argv+=2;
		argc-=2;
	}
	if (strcmp(argv[0], "-g")==0){
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		strncpy (filename, argv[1], sizeof (filename) - 1);
		opcode = RRQ;
		argv+=2;
		argc-=2;
	} else if (strcmp(argv[0], "-p")==0){
		if (argc==1) 
		{
			printf("invalid format of command\n");
			printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
			return 0;
		}
		strncpy (filename, argv[1], sizeof (filename) - 1);
		opcode = WRQ;
		argv+=2;
		argc-=2;
	} else if (strcmp(argv[0], "-n")==0){
		strncpy (mode, "netascii", sizeof (mode) - 1);
		printf ("Client: The mode is set to netascii\n");
	} else{
		printf("Command format: ./client -h [host_addr] -P [port] -g|-p [filename] [-n] \n");
		return (0);
	}

	printf("Client: server ip address: %s and port: %d \n", host_addr, port);
	if (!(host = gethostbyname (host_addr)))
	{
		perror ("could not obtain host address as");
		exit (2);
	}

	printf("Client: Opening file: %s in %s mode \n", filename, (opcode == WRQ ? "Read": "Write") );
	if(opcode == WRQ)
		fp = fopen (filename, "r");	
	else if(opcode == RRQ)
		fp = fopen (filename, "w");		
	if (fp == NULL)
	{
		printf ("Client: file could not be opened: file not found or permission denied\n");
		return 0;
	}
	fclose (fp);		


	/*Create the socket, a -1 will show us an error */
	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
	{
		perror("Client: socket");
		return 0;
	}

	 // bind to an arbitrary return address 
	 // because this is the client side, we don't care about the 
	 // address since no application will connect here  
	 // INADDR_ANY is the IP address and 0 is the socket 
	 // htonl converts a long integer (e.g. address) to a network 
	 // representation (agreed-upon byte ordering 

	bzero(&server, sizeof (server));
	server.sin_family = AF_INET;
	memcpy (&server.sin_addr, host->h_addr, host->h_length);
	// server.sin_addr.s_addr = htonl (INADDR_ANY);
	server.sin_port = htons (port);	


	len2 = sizeof(server);
	memset(buf, 0, 512);
	// creates RRQ packet
	len = request_packet(opcode, filename, mode, buf);
	if (sendto (sock, buf, len, 0, (struct sockaddr *) &server, len2) != len)
	{
		perror("Client: sendto has returend an error");
		exit(-1);
	}
	printf("Client: %s packet sent\n", (opcode==1 ? "RRQ":"WRQ"));
	switch (opcode)
	{
		case RRQ:
			client_get(filename, server, mode, sock);
			break;
		case WRQ:
			client_put(filename, server, mode, sock);
			break;
		default:
			printf("Invalid opcode. Packet discarded.");
	}
	close(sock);
	return 1;
}
コード例 #7
0
ファイル: core-cdev.c プロジェクト: mikeberkelaar/grhardened
static void schedule_iso_resource(struct iso_resource *r)
{
	client_get(r->client);
	if (!schedule_delayed_work(&r->work, 0))
		client_put(r->client);
}
コード例 #8
0
ファイル: core-cdev.c プロジェクト: mikeberkelaar/grhardened
static void iso_resource_work(struct work_struct *work)
{
	struct iso_resource_event *e;
	struct iso_resource *r =
			container_of(work, struct iso_resource, work.work);
	struct client *client = r->client;
	int generation, channel, bandwidth, todo;
	bool skip, free, success;

	spin_lock_irq(&client->lock);
	generation = client->device->generation;
	todo = r->todo;
	/* Allow 1000ms grace period for other reallocations. */
	if (todo == ISO_RES_ALLOC &&
	    time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
		if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3)))
			client_get(client);
		skip = true;
	} else {
		/* We could be called twice within the same generation. */
		skip = todo == ISO_RES_REALLOC &&
		       r->generation == generation;
	}
	free = todo == ISO_RES_DEALLOC ||
	       todo == ISO_RES_ALLOC_ONCE ||
	       todo == ISO_RES_DEALLOC_ONCE;
	r->generation = generation;
	spin_unlock_irq(&client->lock);

	if (skip)
		goto out;

	bandwidth = r->bandwidth;

	fw_iso_resource_manage(client->device->card, generation,
			r->channels, &channel, &bandwidth,
			todo == ISO_RES_ALLOC ||
			todo == ISO_RES_REALLOC ||
			todo == ISO_RES_ALLOC_ONCE,
			r->transaction_data);
	/*
	 * Is this generation outdated already?  As long as this resource sticks
	 * in the idr, it will be scheduled again for a newer generation or at
	 * shutdown.
	 */
	if (channel == -EAGAIN &&
	    (todo == ISO_RES_ALLOC || todo == ISO_RES_REALLOC))
		goto out;

	success = channel >= 0 || bandwidth > 0;

	spin_lock_irq(&client->lock);
	/*
	 * Transit from allocation to reallocation, except if the client
	 * requested deallocation in the meantime.
	 */
	if (r->todo == ISO_RES_ALLOC)
		r->todo = ISO_RES_REALLOC;
	/*
	 * Allocation or reallocation failure?  Pull this resource out of the
	 * idr and prepare for deletion, unless the client is shutting down.
	 */
	if (r->todo == ISO_RES_REALLOC && !success &&
	    !client->in_shutdown &&
	    idr_find(&client->resource_idr, r->resource.handle)) {
		idr_remove(&client->resource_idr, r->resource.handle);
		client_put(client);
		free = true;
	}
	spin_unlock_irq(&client->lock);

	if (todo == ISO_RES_ALLOC && channel >= 0)
		r->channels = 1ULL << channel;

	if (todo == ISO_RES_REALLOC && success)
		goto out;

	if (todo == ISO_RES_ALLOC || todo == ISO_RES_ALLOC_ONCE) {
		e = r->e_alloc;
		r->e_alloc = NULL;
	} else {
		e = r->e_dealloc;
		r->e_dealloc = NULL;
	}
	e->resource.handle	= r->resource.handle;
	e->resource.channel	= channel;
	e->resource.bandwidth	= bandwidth;

	queue_event(client, &e->event,
		    &e->resource, sizeof(e->resource), NULL, 0);

	if (free) {
		cancel_delayed_work(&r->work);
		kfree(r->e_alloc);
		kfree(r->e_dealloc);
		kfree(r);
	}
 out:
	client_put(client);
}