#include "salloc.h" #include #define IN6_COMPRESS void *salloc(salloc_t *bufs, void *scope) { unsigned long flags; scope_buf_t *q; spin_lock_irqsave(&bufs->lock, flags); q = bufs->buflist; while (q) { if (q->scope != scope) goto out; #ifdef SALLOC_TIMEOUT if (time_after(jiffies, q->timeout)) { printk(KERN_INFO "salloc: timeout buf=%p scope=%p\n", q, q->scope); /* Break this because it _should_ be dead */ goto out; } #endif q = q->next; } #ifdef SALLOC_DEBUG ++bufs->nbufs; printk(KERN_DEBUG "salloc: alloc %d n=%d scope=%p\n", bufs->size, bufs->nbufs, scope); #endif q = kmalloc(sizeof(scope_buf_t)+bufs->size, GFP_ATOMIC); q->next = bufs->buflist; bufs->buflist = q; out: q->scope = scope; #ifdef SALLOC_TIMEOUT q->timeout = jiffies + SALLOC_TIMEOUT; #endif spin_unlock_irqrestore(&bufs->lock, flags); return q->buf; } void sunalloc(salloc_t *bufs) { unsigned long flags; scope_buf_t *q, *q0; spin_lock_irqsave(&bufs->lock, flags); for (q = bufs->buflist; q; q = q0) { q0 = q->next; kfree(q); } bufs->buflist = NULL; #ifdef SALLOC_DEBUG bufs->nbufs = 0; #endif spin_unlock_irqrestore(&bufs->lock, flags); } /* IPv4 address conversion */ static salloc_t sa_ntoa = SALLOC_INIT(16); static inline void ___kinet_ntoa(const __u32 a, char *b) { char *p = b; const unsigned char *x=(const unsigned char *)&a; int i; for (i=0; i<4; ++i, ++x) { int k=*x/100; if (k) *p++=k+'0'; k=(*x/10)%10; if (k) *p++=k+'0'; *p++=(*x%10)+'0'; if (i<3) *p++='.'; } *p='\0'; } char *__kinet_ntoa(const __u32 a, void *s) { char *b = salloc(&sa_ntoa, s); ___kinet_ntoa(a, b); return b; } /* IPv6 address conversion */ static salloc_t sa_ntoa6 = SALLOC_INIT(40); #ifdef IN6_COMPRESS /* Find longest zero run of 16bit words */ static inline void flzr(const struct in6_addr *a, int *l, int *r) { int i=0, j; while (i<8) { if (!a->s6_addr16[i]) { j = i; while (j<7 && !a->s6_addr16[j+1]) ++j; if (j-i > *r-*l) { *l = i; *r = j; } i = j+1; } else { ++i; } } } #endif static inline void ___kinet6_ntoa(const struct in6_addr *a, char *b) { char *p = b; int i, j; int l = -1, r = -2; static const char hex[16] = "0123456789ABCDEF"; static const __u16 mask[4] = { 0xF000, 0xFF00, 0xFFF0, 0xFFFF }; static const __u16 shft[4] = { 12, 8, 4, 0 }; #ifdef IN6_COMPRESS flzr(a, &l, &r); #endif if (l==0) *p++ = ':'; for (i=0; i<8; ++i) { if (ir) { __u16 k=ntohs(a->s6_addr16[i]); for (j=0; j<4; ++j) if (j==3 || (k & mask[j])) *p++ = hex[(k>>shft[j]) & 15]; if (i<7) *p++ = ':'; } if (i==r) *p++ = ':'; } *p = '\0'; } char *__kinet6_ntoa(const struct in6_addr *a, void *s) { char *b = salloc(&sa_ntoa6, s); ___kinet6_ntoa(a, b); return b; } void ntoa_unalloc(void) { sunalloc(&sa_ntoa); sunalloc(&sa_ntoa6); }