void dn_send_conn_conf(struct sock *sk, gfp_t gfp) { struct dn_scp *scp = DN_SK(sk); struct sk_buff *skb = NULL; struct nsp_conn_init_msg *msg; __u8 len = (__u8)le16_to_cpu(scp->conndata_out.opt_optl); if ((skb = dn_alloc_skb(sk, 50 + len, gfp)) == NULL) return; msg = (struct nsp_conn_init_msg *)skb_put(skb, sizeof(*msg)); msg->msgflg = 0x28; msg->dstaddr = scp->addrrem; msg->srcaddr = scp->addrloc; msg->services = scp->services_loc; msg->info = scp->info_loc; msg->segsize = cpu_to_le16(scp->segsize_loc); *skb_put(skb,1) = len; if (len > 0) memcpy(skb_put(skb, len), scp->conndata_out.opt_data, len); dn_nsp_send(skb); scp->persist = dn_nsp_persist(sk); scp->persist_fxn = dn_nsp_retrans_conn_conf; }
void dn_nsp_send_oth_ack(struct sock *sk) { struct sk_buff *skb = NULL; if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL) return; skb_reserve(skb, 9); dn_mk_ack_header(sk, skb, 0x14, 9, 1); dn_nsp_send(skb); }
/* * Wrapper for the above, for allocs of data skbs. We try and get the * whole size thats been asked for (plus 11 bytes of header). If this * fails, then we try for any size over 16 bytes for SOCK_STREAMS. */ struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err) { int space; int len; struct sk_buff *skb = NULL; *err = 0; while(skb == NULL) { if (signal_pending(current)) { *err = sock_intr_errno(timeo); break; } if (sk->sk_shutdown & SEND_SHUTDOWN) { *err = EINVAL; break; } if (sk->sk_err) break; len = *size + 11; space = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); if (space < len) { if ((sk->sk_socket->type == SOCK_STREAM) && (space >= (16 + 11))) len = space; } if (space < len) { set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); if (noblock) { *err = EWOULDBLOCK; break; } clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); SOCK_SLEEP_PRE(sk) if ((sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc)) < len) schedule(); SOCK_SLEEP_POST(sk) continue; } if ((skb = dn_alloc_skb(sk, len, sk->sk_allocation)) == NULL) continue; *size = len - 11; }
void dn_send_conn_ack (struct sock *sk) { struct dn_scp *scp = DN_SK(sk); struct sk_buff *skb = NULL; struct nsp_conn_ack_msg *msg; if ((skb = dn_alloc_skb(sk, 3, sk->sk_allocation)) == NULL) return; msg = (struct nsp_conn_ack_msg *)skb_put(skb, 3); msg->msgflg = 0x24; msg->dstaddr = scp->addrrem; dn_nsp_send(skb); }
static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, unsigned short reason, gfp_t gfp, struct dst_entry *dst, int ddl, unsigned char *dd, __le16 rem, __le16 loc) { struct sk_buff *skb = NULL; int size = 7 + ddl + ((msgflg == NSP_DISCINIT) ? 1 : 0); unsigned char *msg; if ((dst == NULL) || (rem == 0)) { if (net_ratelimit()) printk(KERN_DEBUG "DECnet: dn_nsp_do_disc: BUG! Please report this to [email protected] rem=%u dst=%p\n", le16_to_cpu(rem), dst); return; } if ((skb = dn_alloc_skb(sk, size, gfp)) == NULL) return; msg = skb_put(skb, size); *msg++ = msgflg; *(__le16 *)msg = rem; msg += 2; *(__le16 *)msg = loc; msg += 2; *(__le16 *)msg = cpu_to_le16(reason); msg += 2; if (msgflg == NSP_DISCINIT) *msg++ = ddl; if (ddl) { memcpy(msg, dd, ddl); } /* * This doesn't go via the dn_nsp_send() function since we need * to be able to send disc packets out which have no socket * associations. */ skb_dst_set(skb, dst_clone(dst)); dst_output(skb); }
void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval) { struct dn_scp *scp = DN_SK(sk); struct sk_buff *skb; unsigned char *ptr; gfp_t gfp = GFP_ATOMIC; if ((skb = dn_alloc_skb(sk, DN_MAX_NSP_DATA_HEADER + 2, gfp)) == NULL) return; skb_reserve(skb, DN_MAX_NSP_DATA_HEADER); ptr = skb_put(skb, 2); DN_SKB_CB(skb)->nsp_flags = 0x10; *ptr++ = lsflags; *ptr = fcval; dn_nsp_queue_xmit(sk, skb, gfp, 1); scp->persist = dn_nsp_persist(sk); scp->persist_fxn = dn_nsp_xmit_timeout; }
void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg) { struct dn_scp *scp = DN_SK(sk); struct nsp_conn_init_msg *msg; unsigned char aux; unsigned char menuver; struct dn_skb_cb *cb; unsigned char type = 1; gfp_t allocation = (msgflg == NSP_CI) ? sk->sk_allocation : GFP_ATOMIC; struct sk_buff *skb = dn_alloc_skb(sk, 200, allocation); if (!skb) return; cb = DN_SKB_CB(skb); msg = (struct nsp_conn_init_msg *)skb_put(skb,sizeof(*msg)); msg->msgflg = msgflg; msg->dstaddr = 0x0000; /* Remote Node will assign it*/ msg->srcaddr = scp->addrloc; msg->services = scp->services_loc; /* Requested flow control */ msg->info = scp->info_loc; /* Version Number */ msg->segsize = cpu_to_le16(scp->segsize_loc); /* Max segment size */ if (scp->peer.sdn_objnum) type = 0; skb_put(skb, dn_sockaddr2username(&scp->peer, skb_tail_pointer(skb), type)); skb_put(skb, dn_sockaddr2username(&scp->addr, skb_tail_pointer(skb), 2)); menuver = DN_MENUVER_ACC | DN_MENUVER_USR; if (scp->peer.sdn_flags & SDF_PROXY) menuver |= DN_MENUVER_PRX; if (scp->peer.sdn_flags & SDF_UICPROXY) menuver |= DN_MENUVER_UIC; *skb_put(skb, 1) = menuver; /* Menu Version */ aux = scp->accessdata.acc_userl; *skb_put(skb, 1) = aux; if (aux > 0) memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux); aux = scp->accessdata.acc_passl; *skb_put(skb, 1) = aux; if (aux > 0) memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux); aux = scp->accessdata.acc_accl; *skb_put(skb, 1) = aux; if (aux > 0) memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux); aux = (__u8)le16_to_cpu(scp->conndata_out.opt_optl); *skb_put(skb, 1) = aux; if (aux > 0) memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux); scp->persist = dn_nsp_persist(sk); scp->persist_fxn = dn_nsp_retrans_conninit; cb->rt_flags = DN_RT_F_RQR; dn_nsp_send(skb); }