PageRenderTime 42ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/CSipSimple/jni/pjsip/sources/pjlib/src/pj/sock_linux_kernel.c

https://bitbucket.org/bohlooli/csipsimple2
C | 755 lines | 452 code | 122 blank | 181 comment | 64 complexity | 0f38fb05c6c641643c401683031ad2e1 MD5 | raw file
  1. /* $Id: sock_linux_kernel.c 3553 2011-05-05 06:14:19Z nanang $ */
  2. /*
  3. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  4. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include <pj/sock.h>
  21. #include <pj/assert.h>
  22. #include <pj/string.h> /* pj_memcpy() */
  23. #include <pj/os.h> /* PJ_CHECK_STACK() */
  24. #include <pj/addr_resolv.h> /* pj_gethostbyname() */
  25. #include <pj/ctype.h>
  26. #include <pj/compat/sprintf.h>
  27. #include <pj/log.h>
  28. #include <pj/errno.h>
  29. /* Linux kernel specific. */
  30. #include <linux/socket.h>
  31. #include <linux/net.h>
  32. //#include <net/sock.h>
  33. #include <linux/security.h>
  34. #include <linux/syscalls.h> /* sys_xxx() */
  35. #include <asm/ioctls.h> /* FIONBIO */
  36. #include <linux/utsname.h> /* for pj_gethostname() */
  37. /*
  38. * Address families conversion.
  39. * The values here are indexed based on pj_addr_family-0xFF00.
  40. */
  41. const pj_uint16_t PJ_AF_UNIX = AF_UNIX;
  42. const pj_uint16_t PJ_AF_INET = AF_INET;
  43. const pj_uint16_t PJ_AF_INET6 = AF_INET6;
  44. #ifdef AF_PACKET
  45. const pj_uint16_t PJ_AF_PACKET = AF_PACKET;
  46. #else
  47. # error "AF_PACKET undeclared!"
  48. #endif
  49. #ifdef AF_IRDA
  50. const pj_uint16_t PJ_AF_IRDA = AF_IRDA;
  51. #else
  52. # error "AF_IRDA undeclared!"
  53. #endif
  54. /*
  55. * Socket types conversion.
  56. * The values here are indexed based on pj_sock_type-0xFF00
  57. */
  58. const pj_uint16_t PJ_SOCK_STREAM= SOCK_STREAM;
  59. const pj_uint16_t PJ_SOCK_DGRAM = SOCK_DGRAM;
  60. const pj_uint16_t PJ_SOCK_RAW = SOCK_RAW;
  61. const pj_uint16_t PJ_SOCK_RDM = SOCK_RDM;
  62. /*
  63. * Socket level values.
  64. */
  65. const pj_uint16_t PJ_SOL_SOCKET = SOL_SOCKET;
  66. #ifdef SOL_IP
  67. const pj_uint16_t PJ_SOL_IP = SOL_IP;
  68. #else
  69. # error "SOL_IP undeclared!"
  70. #endif /* SOL_IP */
  71. #if defined(SOL_TCP)
  72. const pj_uint16_t PJ_SOL_TCP = SOL_TCP;
  73. #else
  74. # error "SOL_TCP undeclared!"
  75. #endif /* SOL_TCP */
  76. #ifdef SOL_UDP
  77. const pj_uint16_t PJ_SOL_UDP = SOL_UDP;
  78. #else
  79. # error "SOL_UDP undeclared!"
  80. #endif
  81. #ifdef SOL_IPV6
  82. const pj_uint16_t PJ_SOL_IPV6 = SOL_IPV6;
  83. #else
  84. # error "SOL_IPV6 undeclared!"
  85. #endif
  86. /* optname values. */
  87. const pj_uint16_t PJ_SO_TYPE = SO_TYPE;
  88. const pj_uint16_t PJ_SO_RCVBUF = SO_RCVBUF;
  89. const pj_uint16_t PJ_SO_SNDBUF = SO_SNDBUF;
  90. /*
  91. * Convert 16-bit value from network byte order to host byte order.
  92. */
  93. PJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)
  94. {
  95. return ntohs(netshort);
  96. }
  97. /*
  98. * Convert 16-bit value from host byte order to network byte order.
  99. */
  100. PJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)
  101. {
  102. return htons(hostshort);
  103. }
  104. /*
  105. * Convert 32-bit value from network byte order to host byte order.
  106. */
  107. PJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)
  108. {
  109. return ntohl(netlong);
  110. }
  111. /*
  112. * Convert 32-bit value from host byte order to network byte order.
  113. */
  114. PJ_DEF(pj_uint32_t) pj_htonl(pj_uint32_t hostlong)
  115. {
  116. return htonl(hostlong);
  117. }
  118. /*
  119. * Convert an Internet host address given in network byte order
  120. * to string in standard numbers and dots notation.
  121. */
  122. PJ_DEF(char*) pj_inet_ntoa(pj_in_addr in)
  123. {
  124. #define UC(b) (((int)b)&0xff)
  125. static char b[18];
  126. char *p;
  127. p = (char *)&in;
  128. pj_snprintf(b, sizeof(b), "%d.%d.%d.%d",
  129. UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
  130. return b;
  131. }
  132. /*
  133. * This function converts the Internet host address ccp from the standard
  134. * numbers-and-dots notation into binary data and stores it in the structure
  135. * that inp points to.
  136. */
  137. PJ_DEF(int) pj_inet_aton(const pj_str_t *ccp, struct pj_in_addr *addr)
  138. {
  139. pj_uint32_t val;
  140. int base, n;
  141. char c;
  142. unsigned parts[4];
  143. unsigned *pp = parts;
  144. char cp_copy[18];
  145. char *cp = cp_copy;
  146. addr->s_addr = PJ_INADDR_NONE;
  147. if (ccp->slen > 15) return 0;
  148. pj_memcpy(cp, ccp->ptr, ccp->slen);
  149. cp[ccp->slen] = '\0';
  150. c = *cp;
  151. for (;;) {
  152. /*
  153. * Collect number up to ``.''.
  154. * Values are specified as for C:
  155. * 0x=hex, 0=octal, isdigit=decimal.
  156. */
  157. if (!pj_isdigit((int)c))
  158. return (0);
  159. val = 0; base = 10;
  160. if (c == '0') {
  161. c = *++cp;
  162. if (c == 'x' || c == 'X')
  163. base = 16, c = *++cp;
  164. else
  165. base = 8;
  166. }
  167. for (;;) {
  168. if (pj_isascii((int)c) && pj_isdigit((int)c)) {
  169. val = (val * base) + (c - '0');
  170. c = *++cp;
  171. } else if (base==16 && pj_isascii((int)c) && pj_isxdigit((int)c)) {
  172. val = (val << 4) |
  173. (c + 10 - (pj_islower((int)c) ? 'a' : 'A'));
  174. c = *++cp;
  175. } else
  176. break;
  177. }
  178. if (c == '.') {
  179. /*
  180. * Internet format:
  181. * a.b.c.d
  182. * a.b.c (with c treated as 16 bits)
  183. * a.b (with b treated as 24 bits)
  184. */
  185. if (pp >= parts + 3)
  186. return (0);
  187. *pp++ = val;
  188. c = *++cp;
  189. } else
  190. break;
  191. }
  192. /*
  193. * Check for trailing characters.
  194. */
  195. if (c != '\0' && (!pj_isascii((int)c) || !pj_isspace((int)c)))
  196. return (0);
  197. /*
  198. * Concoct the address according to
  199. * the number of parts specified.
  200. */
  201. n = pp - parts + 1;
  202. switch (n) {
  203. case 0:
  204. return (0); /* initial nondigit */
  205. case 1: /* a -- 32 bits */
  206. break;
  207. case 2: /* a.b -- 8.24 bits */
  208. if (val > 0xffffff)
  209. return (0);
  210. val |= parts[0] << 24;
  211. break;
  212. case 3: /* a.b.c -- 8.8.16 bits */
  213. if (val > 0xffff)
  214. return (0);
  215. val |= (parts[0] << 24) | (parts[1] << 16);
  216. break;
  217. case 4: /* a.b.c.d -- 8.8.8.8 bits */
  218. if (val > 0xff)
  219. return (0);
  220. val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
  221. break;
  222. }
  223. if (addr)
  224. addr->s_addr = pj_htonl(val);
  225. return (1);
  226. }
  227. /*
  228. * Convert address string with numbers and dots to binary IP address.
  229. */
  230. PJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp)
  231. {
  232. pj_in_addr addr;
  233. pj_inet_aton(cp, &addr);
  234. return addr;
  235. }
  236. /*
  237. * Set the IP address of an IP socket address from string address,
  238. * with resolving the host if necessary. The string address may be in a
  239. * standard numbers and dots notation or may be a hostname. If hostname
  240. * is specified, then the function will resolve the host into the IP
  241. * address.
  242. */
  243. PJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,
  244. const pj_str_t *str_addr)
  245. {
  246. PJ_CHECK_STACK();
  247. pj_assert(str_addr && str_addr->slen < PJ_MAX_HOSTNAME);
  248. addr->sin_family = AF_INET;
  249. if (str_addr && str_addr->slen) {
  250. addr->sin_addr = pj_inet_addr(str_addr);
  251. if (addr->sin_addr.s_addr == PJ_INADDR_NONE) {
  252. pj_hostent he;
  253. if (pj_gethostbyname(str_addr, &he) == 0) {
  254. addr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;
  255. } else {
  256. addr->sin_addr.s_addr = PJ_INADDR_NONE;
  257. return -1;
  258. }
  259. }
  260. } else {
  261. addr->sin_addr.s_addr = 0;
  262. }
  263. return PJ_SUCCESS;
  264. }
  265. /*
  266. * Set the IP address and port of an IP socket address.
  267. * The string address may be in a standard numbers and dots notation or
  268. * may be a hostname. If hostname is specified, then the function will
  269. * resolve the host into the IP address.
  270. */
  271. PJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,
  272. const pj_str_t *str_addr,
  273. pj_uint16_t port)
  274. {
  275. pj_assert(addr && str_addr);
  276. addr->sin_family = PJ_AF_INET;
  277. pj_sockaddr_in_set_port(addr, port);
  278. return pj_sockaddr_in_set_str_addr(addr, str_addr);
  279. }
  280. /*
  281. * Get hostname.
  282. */
  283. PJ_DEF(const pj_str_t*) pj_gethostname(void)
  284. {
  285. static char buf[PJ_MAX_HOSTNAME];
  286. static pj_str_t hostname;
  287. PJ_CHECK_STACK();
  288. if (hostname.ptr == NULL) {
  289. hostname.ptr = buf;
  290. down_read(&uts_sem);
  291. hostname.slen = strlen(system_utsname.nodename);
  292. if (hostname.slen > PJ_MAX_HOSTNAME) {
  293. hostname.ptr[0] = '\0';
  294. hostname.slen = 0;
  295. } else {
  296. pj_memcpy(hostname.ptr, system_utsname.nodename, hostname.slen);
  297. }
  298. up_read(&uts_sem);
  299. }
  300. return &hostname;
  301. }
  302. /*
  303. * Get first IP address associated with the hostname.
  304. */
  305. PJ_DEF(pj_in_addr) pj_gethostaddr(void)
  306. {
  307. pj_sockaddr_in addr;
  308. const pj_str_t *hostname = pj_gethostname();
  309. pj_sockaddr_in_set_str_addr(&addr, hostname);
  310. return addr.sin_addr;
  311. }
  312. /*
  313. * Create new socket/endpoint for communication and returns a descriptor.
  314. */
  315. PJ_DEF(pj_status_t) pj_sock_socket(int af, int type, int proto,
  316. pj_sock_t *sock_fd)
  317. {
  318. long result;
  319. PJ_CHECK_STACK();
  320. /* Sanity checks. */
  321. PJ_ASSERT_RETURN(PJ_INVALID_SOCKET == -1 && sock_fd != NULL, PJ_EINVAL);
  322. /* Initialize returned socket */
  323. *sock_fd = PJ_INVALID_SOCKET;
  324. /* Create socket. */
  325. result = sys_socket(af, type, proto);
  326. if (result < 0) {
  327. return PJ_RETURN_OS_ERROR((-result));
  328. }
  329. *sock_fd = result;
  330. return PJ_SUCCESS;
  331. }
  332. /*
  333. * Bind socket.
  334. */
  335. PJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sockfd,
  336. const pj_sockaddr_t *addr,
  337. int len)
  338. {
  339. long err;
  340. mm_segment_t oldfs;
  341. PJ_CHECK_STACK();
  342. PJ_ASSERT_RETURN(addr!=NULL && len >= sizeof(struct pj_sockaddr),
  343. PJ_EINVAL);
  344. oldfs = get_fs();
  345. set_fs(KERNEL_DS);
  346. err = sys_bind(sockfd, (struct sockaddr*)addr, len);
  347. set_fs(oldfs);
  348. if (err)
  349. return PJ_RETURN_OS_ERROR(-err);
  350. else
  351. return PJ_SUCCESS;
  352. }
  353. /*
  354. * Bind socket.
  355. */
  356. PJ_DEF(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd,
  357. pj_uint32_t addr32,
  358. pj_uint16_t port)
  359. {
  360. pj_sockaddr_in addr;
  361. PJ_CHECK_STACK();
  362. addr.sin_family = PJ_AF_INET;
  363. addr.sin_addr.s_addr = pj_htonl(addr32);
  364. addr.sin_port = pj_htons(port);
  365. return pj_sock_bind(sockfd, &addr, sizeof(pj_sockaddr_in));
  366. }
  367. /*
  368. * Close socket.
  369. */
  370. PJ_DEF(pj_status_t) pj_sock_close(pj_sock_t sockfd)
  371. {
  372. long err;
  373. err = sys_close(sockfd);
  374. if (err != 0)
  375. return PJ_RETURN_OS_ERROR(-err);
  376. else
  377. return PJ_SUCCESS;
  378. }
  379. /*
  380. * Get remote's name.
  381. */
  382. PJ_DEF(pj_status_t) pj_sock_getpeername( pj_sock_t sockfd,
  383. pj_sockaddr_t *addr,
  384. int *namelen)
  385. {
  386. mm_segment_t oldfs;
  387. long err;
  388. PJ_CHECK_STACK();
  389. oldfs = get_fs();
  390. set_fs(KERNEL_DS);
  391. err = sys_getpeername( sockfd, addr, namelen);
  392. set_fs(oldfs);
  393. if (err)
  394. return PJ_RETURN_OS_ERROR(-err);
  395. else
  396. return PJ_SUCCESS;
  397. }
  398. /*
  399. * Get socket name.
  400. */
  401. PJ_DEF(pj_status_t) pj_sock_getsockname( pj_sock_t sockfd,
  402. pj_sockaddr_t *addr,
  403. int *namelen)
  404. {
  405. mm_segment_t oldfs;
  406. int err;
  407. PJ_CHECK_STACK();
  408. oldfs = get_fs();
  409. set_fs(KERNEL_DS);
  410. err = sys_getsockname( sockfd, addr, namelen );
  411. set_fs(oldfs);
  412. if (err)
  413. return PJ_RETURN_OS_ERROR(-err);
  414. else
  415. return PJ_SUCCESS;
  416. }
  417. /*
  418. * Send data
  419. */
  420. PJ_DEF(pj_status_t) pj_sock_send( pj_sock_t sockfd,
  421. const void *buf,
  422. pj_ssize_t *len,
  423. unsigned flags)
  424. {
  425. return pj_sock_sendto(sockfd, buf, len, flags, NULL, 0);
  426. }
  427. /*
  428. * Send data.
  429. */
  430. PJ_DEF(pj_status_t) pj_sock_sendto( pj_sock_t sockfd,
  431. const void *buff,
  432. pj_ssize_t *len,
  433. unsigned flags,
  434. const pj_sockaddr_t *addr,
  435. int addr_len)
  436. {
  437. long err;
  438. mm_segment_t oldfs;
  439. PJ_CHECK_STACK();
  440. oldfs = get_fs();
  441. set_fs(KERNEL_DS);
  442. err = *len = sys_sendto( sockfd, (void*)buff, *len, flags,
  443. (void*)addr, addr_len );
  444. set_fs(oldfs);
  445. if (err >= 0) {
  446. return PJ_SUCCESS;
  447. }
  448. else {
  449. return PJ_RETURN_OS_ERROR(-err);
  450. }
  451. }
  452. /*
  453. * Receive data.
  454. */
  455. PJ_DEF(pj_status_t) pj_sock_recv( pj_sock_t sockfd,
  456. void *buf,
  457. pj_ssize_t *len,
  458. unsigned flags)
  459. {
  460. return pj_sock_recvfrom(sockfd, buf, len, flags, NULL, NULL);
  461. }
  462. /*
  463. * Receive data.
  464. */
  465. PJ_DEF(pj_status_t) pj_sock_recvfrom( pj_sock_t sockfd,
  466. void *buff,
  467. pj_ssize_t *size,
  468. unsigned flags,
  469. pj_sockaddr_t *from,
  470. int *fromlen)
  471. {
  472. mm_segment_t oldfs;
  473. long err;
  474. PJ_CHECK_STACK();
  475. oldfs = get_fs();
  476. set_fs(KERNEL_DS);
  477. err = *size = sys_recvfrom( sockfd, buff, *size, flags, from, fromlen);
  478. set_fs(oldfs);
  479. if (err >= 0) {
  480. return PJ_SUCCESS;
  481. }
  482. else {
  483. return PJ_RETURN_OS_ERROR(-err);
  484. }
  485. }
  486. /*
  487. * Get socket option.
  488. */
  489. PJ_DEF(pj_status_t) pj_sock_getsockopt( pj_sock_t sockfd,
  490. pj_uint16_t level,
  491. pj_uint16_t optname,
  492. void *optval,
  493. int *optlen)
  494. {
  495. mm_segment_t oldfs;
  496. long err;
  497. PJ_CHECK_STACK();
  498. oldfs = get_fs();
  499. set_fs(KERNEL_DS);
  500. err = sys_getsockopt( sockfd, level, optname, optval, optlen);
  501. set_fs(oldfs);
  502. if (err)
  503. return PJ_RETURN_OS_ERROR(-err);
  504. else
  505. return PJ_SUCCESS;
  506. }
  507. /*
  508. * Set socket option.
  509. */
  510. PJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sockfd,
  511. pj_uint16_t level,
  512. pj_uint16_t optname,
  513. const void *optval,
  514. int optlen)
  515. {
  516. long err;
  517. mm_segment_t oldfs;
  518. PJ_CHECK_STACK();
  519. oldfs = get_fs();
  520. set_fs(KERNEL_DS);
  521. err = sys_setsockopt( sockfd, level, optname, (void*)optval, optlen);
  522. set_fs(oldfs);
  523. if (err)
  524. return PJ_RETURN_OS_ERROR(-err);
  525. else
  526. return PJ_SUCCESS;
  527. }
  528. /*
  529. * Shutdown socket.
  530. */
  531. #if PJ_HAS_TCP
  532. PJ_DEF(pj_status_t) pj_sock_shutdown( pj_sock_t sockfd,
  533. int how)
  534. {
  535. long err;
  536. PJ_CHECK_STACK();
  537. err = sys_shutdown(sockfd, how);
  538. if (err)
  539. return PJ_RETURN_OS_ERROR(-err);
  540. else
  541. return PJ_SUCCESS;
  542. }
  543. /*
  544. * Start listening to incoming connections.
  545. */
  546. PJ_DEF(pj_status_t) pj_sock_listen( pj_sock_t sockfd,
  547. int backlog)
  548. {
  549. long err;
  550. PJ_CHECK_STACK();
  551. err = sys_listen( sockfd, backlog );
  552. if (err)
  553. return PJ_RETURN_OS_ERROR(-err);
  554. else
  555. return PJ_SUCCESS;
  556. }
  557. /*
  558. * Connect socket.
  559. */
  560. PJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sockfd,
  561. const pj_sockaddr_t *addr,
  562. int namelen)
  563. {
  564. long err;
  565. mm_segment_t oldfs;
  566. PJ_CHECK_STACK();
  567. oldfs = get_fs();
  568. set_fs(KERNEL_DS);
  569. err = sys_connect( sockfd, (void*)addr, namelen );
  570. set_fs(oldfs);
  571. if (err)
  572. return PJ_RETURN_OS_ERROR(-err);
  573. else
  574. return PJ_SUCCESS;
  575. }
  576. /*
  577. * Accept incoming connections
  578. */
  579. PJ_DEF(pj_status_t) pj_sock_accept( pj_sock_t sockfd,
  580. pj_sock_t *newsockfd,
  581. pj_sockaddr_t *addr,
  582. int *addrlen)
  583. {
  584. long err;
  585. PJ_CHECK_STACK();
  586. PJ_ASSERT_RETURN(newsockfd != NULL, PJ_EINVAL);
  587. err = sys_accept( sockfd, addr, addrlen);
  588. if (err < 0) {
  589. *newsockfd = PJ_INVALID_SOCKET;
  590. return PJ_RETURN_OS_ERROR(-err);
  591. }
  592. else {
  593. *newsockfd = err;
  594. return PJ_SUCCESS;
  595. }
  596. }
  597. #endif /* PJ_HAS_TCP */
  598. /*
  599. * Permission to steal inet_ntoa() and inet_aton() as long as this notice below
  600. * is included:
  601. */
  602. /*
  603. * Copyright (c) 1983, 1993
  604. * The Regents of the University of California. All rights reserved.
  605. *
  606. * Redistribution and use in source and binary forms, with or without
  607. * modification, are permitted provided that the following conditions
  608. * are met:
  609. * 1. Redistributions of source code must retain the above copyright
  610. * notice, this list of conditions and the following disclaimer.
  611. * 2. Redistributions in binary form must reproduce the above copyright
  612. * notice, this list of conditions and the following disclaimer in the
  613. * documentation and/or other materials provided with the distribution.
  614. * 3. All advertising materials mentioning features or use of this software
  615. * must display the following acknowledgement:
  616. * This product includes software developed by the University of
  617. * California, Berkeley and its contributors.
  618. * 4. Neither the name of the University nor the names of its contributors
  619. * may be used to endorse or promote products derived from this software
  620. * without specific prior written permission.
  621. *
  622. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  623. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  624. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  625. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  626. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  627. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  628. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  629. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  630. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  631. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  632. * SUCH DAMAGE.
  633. */