1 /* $OpenBSD: util.c,v 1.2 2010/09/25 16:20:06 sobrado Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 #include <sys/types.h> 19 #include <sys/queue.h> 20 #include <sys/socket.h> 21 #include <sys/uio.h> 22 23 #include <scsi/iscsi.h> 24 25 #include <errno.h> 26 #include <event.h> 27 #include <fcntl.h> 28 #include <netdb.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <strings.h> 32 #include <unistd.h> 33 34 #include "iscsid.h" 35 #include "log.h" 36 37 struct pdu * 38 pdu_new(void) 39 { 40 struct pdu *p; 41 42 if (!(p = calloc(1, sizeof(*p)))) 43 return NULL; 44 return p; 45 } 46 47 void * 48 pdu_alloc(size_t len) 49 { 50 return malloc(PDU_LEN(len)); 51 } 52 53 void * 54 pdu_dup(void *data, size_t len) 55 { 56 void *p; 57 58 if ((p = malloc(PDU_LEN(len)))) 59 bcopy(data, p, len); 60 return p; 61 } 62 63 int 64 pdu_addbuf(struct pdu *p, void *buf, size_t len, unsigned int elm) 65 { 66 if (len & 0x3) { 67 bzero((char *)buf + len, 4 - (len & 0x3)); 68 len += 4 - (len & 0x3); 69 } 70 71 if (elm < PDU_MAXIOV) 72 if (!p->iov[elm].iov_base) { 73 p->iov[elm].iov_base = buf; 74 p->iov[elm].iov_len = len; 75 return 0; 76 } 77 78 /* no space left */ 79 return -1; 80 } 81 82 void * 83 pdu_getbuf(struct pdu *p, size_t *len, unsigned int elm) 84 { 85 if (len) 86 *len = 0; 87 if (elm < PDU_MAXIOV) 88 if (p->iov[elm].iov_base) { 89 if (len) 90 *len = p->iov[elm].iov_len; 91 return p->iov[elm].iov_base; 92 } 93 94 return NULL; 95 } 96 97 void 98 pdu_free(struct pdu *p) 99 { 100 unsigned int j; 101 102 for (j = 0; j < PDU_MAXIOV; j++) 103 free(p->iov[j].iov_base); 104 free(p); 105 } 106 107 int 108 socket_setblockmode(int fd, int nonblocking) 109 { 110 int flags; 111 112 if ((flags = fcntl(fd, F_GETFL, 0)) == -1) 113 return -1; 114 115 if (nonblocking) 116 flags |= O_NONBLOCK; 117 else 118 flags &= ~O_NONBLOCK; 119 120 if ((flags = fcntl(fd, F_SETFL, flags)) == -1) 121 return -1; 122 return 0; 123 } 124 125 const char * 126 log_sockaddr(void *arg) 127 { 128 struct sockaddr *sa = arg; 129 char port[6]; 130 char host[NI_MAXHOST]; 131 static char buf[NI_MAXHOST + 8]; 132 133 if (getnameinfo(sa, sa->sa_len, host, sizeof(host), port, sizeof(port), 134 NI_NUMERICHOST)) 135 return "unknown"; 136 if (port[0] == '0') 137 strlcpy(buf, host, sizeof(buf)); 138 else if (sa->sa_family == AF_INET) 139 snprintf(buf, sizeof(buf), "%s:%s", host, port); 140 else 141 snprintf(buf, sizeof(buf), "[%s]:%s", host, port); 142 return buf; 143 } 144