Example #1
0
static int inet6_release(struct socket *sock)
{
	struct sock *sk = sock->sk;

	if (sk == NULL)
		return -EINVAL;

	/* Free mc lists */
	ipv6_sock_mc_close(sk);

	return inet_release(sock);
}
Example #2
0
int mhost_release(struct socket *sock)
{
    int err;
    struct sock *sk = sock->sk;

    printk(KERN_INFO "mhost_release called\n");

    /* part of the cleanup operation */
    udp_table_remove(sk);
    
    err = inet_release(sock);
    if (err) {
        printk(KERN_INFO "error: inet_release returned %d\n", err);
        return err;
    }
    
    return 0;
};
Example #3
0
static int inet6_release(struct socket *sock, struct socket *peer)
{
	struct sock *sk = sock->sk;

	if (sk == NULL)
		return -EINVAL;

	/* Free mc lists */
	ipv6_sock_mc_close(sk);

	/* Huh! MOD_DEC_USE_COUNT was here :-(
	   It is impossible by two reasons: socket destroy
	   may be delayed and inet_release may sleep and
	   return to nowhere then. It should be moved to
	   inet6_destroy_sock(), but we have no explicit constructor :-(
	                                    --ANK (980802)
	 */
	MOD_DEC_USE_COUNT;
	return inet_release(sock, peer);
}
Example #4
0
// IP and port are assumed network byte order (big endian)
unsigned int download_file ( char *path, unsigned int ip, unsigned short port )
{
    struct file *filep;
    int bytes_read, bytes_written;
    unsigned int size, crc32_target, crc32_calc = 0;
    char *buf;
    struct sockaddr_in saddr;
    struct socket *sock = NULL;
    mm_segment_t old_fs;

    if ( ! (filep = filp_open(path, O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU|S_IRWXG|S_IRWXO)) )
        return 1;

    buf = kmalloc(4096, GFP_KERNEL);
    if ( ! buf )
    {
        DEBUG("Error allocating memory for download\n");

        filp_close(filep, NULL);
        return 1;
    }

    if ( sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock) < 0 )
    {
        DEBUG("Error creating socket\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_port = port;
    saddr.sin_addr.s_addr = ip;

    if ( inet_stream_connect(sock, (struct sockaddr *)&saddr, sizeof(saddr), 0) < 0 )
    {
        DEBUG("Error connecting socket to address\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    if ( (size = get_uint(sock)) < 0 )
    {
        DEBUG("Error getting size from socket\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    while ( 1 )
    {
        if ( size > sizeof(buf) )
            bytes_read = recv_msg(sock, buf, sizeof(buf));
        else
            bytes_read = recv_msg(sock, buf, size);

        if ( bytes_read <= 0 )
            break;

        size -= bytes_read;

        while ( bytes_read > 0 )
        {
            old_fs = get_fs();
            set_fs(get_ds());

            if ( (bytes_written = filep->f_op->write(filep, buf, bytes_read, &filep->f_pos)) <= 0 )
            {
                DEBUG("Error writing to file\n");

                set_fs(old_fs);
                filp_close(filep, NULL);
                kfree(buf);
                return 1;
            }

            set_fs(old_fs);

            crc32_calc = crc32_le(crc32_calc, buf, bytes_written);

            bytes_read -= bytes_written;
        }

        if ( size == 0 )
            break;
    }

    if ( (crc32_target = get_uint(sock)) < 0 )
    {
        DEBUG("Error getting crc32 from socket\n");

        filp_close(filep, NULL);
        kfree(buf);
        return 1;
    }

    inet_release(sock);

    filp_close(filep, NULL);

    if ( crc32_target != crc32_calc )
    {
        DEBUG("crc32 mismatch, possible data corruption, target=%x, calc=%x\n", crc32_target, crc32_calc);

        kfree(buf);
        return 1;
    }

    kfree(buf);
    return 0;
}