Socket types

/**
 * enum sock_type - Socket types
 * @SOCK_STREAM: stream (connection) socket
 * @SOCK_DGRAM: datagram (conn.less) socket
 * @SOCK_RAW: raw socket
 * @SOCK_RDM: reliably-delivered message
 * @SOCK_SEQPACKET: sequential packet socket
 * @SOCK_DCCP: Datagram Congestion Control Protocol socket
 * @SOCK_PACKET: linux specific way of getting packets at the dev level.
 *  For writing rarp and other similar things on the user level.
 *
 * When adding some new socket type please
 * grep ARCH_HAS_SOCKET_TYPE include/asm-* /socket.h, at least MIPS
 * overrides this enum for binary compat reasons.
 */
enum sock_type {
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
SOCK_DCCP = 6,
SOCK_PACKET = 10,
};


#define SOCK_MAX (SOCK_PACKET + 1)
/* Mask which covers at least up to SOCK_MASK-1.  The
 * remaining bits are used as flags. */

#define SOCK_TYPE_MASK 0xf




/* This is used to register socket interfaces for IP protocols.  */
struct inet_protosw {
struct list_head list;


        /* These two fields form the lookup key.  */
unsigned short type;   /* This is the 2nd argument to socket(2). */
unsigned short protocol; /* This is the L4 protocol number.  */


struct proto *prot;
const struct proto_ops *ops;
  
unsigned char flags;      /* See INET_PROTOSW_* below.  */
};
#define INET_PROTOSW_REUSE 0x01     /* Are ports automatically reusable? */
#define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
#define INET_PROTOSW_ICSK      0x04  /* Is this an inet_connection_sock? */


void inet_register_protosw(struct inet_protosw *p)
{
struct list_head *lh;
struct inet_protosw *answer;
int protocol = p->protocol;
struct list_head *last_perm;


spin_lock_bh(&inetsw_lock);


if (p->type >= SOCK_MAX)
goto out_illegal;


/* If we are trying to override a permanent protocol, bail. */
last_perm = &inetsw[p->type];
list_for_each(lh, &inetsw[p->type]) {
answer = list_entry(lh, struct inet_protosw, list);
/* Check only the non-wild match. */
if ((INET_PROTOSW_PERMANENT & answer->flags) == 0)
break;
if (protocol == answer->protocol)
goto out_permanent;
last_perm = lh;
}


/* Add the new entry after the last permanent entry if any, so that
* the new entry does not override a permanent entry when matched with
* a wild-card protocol. But it is allowed to override any existing
* non-permanent entry.  This means that when we remove this entry, the
* system automatically returns to the old behavior.
*/
list_add_rcu(&p->list, last_perm);
out:
spin_unlock_bh(&inetsw_lock);


return;


out_permanent:
pr_err("Attempt to override permanent protocol %d\n", protocol);
goto out;


out_illegal:
pr_err("Ignoring attempt to register invalid socket type %d\n",
      p->type);
goto out;
}
EXPORT_SYMBOL(inet_register_protosw);


void inet_unregister_protosw(struct inet_protosw *p)
{
if (INET_PROTOSW_PERMANENT & p->flags) {
pr_err("Attempt to unregister permanent protocol %d\n",
      p->protocol);
} else {
spin_lock_bh(&inetsw_lock);
list_del_rcu(&p->list);
spin_unlock_bh(&inetsw_lock);


synchronize_net();
}
}
EXPORT_SYMBOL(inet_unregister_protosw);


static struct inet_protosw inetsw_array[] =
{
{
.type =       SOCK_STREAM,
.protocol =   IPPROTO_TCP,
.prot =       &tcp_prot,
.ops =        &inet_stream_ops,
.flags =      INET_PROTOSW_PERMANENT |
     INET_PROTOSW_ICSK,
},


{
.type =       SOCK_DGRAM,
.protocol =   IPPROTO_UDP,
.prot =       &udp_prot,
.ops =        &inet_dgram_ops,
.flags =      INET_PROTOSW_PERMANENT,
       },


       {
.type =       SOCK_DGRAM,
.protocol =   IPPROTO_ICMP,
.prot =       &ping_prot,
.ops =        &inet_dgram_ops,
.flags =      INET_PROTOSW_REUSE,
       },


       {
      .type =       SOCK_RAW,
      .protocol =   IPPROTO_IP, /* wild card */
      .prot =       &raw_prot,
      .ops =        &inet_sockraw_ops,
      .flags =      INET_PROTOSW_REUSE,
       }
};


#define INETSW_ARRAY_LEN ARRAY_SIZE(inetsw_array)


static struct inet_protosw sctp_seqpacket_protosw = {
.type       = SOCK_SEQPACKET,
.protocol   = IPPROTO_SCTP,
.prot       = &sctp_prot,
.ops        = &inet_seqpacket_ops,
.flags      = SCTP_PROTOSW_FLAG
};
static struct inet_protosw sctp_stream_protosw = {
.type       = SOCK_STREAM,
.protocol   = IPPROTO_SCTP,
.prot       = &sctp_prot,
.ops        = &inet_seqpacket_ops,
.flags      = SCTP_PROTOSW_FLAG
};




static struct inet_protosw udplite4_protosw = {
.type =  SOCK_DGRAM,
.protocol =  IPPROTO_UDPLITE,
.prot =  &udplite_prot,
.ops =  &inet_dgram_ops,
.flags =  INET_PROTOSW_PERMANENT,
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值