static void packet_close (volatile struct sock *sk, int timeout) { sk->inuse = 1; sk->state = TCP_CLOSE; dev_remove_pack ((struct packet_type *)sk->pair); free_s ((void *)sk->pair, sizeof (struct packet_type)); release_sock (sk); }
void sock_rfree (volatile struct sock *sk, void *mem, unsigned long size) { MPRINTK ("sock_rfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size); if (sk) { sk->rmem_alloc -= size; sfree(mem,size); if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) { delete_timer ((struct timer *)&sk->time_wait); free_s ((void *)sk, sizeof (*sk)); } } else { free_s (mem, size); } }
/* シート破棄関数 引数 対象シートへのポインタ */ void SHTCTL::del(SHEET *sheet) { _using.Lock(); _del(sheet) ; _using.Free(); free_s(sheet) ; return ; }
void sock_wfree (volatile struct sock *sk, void *mem, unsigned long size) { MPRINTK ("sock_wfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size); if (sk) { sk->wmem_alloc -= size; sfree(mem,size); /* in case it might be waiting for more memory. */ if (!sk->dead && sk->wmem_alloc > SK_WMEM_MAX/2) wake_up(sk->sleep); if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0) { MPRINTK ("recovered lost memory, destroying sock = %X\n",sk); delete_timer ((struct timer *)&sk->time_wait); free_s ((void *)sk, sizeof (*sk)); } } else { free_s (mem, size); } }
/* Since we are operating in binary mode, the return value from control * is irrelevant, as long as it is not negative. */ static int control(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen) { int r; char* s; s = get_s(buf, len); switch (command) { case DRV_CONNECT: r = do_connect(s, (our_data_t*)drv_data); break; case DRV_DISCONNECT: r = do_disconnect((our_data_t*)drv_data); break; case DRV_SELECT: r = do_select(s, (our_data_t*)drv_data); break; default: r = -1; break; } free_s(s); return r; }
void free_skb (struct sk_buff *skb, int rw) { if (skb->lock) { skb->free = 1; return; } if (skb->sk) { if (rw) { skb->sk->prot->rfree (skb->sk, skb->mem_addr, skb->mem_len); } else { skb->sk->prot->wfree (skb->sk, skb->mem_addr, skb->mem_len); } } else { free_s (skb->mem_addr, skb->mem_len); } }
int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt, unsigned long daddr, unsigned short len, unsigned long saddr, int redo, struct ip_protocol *protocol ) { int size, offset; struct icmp_header *icmph, *icmphr; struct sk_buff *skb; unsigned char *buff; /* drop broadcast packets. */ if ((daddr & 0xff000000) == 0 || (daddr & 0xff000000) == 0xff000000) { skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } buff = skb1->h.raw; icmph = (struct icmp_header *)buff; /* Validate the packet first */ if( icmph->checksum ) { /* Checksums Enabled? */ if( ip_compute_csum( (unsigned char *)icmph, len ) ) { /* Failed checksum! */ PRINTK("\nICMP ECHO failed checksum!"); skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } } print_icmph(icmph); /* Parse the ICMP message */ switch( icmph->type ) { case ICMP_DEST_UNREACH: case ICMP_SOURCE_QUENCH: { struct ip_header *iph; struct ip_protocol *ipprot; unsigned char hash; int err; err = icmph->type << 8 | icmph->code; /* we need to cause the socket to be closed and the error message to be set appropriately. */ iph = (struct ip_header *)(icmph+1); /* get the protocol(s) */ hash = iph->protocol & (MAX_IP_PROTOS -1 ); for (ipprot = ip_protos[hash]; ipprot != NULL; ipprot=ipprot->next) { /* pass it off to everyone who wants it. */ ipprot->err_handler (err, (unsigned char *)iph+4*iph->ihl, iph->daddr, iph->saddr, ipprot); } skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } case ICMP_REDIRECT: { /* we need to put a new route in the routing table. */ struct rtable *rt; /* we will add a new route. */ struct ip_header *iph; iph = (struct ip_header *)(icmph+1); rt = malloc (sizeof (*rt)); if (rt != NULL) { rt->net = iph->daddr; /* assume class C network. Technically this is incorrect, but will give it a try. */ if ((icmph->code & 1) == 0) rt->net &= 0x00ffffff; rt->dev = dev; rt->router = icmph->un.gateway; add_route (rt); } skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } case ICMP_ECHO: /* Allocate an sk_buff response buffer (assume 64 byte IP header) */ size = sizeof( struct sk_buff ) + dev->hard_header_len + 64 + len; skb = malloc( size ); if (skb == NULL) { skb1->sk = NULL; free_skb (skb1, FREE_READ); return (0); } skb->sk = NULL; skb->mem_addr = skb; skb->mem_len = size; /* Build Layer 2-3 headers for message back to source */ offset = ip_build_header( skb, daddr, saddr, &dev, IP_ICMP, opt, len ); if (offset < 0) { /* Problems building header */ PRINTK("\nCould not build IP Header for ICMP ECHO Response"); free_s (skb->mem_addr, skb->mem_len); skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); /* just toss the received packet */ } /* Readjust length according to actual IP header size */ skb->len = offset + len; /* Build ICMP_ECHO Response message */ icmphr = (struct icmp_header *)( (char *)( skb + 1 ) + offset ); memcpy( (char *)icmphr, (char *)icmph, len ); icmphr->type = ICMP_ECHOREPLY; icmphr->code = 0; icmphr->checksum = 0; if( icmph->checksum ) { /* Calculate Checksum */ icmphr->checksum = ip_compute_csum( (void *)icmphr, len ); } /* Ship it out - free it when done */ ip_queue_xmit( (volatile struct sock *)NULL, dev, skb, 1 ); skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); default: PRINTK("\nUnsupported ICMP type = x%x", icmph->type ); skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); /* just toss the packet */ } /* should be unecessary, but just in case. */ skb1->sk = NULL; free_skb (skb1, FREE_READ); return( 0 ); /* just toss the packet */ }
static int ip_proto_create (struct socket *sock, int protocol) { volatile struct sock *sk; struct proto *prot; int err; sk = malloc (sizeof (*sk)); if (sk == NULL) return (-ENOMEM); sk->num = 0; switch (sock->type) { case SOCK_STREAM: case SOCK_SEQPACKET: if (protocol && protocol != IP_TCP) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } sk->no_check = TCP_NO_CHECK; prot = &tcp_prot; break; case SOCK_DGRAM: if (protocol && protocol != IP_UDP) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } sk->no_check = UDP_NO_CHECK; prot=&udp_prot; break; case SOCK_RAW: if (!suser()) { free_s ((void *)sk, sizeof (*sk)); return (-EPERM); } if (!protocol) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } prot = &raw_prot; sk->reuse = 1; sk->no_check = 0; /* doesn't matter no checksum is preformed anyway. */ sk->num = protocol; break; case SOCK_PACKET: if (!suser()) { free_s ((void *)sk, sizeof (*sk)); return (-EPERM); } if (!protocol) { free_s ((void *)sk, sizeof (*sk)); return (-EPROTONOSUPPORT); } prot = &packet_prot; sk->reuse = 1; sk->no_check = 0; /* doesn't matter no checksum is preformed anyway. */ sk->num = protocol; break; default: free_s ((void *)sk, sizeof (*sk)); return (-ESOCKTNOSUPPORT); } sk->protocol = protocol; sk->wmem_alloc = 0; sk->rmem_alloc = 0; sk->pair = NULL; sk->opt = NULL; sk->send_seq = 0; sk->acked_seq = 0; sk->copied_seq = 0; sk->fin_seq = 0; sk->proc = 0; sk->rtt = TCP_WRITE_TIME; sk->packets_out = 0; sk->cong_window = 1; /* start with only sending one packet at a time. */ sk->exp_growth = 1; /* if set cong_window grow exponentially every time we get an ack. */ sk->urginline = 0; sk->intr = 0; sk->linger = 0; sk->destroy = 0; sk->reuse = 0; sk->priority = 1; sk->shutdown = 0; sk->urg = 0; sk->keepopen = 0; sk->done = 0; sk->ack_backlog = 0; sk->window = 0; sk->bytes_rcv = 0; sk->state = TCP_CLOSE; sk->dead = 0; sk->ack_timed = 0; /* this is how many unacked bytes we will accept for this socket. */ sk->max_unacked = 2048; /* needs to be at most 2 full packets. */ /* how many packets we should send before forcing an ack. if this is set to zero it is the same as sk->delay_acks = 0 */ sk->max_ack_backlog = MAX_ACK_BACKLOG; sk->inuse = 0; sk->delay_acks = 1; /* default to waiting a while before sending acks. */ sk->wback = NULL; sk->wfront = NULL; sk->rqueue = NULL; sk->mtu = 576; sk->prot = prot; sk->sleep = sock->wait; sk->daddr = 0; sk->saddr = MY_IP_ADDR; sk->err = 0; sk->next = NULL; sk->pair = NULL; sk->send_tail = NULL; sk->send_head = NULL; sk->time_wait.len = TCP_CONNECT_TIME; sk->time_wait.when = 0; sk->time_wait.sk = sk; sk->time_wait.next = NULL; sk->timeout = 0; sk->back_log = NULL; sk->blog = 0; sock->data =(void *) sk; sk->dummy_th.doff = sizeof (sk->dummy_th)/4; sk->dummy_th.res1=0; sk->dummy_th.res2=0; sk->dummy_th.urg_ptr = 0; sk->dummy_th.fin = 0; sk->dummy_th.syn = 0; sk->dummy_th.rst = 0; sk->dummy_th.psh = 0; sk->dummy_th.ack = 0; sk->dummy_th.urg = 0; sk->dummy_th.dest = 0; if (sk->num) { put_sock (sk->num, sk); } else { sk->num = get_new_socknum(sk->prot, 0); } /* make sure there was a free socket. */ if (sk->num == 0) { destroy_sock(sk); return (-EAGAIN); } put_sock(sk->num, sk); sk->dummy_th.source = net16(sk->num); if (sk->prot->init) { err = sk->prot->init(sk); if (err != 0) { destroy_sock (sk); return (err); } } return (0); }
void destroy_sock(volatile struct sock *sk) { struct sk_buff *skb; PRINTK ("destroying socket %X\n",sk); /* just to be safe. */ sk->inuse = 1; remove_sock (sk); /* now we can no longer get new packets. */ delete_timer((struct timer *)&sk->time_wait); /* cleanup up the write buffer. */ for (skb = sk->wfront; skb != NULL; ) { struct sk_buff *skb2; skb2=skb->next; free_skb(skb, FREE_WRITE); skb=skb2; } sk->wfront = NULL; if (sk->rqueue != NULL) { skb = sk->rqueue; do { struct sk_buff *skb2; skb2=skb->next; /* this will take care of closing sockets that were listening and didn't accept everything. */ if (skb->sk != NULL && skb->sk != sk) { skb->sk->dead = 1; skb->sk->prot->close (skb->sk, 0); } free_skb(skb, FREE_READ); skb=skb2; } while (skb != sk->rqueue); } sk->rqueue = NULL; /* now we need to clean up the send head. */ for (skb = sk->send_head; skb != NULL; ) { struct sk_buff *skb2; /* we need to remove skb from the transmit queue. */ cli(); /* see if it's in a transmit queue. */ if (skb->next != NULL) { if (skb->next != skb) { skb->next->prev = skb->prev; skb->prev->next = skb->next; } else { int i; for (i = 0; i < DEV_NUMBUFFS; i++) { if (skb->dev && skb->dev->buffs[i] == skb) { skb->dev->buffs[i]= NULL; break; } } } } sti(); skb2=skb->link3; free_skb(skb, FREE_WRITE); skb=skb2; } sk->send_head = NULL; /* and now the backlog. */ if (sk->back_log != NULL) { /* this should never happen. */ printk ("cleaning back_log. \n"); cli(); skb = sk->back_log; do { struct sk_buff *skb2; skb2=skb->next; free_skb(skb, FREE_READ); skb=skb2; } while (skb != sk->back_log); sti(); } sk->back_log = NULL; /* now if everything is gone we can free the socket structure, otherwise we need to keep it around until everything is gone. */ if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0) { free_s ((void *)sk,sizeof (*sk)); } else { /* this should never happen. */ /* actually it can if an ack has just been sent. */ PRINTK ("possible memory leak in socket = %X\n", sk); print_sk (sk); sk->destroy = 1; sk->ack_backlog = 0; sk->inuse = 0; sk->time_wait.len = SOCK_DESTROY_TIME; sk->timeout = TIME_DESTROY; reset_timer ((struct timer *)&sk->time_wait); } }
static void sfree(void *data, unsigned long len) { free_s(data,len); }
void sfree (void *data, unsigned long len) { int i; int sum; int csum; unsigned char *ptr; int bad = 0; struct mem *head, *tail; MPRINTK ("sfree(data=%X, len = %d)\n", data, len); head = data; head--; tail = (struct mem *)((unsigned char *)(head+1) + len); print_mem (head); print_mem (tail); if (head->other != tail) { MPRINTK ("sfree: head->other != tail:\n"); bad = 1; } if (tail->other != head) { MPRINTK ("sfree: tail->other != head:\n"); bad =1 ; } if (head ->len != len) { MPRINTK ("sfree: head->len != len"); bad = 1; } if (tail ->len != len) { MPRINTK ("sfree: tail->len != len"); bad = 1; } csum = head->check; ptr = (unsigned char *)head; head->check = 0; sum = 0; for (i = 0; i < sizeof (*head); i ++) { sum+= ptr[i]; } if (csum != ~sum) { MPRINTK ("sfree: head failed checksum\n"); bad = 1; } csum = tail->check; ptr = (unsigned char *)tail; tail->check = 0; sum = 0; for (i = 0; i < sizeof (*head); i ++) { sum+= ptr[i]; } if (csum != ~sum) { MPRINTK ("sfree: tail failed checksum\n"); bad = 1; } if (!bad) free_s (head, len+2*sizeof (*head)); else schedule(); }
static void arp_free (void *ptr, unsigned long len) { free_s(ptr, len); }