]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/capture/cap_debug/socket.c
Уменьшена зависимостть между заголовочными файлами путем использования
[stg.git] / projects / stargazer / plugins / capture / cap_debug / socket.c
1 /* $Id: socket.c,v 1.1 2005/12/12 18:14:22 nobunaga Exp $ 
2
3 Copyright (C) 2002 Marc Kirchner <kirchner@stud.fh-heilbronn.de>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include "libpal.h"
21
22 /*
23 <++doc++>
24 @name int pkt_socket_open(struct pkt_socket *sck, int type)
25 @desc Opens a packet socket. This is necessary to be able to send any packages.
26 @param sck pointer to a pkt_socket structure
27 @param type The type of the socket. Possible values are PKT_RAW (to open a raw socket. IP, TCP/UDP and application header have to be forged before sending) , PKT_STREAM, PKT_DGRAM. STREAM and DGRAM are supported by this function, but other function do not care.
28 <--doc-->
29 */
30 int
31 pkt_socket_open(struct pkt_socket *sck, int type)
32 {
33         int proto;
34         int iphdrincl = 1;
35         int ret = 0;
36
37         if (!sck)
38                 return EPKTINVALPTR;
39         
40         /* get mem for sockaddr structure */
41         if ((sck->sckad = (struct sockaddr_in *) malloc (sizeof(struct sockaddr_in))) == NULL) {
42                 return -1;
43         }
44         sck->sckad_len = sizeof(struct sockaddr_in);
45         memset(sck->sckad, 0, sck->sckad_len);
46         
47         /* except for raw sockets, proto is set to 0 */
48         /* (Stevens, UNP 2nd ed., 1998) */
49         switch (type) {
50                 case PKT_RAW:
51                         proto = IPPROTO_RAW;
52                         break;
53                 default:
54                         proto = 0;
55                         break;
56         }
57         if ((sck->rawfd = socket(AF_INET, type, proto)) == -1) {
58                 return -1;
59         }
60         if (type == PKT_RAW) {
61                 if ((ret = setsockopt(sck->rawfd, IPPROTO_IP, IP_HDRINCL, (const void *) &iphdrincl, sizeof(iphdrincl))) < 0) {
62                         return -1;
63                 }
64         }
65         return 0;
66 }       
67
68         
69 /*
70 <++doc++>
71 @name int pkt_socket_close(struct pkt_socket *sck)
72 @desc Closes a packet socket and frees used memory.
73 @param sck pointer to a pkt_socket structure
74 <--doc-->
75 */
76 int
77 pkt_socket_close(struct pkt_socket *sck)
78 {
79         if (!sck)
80                 return EPKTINVALPTR;
81         close(sck->rawfd);
82         free(sck->sckad);
83         sck->sckad=NULL;
84         return 0;
85 }
86
87 /*
88 <++doc++>
89 @name int pkt_socket_prepare(struct pkt_socket *sck, char *daddr)
90 @desc this function is necessary to enable the kernel to determine the correct outgoing interface
91 @param sck pointer to a pkt_socket structure
92 @param daddr dotted-decimal destination IP address
93 <--doc-->
94 */
95 int
96 pkt_socket_prepare(struct pkt_socket *sck, char *daddr)
97 {
98         /* 
99         * this is necessary for the kernel to determine outgoing
100         * interface.
101         */
102         
103         int ret = 0;
104         
105         if (!sck || !daddr)
106                 return EPKTINVALPTR;
107                 
108         /* set up sockaddr struct */
109         memset(sck->sckad, 0, sck->sckad_len);
110         if ((ret = inet_pton(AF_INET, daddr, &(sck->sckad->sin_addr))) == 0) {
111                 return -1;
112         }
113         sck->sckad->sin_family = AF_INET;
114         
115         /*
116         * i dont think we need to set the dest port...
117         */
118         return 0;
119 }
120
121 /*
122 <++doc++>
123 @name int pkt_socket_setopt(struct pkt_socket *sck, int level, int optname, void *optval, socklen_t optlen)
124 @desc this is basically a wrapper function for setsockopt(2)
125 @param sck pointer to a pkt_socket structure
126 @param level level the socket option will apply to (should be SOL_SOCKET)
127 @param optname option name, see sys/socket.h for values
128 @param optval new option value (for boolean options: 0=false)
129 @param optlen option value size (this is a value-result parameter!)
130 <--doc-->
131 */
132 int
133 pkt_socket_setopt(struct pkt_socket *sck, int level, 
134                 int optname, void *optval, socklen_t optlen)
135 {
136         if (!sck)
137                 return EPKTINVALPTR;
138         return (setsockopt(sck->rawfd, level, optname, optval, optlen));
139 }
140
141
142 /*
143 <++doc++>
144 @name int pkt_send(struct packet *pkt, struct pkt_socket *sck)
145 @desc sends the packet pkt unsing the socket sck
146 @param pkt pointer to a packet structure
147 @param sck pointer to a pkt_socket structure
148 <--doc-->
149 */
150 int 
151 pkt_send(struct packet *pkt, struct pkt_socket *sck)
152 {
153         int ret = 0;
154         
155         if (!pkt || !sck)
156                 return EPKTINVALPTR;
157         
158         /* no sendto-flags support */
159         if ((ret = sendto(sck->rawfd, pkt->pkt, pkt->pkt_size, 0, (struct sockaddr *) sck->sckad, sck->sckad_len)) == -1) {
160                 return -1;
161         }
162         return 0;
163 }