Annotation of ansh/src/utils.c, revision 1.1
1.1 ! misho 1: /*************************************************************************
! 2: * (C) 2011 AITNET - Sofia/Bulgaria - <office@aitnet.org>
! 3: * by Michael Pounov <misho@elwix.org>
! 4: *
! 5: * $Author: misho $
! 6: * $Id: global.h,v 1.2 2011/06/08 12:45:40 misho Exp $
! 7: *
! 8: *************************************************************************/
! 9: #include "global.h"
! 10:
! 11:
! 12: void
! 13: Get1stEth(char *psDev, int devlen)
! 14: {
! 15: struct ifaddrs *ifa;
! 16:
! 17: assert(psDev);
! 18: assert(devlen > 0);
! 19:
! 20: getifaddrs(&ifa);
! 21: strlcpy(psDev, ifa->ifa_name, devlen);
! 22: freeifaddrs(ifa);
! 23: }
! 24:
! 25: int
! 26: PrepareL2(const char *psDev, int *bpflen)
! 27: {
! 28: int h, n = 1;
! 29: register int i;
! 30: char szStr[STRSIZ];
! 31: struct ifreq ifr;
! 32:
! 33: FTRACE(3);
! 34: assert(psDev);
! 35:
! 36: for (i = 0; i < 10; i++) {
! 37: memset(szStr, 0, sizeof szStr);
! 38: snprintf(szStr, sizeof szStr, "/dev/bpf%d", i);
! 39: h = open(szStr, O_RDWR);
! 40: if (h > 2)
! 41: break;
! 42: }
! 43: if (h < 3) {
! 44: printf("Error:: open bpf %s #%d - %s\n", szStr, errno, strerror(errno));
! 45: return -1;
! 46: }
! 47:
! 48: strlcpy(ifr.ifr_name, psDev, sizeof ifr.ifr_name);
! 49: if (ioctl(h, BIOCSETIF, &ifr) == -1) {
! 50: printf("Error:: bind interface %s to bpf #%d - %s\n", psDev, errno, strerror(errno));
! 51: close(h);
! 52: return -1;
! 53: }
! 54: if (ioctl(h, BIOCIMMEDIATE, &n) == -1) {
! 55: printf("Error:: set interface %s to bpf #%d - %s\n", psDev, errno, strerror(errno));
! 56: close(h);
! 57: return -1;
! 58: }
! 59: if (ioctl(h, BIOCGBLEN, bpflen) == -1) {
! 60: printf("Error:: get interface %s buffer length #%d - %s\n", psDev, errno, strerror(errno));
! 61: close(h);
! 62: return -1;
! 63: }
! 64:
! 65: VERB(3) LOG("Openned device handle %d with bpf buflen %d", h, *bpflen);
! 66: return h;
! 67: }
! 68:
! 69: int
! 70: PrepareL3(const struct sockaddr *sa, int *bpflen)
! 71: {
! 72: int h, n = 1;
! 73:
! 74: FTRACE(3);
! 75: assert(sa);
! 76:
! 77: h = socket(sa->sa_family, SOCK_RAW, IPPROTO_ICMP);
! 78: if (h == -1) {
! 79: printf("Error:: Cant open raw socket #%d - %s\n", errno, strerror(errno));
! 80: return -1;
! 81: }
! 82: /*
! 83: if (setsockopt(h, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n) == -1) {
! 84: printf("Error:: Cant set raw socket #%d - %s\n", errno, strerror(errno));
! 85: close(h);
! 86: return -1;
! 87: }
! 88: */
! 89: if (bind(h, sa, sizeof(struct sockaddr)) == -1) {
! 90: printf("Error:: Cant bind to raw socket #%d - %s\n", errno, strerror(errno));
! 91: close(h);
! 92: return -1;
! 93: }
! 94:
! 95: n = fcntl(h, F_GETFL);
! 96: fcntl(h, F_SETFL, n | O_NONBLOCK);
! 97:
! 98: *bpflen = USHRT_MAX;
! 99: VERB(3) LOG("Openned socket handle %d", h);
! 100: return h;
! 101: }
! 102:
! 103: char
! 104: icmpRecv(int s, u_short * __restrict id, u_char * __restrict data,
! 105: int * __restrict datlen, struct sockaddr *sa, socklen_t *salen)
! 106: {
! 107: int ret = 0;
! 108: struct icmp *icmp;
! 109: struct ansh_hdr *hdr;
! 110: u_char buf[USHRT_MAX] = { 0 };
! 111: u_int crc;
! 112:
! 113: ret = recvfrom(s, buf, sizeof buf, 0, sa, salen);
! 114: if (ret == -1) {
! 115: ERR("Receive recvfrom() #%d - %s", errno, strerror(errno));
! 116: return ANSH_FLG_ERR;
! 117: } else
! 118: VERB(4) LOG("Get packet with len=%d", ret);
! 119:
! 120: /* check header len */
! 121: if (ret < (sizeof(struct ip) + sizeof(struct icmp) + sizeof(struct ansh_hdr))) {
! 122: VERB(1) LOG("Discard packet too short %d ...", ret);
! 123: return ANSH_FLG_ERR;
! 124: } else
! 125: icmp = (struct icmp*) (buf + sizeof(struct ip));
! 126:
! 127: /* check echo magic ansh code */
! 128: if (icmp->icmp_type != ICMP_ECHOREPLY || icmp->icmp_code != ANSH_CODE) {
! 129: VERB(3) LOG("Packet isnt for me %d ... icmp_code=%d", ret, icmp->icmp_code);
! 130: return ANSH_FLG_ERR;
! 131: } else
! 132: hdr = (struct ansh_hdr*) (buf + sizeof(struct ip) + sizeof(struct icmp));
! 133:
! 134: /* check version and total size of packet */
! 135: if (hdr->ansh_ver != ANSH_VERSION) {
! 136: VERB(3) LOG("Packet with wrong version ...");
! 137: return ANSH_FLG_ERR;
! 138: }
! 139:
! 140: /* check crc of packet */
! 141: crc = hdr->ansh_crc;
! 142: hdr->ansh_crc ^= hdr->ansh_crc;
! 143: hdr->ansh_crc = htonl(crcAdler((u_char*) hdr, ntohs(hdr->ansh_len)));
! 144: if (crc != hdr->ansh_crc) {
! 145: VERB(3) LOG("Packet with wrong crc ...");
! 146: return ANSH_FLG_ERR;
! 147: }
! 148:
! 149: /* copy data */
! 150: if (data && datlen) {
! 151: memset(data, 0, *datlen);
! 152: *datlen = ntohs(hdr->ansh_len) - sizeof(struct ansh_hdr);
! 153: memcpy(data, buf + sizeof(struct ip) + sizeof(struct icmp) + sizeof(struct ansh_hdr), *datlen);
! 154: }
! 155:
! 156: if (id)
! 157: *id = ntohs(icmp->icmp_id);
! 158: return hdr->ansh_flg;
! 159: }
! 160:
! 161: int
! 162: icmpSend(int s, u_short id, char flg, u_char *data, int datlen, struct sockaddr *sa, socklen_t salen)
! 163: {
! 164: u_char *pos, buf[USHRT_MAX] = { 0 };
! 165: struct icmp *icmp;
! 166: struct ansh_hdr *hdr;
! 167: int ret = 0;
! 168:
! 169: assert(data);
! 170: if ((sizeof buf - sizeof(struct icmp) + sizeof(struct ansh_hdr)) < datlen)
! 171: return ANSH_FLG_ERR;
! 172:
! 173: icmp = (struct icmp*) buf;
! 174: hdr = (struct ansh_hdr*) (buf + sizeof(struct icmp));
! 175: pos = buf + sizeof(struct icmp) + sizeof(struct ansh_hdr);
! 176:
! 177: memcpy(pos, data, datlen);
! 178:
! 179: hdr->ansh_ver = ANSH_VERSION;
! 180: hdr->ansh_flg = flg;
! 181: hdr->ansh_len = htons(datlen + sizeof(struct ansh_hdr));
! 182: hdr->ansh_crc = 0;
! 183: hdr->ansh_crc = htonl(crcAdler((u_char*) hdr, ntohs(hdr->ansh_len)));
! 184:
! 185: icmp->icmp_type = ICMP_ECHOREPLY;
! 186: icmp->icmp_code = ANSH_CODE;
! 187: icmp->icmp_id = htons(id);
! 188: icmp->icmp_seq = htons(datlen);
! 189: icmp->icmp_cksum = 0;
! 190: icmp->icmp_cksum = crcIP(buf, sizeof(struct icmp) + sizeof(struct ansh_hdr) + datlen);
! 191:
! 192: if ((ret = sendto(s, buf, sizeof(struct icmp) + sizeof(struct ansh_hdr) + datlen,
! 193: 0, sa, salen)) == -1) {
! 194: ERR("Send sendto() #%d - %s", errno, strerror(errno));
! 195: return ANSH_FLG_ERR;
! 196: } else
! 197: VERB(4) LOG("Put packet with len=%d", ret);
! 198: if (ret != sizeof(struct icmp) + sizeof(struct ansh_hdr) + datlen) {
! 199: VERB(3) LOG("Sended data %d is different from source data len %d", ret,
! 200: sizeof(struct icmp) + sizeof(struct ansh_hdr) + datlen);
! 201: return ANSH_FLG_ERR;
! 202: }
! 203:
! 204: return ret;
! 205: }
! 206:
! 207: int
! 208: pktSend(int s, u_short id, char flg, u_char *data, int datlen, struct ether_addr *ea)
! 209: {
! 210: u_char *pos, buf[USHRT_MAX] = { 0 };
! 211: struct ether_header *e = (struct ether_header*) buf;
! 212: struct ansh_hdr *hdr;
! 213: int ret = 0;
! 214:
! 215: assert(data);
! 216: if ((sizeof buf - ETHER_HDR_LEN + sizeof(struct ansh_hdr)) < datlen)
! 217: return ANSH_FLG_ERR;
! 218:
! 219: e->ether_type = htons(id);
! 220: memcpy(e->ether_dhost, ea->octet, ETHER_ADDR_LEN);
! 221: hdr = (struct ansh_hdr*) (buf + ETHER_HDR_LEN);
! 222: pos = ((u_char*) hdr) + sizeof(struct ansh_hdr);
! 223:
! 224: memcpy(pos, data, datlen);
! 225:
! 226: hdr->ansh_ver = ANSH_VERSION;
! 227: hdr->ansh_flg = flg;
! 228: hdr->ansh_len = htons(datlen + sizeof(struct ansh_hdr));
! 229: hdr->ansh_crc = 0;
! 230: hdr->ansh_crc = htonl(crcAdler((u_char*) hdr, ntohs(hdr->ansh_len)));
! 231:
! 232: if ((ret = write(s, buf, ETHER_HDR_LEN + sizeof(struct ansh_hdr) + datlen)) == -1) {
! 233: ERR("Send packet() #%d - %s", errno, strerror(errno));
! 234: return ANSH_FLG_ERR;
! 235: } else
! 236: VERB(4) LOG("Put packet with len=%d", ret);
! 237: if (ret != ETHER_HDR_LEN + sizeof(struct ansh_hdr) + datlen) {
! 238: VERB(3) LOG("Sended data %d is different from source data len %d", ret,
! 239: ETHER_HDR_LEN + sizeof(struct ansh_hdr) + datlen);
! 240: return ANSH_FLG_ERR;
! 241: }
! 242:
! 243: return ret;
! 244: }
! 245:
! 246: char
! 247: pktRecv(int s, u_char * __restrict data, int * __restrict datlen, struct ether_header *eth)
! 248: {
! 249: int ret = 0;
! 250: struct bpf_hdr *bpf;
! 251: struct ether_header *e;
! 252: struct ansh_hdr *hdr;
! 253: u_char *buf;
! 254: u_int crc;
! 255:
! 256: if (!eth || !datlen)
! 257: return ANSH_FLG_ERR;
! 258:
! 259: if (!(buf = malloc(*datlen))) {
! 260: ERR("malloc() #%d - %s", errno, strerror(errno));
! 261: return ANSH_FLG_ERR;
! 262: }
! 263:
! 264: ret = read(s, buf, *datlen);
! 265: if (ret == -1) {
! 266: ERR("Receive packet() #%d - %s", errno, strerror(errno));
! 267: free(buf);
! 268: return ANSH_FLG_ERR;
! 269: } else
! 270: VERB(4) LOG("Get packet with len=%d", ret);
! 271:
! 272: /* check header len */
! 273: if (ret < (sizeof(struct bpf_hdr) + ETHER_HDR_LEN + sizeof(struct ansh_hdr))) {
! 274: VERB(1) LOG("Discard packet too short %d ...", ret);
! 275: free(buf);
! 276: return ANSH_FLG_ERR;
! 277: } else {
! 278: bpf = (struct bpf_hdr*) buf;
! 279: e = (struct ether_header*) (buf + bpf->bh_hdrlen);
! 280: memcpy(eth, e, ETHER_HDR_LEN);
! 281: hdr = (struct ansh_hdr*) (buf + bpf->bh_hdrlen + ETHER_HDR_LEN);
! 282: }
! 283:
! 284: /* check version and total size of packet */
! 285: if (hdr->ansh_ver != ANSH_VERSION) {
! 286: VERB(3) LOG("Packet with wrong version ... %d", hdr->ansh_ver);
! 287: free(buf);
! 288: return ANSH_FLG_ERR;
! 289: }
! 290: /* check crc of packet */
! 291: crc = hdr->ansh_crc;
! 292: hdr->ansh_crc ^= hdr->ansh_crc;
! 293: hdr->ansh_crc = htonl(crcAdler((u_char*) hdr, ntohs(hdr->ansh_len)));
! 294: if (crc != hdr->ansh_crc) {
! 295: VERB(3) LOG("Packet with wrong crc ...");
! 296: free(buf);
! 297: return ANSH_FLG_ERR;
! 298: }
! 299:
! 300: /* copy data */
! 301: if (data) {
! 302: memset(data, 0, *datlen);
! 303: *datlen = ntohs(hdr->ansh_len) - sizeof(struct ansh_hdr);
! 304: memcpy(data, hdr + sizeof(struct ansh_hdr), *datlen);
! 305: }
! 306:
! 307: ret = (char) hdr->ansh_flg;
! 308: free(buf);
! 309: return (char) ret;
! 310: }
! 311:
! 312: void *
! 313: TOfunc(sched_task_t *task)
! 314: {
! 315: struct tagProc *proc;
! 316:
! 317: FTRACE(3);
! 318:
! 319: /* not found argument, drop data */
! 320: if (!(proc = TASK_ARG(task)))
! 321: return (void*) -1;
! 322:
! 323: if (proc->proc_pid)
! 324: kill(proc->proc_pid, SIGTERM);
! 325:
! 326: return NULL;
! 327: }
! 328:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>