blob: 191eef18dd97a589ca9ecfea82035a1f32b9f01f [file] [log] [blame]
jjako52c24142002-12-16 13:33:51 +00001/*
2 * OpenGGSN - Gateway GPRS Support Node
3 * Copyright (C) 2002 Mondru AB.
4 *
5 * The contents of this file may be used under the terms of the GNU
6 * General Public License Version 2, provided that the above copyright
7 * notice and this permission notice is included in all copies or
8 * substantial portions of the software.
9 *
10 * The initial developer of the original code is
11 * Jens Jakobsen <jj@openggsn.org>
12 *
13 * Contributor(s):
14 *
15 */
16
17#ifndef _GTP_H
18#define _GTP_H
19
jjako2e840a32003-01-28 16:05:18 +000020#define GTP_DEBUG 1 /* Print debug information */
21
jjako52c24142002-12-16 13:33:51 +000022#define GTP0_PORT 3386
23#define GTP1C_PORT 2123
24#define GTP1U_PORT 2152
25#define PACKET_MAX 8196
26
27#define GTP_MAX 0xffff /* TODO: Choose right number */
28#define GTP0_HEADER_SIZE 20
29#define GTP1_HEADER_SIZE_SHORT 8
30#define GTP1_HEADER_SIZE_LONG 12
31
32#define SYSLOG_PRINTSIZE 255
33#define ERRMSG_SIZE 255
34
35#define RESTART_FILE "gsn_restart"
36#define NAMESIZE 1024
37
38/* GTP version 1 message type definitions. Also covers version 0 except *
39 * for anonymous PDP context which was superceded in version 1 */
40
41/* 0 For future use. */
42#define GTP_ECHO_REQ 1 /* Echo Request */
43#define GTP_ECHO_RSP 2 /* Echo Response */
44#define GTP_NOT_SUPPORTED 3 /* Version Not Supported */
45#define GTP_ALIVE_REQ 4 /* Node Alive Request */
46#define GTP_ALIVE_RSP 5 /* Node Alive Response */
47#define GTP_REDIR_REQ 6 /* Redirection Request */
48#define GTP_REDIR_RSP 7 /* Redirection Response */
49/* 8-15 For future use. */
50#define GTP_CREATE_PDP_REQ 16 /* Create PDP Context Request */
51#define GTP_CREATE_PDP_RSP 17 /* Create PDP Context Response */
52#define GTP_UPDATE_PDP_REQ 18 /* Update PDP Context Request */
53#define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */
54#define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */
55#define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */
56/* 22-25 For future use. */ /* In version GTP 1 anonomous PDP context */
57#define GTP_ERROR 26 /* Error Indication */
58#define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */
59#define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */
60#define GTP_PDU_NOT_REJ_REQ 29 /* PDU Notification Reject Request */
61#define GTP_PDU_NOT_REJ_RSP 30 /* PDU Notification Reject Response */
62#define GTP_SUPP_EXT_HEADER 31 /* Supported Extension Headers Notification */
63#define GTP_SND_ROUTE_REQ 32 /* Send Routeing Information for GPRS Request */
64#define GTP_SND_ROUTE_RSP 33 /* Send Routeing Information for GPRS Response */
65#define GTP_FAILURE_REQ 34 /* Failure Report Request */
66#define GTP_FAILURE_RSP 35 /* Failure Report Response */
67#define GTP_MS_PRESENT_REQ 36 /* Note MS GPRS Present Request */
68#define GTP_MS_PRESENT_RSP 37 /* Note MS GPRS Present Response */
69/* 38-47 For future use. */
70#define GTP_IDEN_REQ 48 /* Identification Request */
71#define GTP_IDEN_RSP 49 /* Identification Response */
72#define GTP_SGSN_CONTEXT_REQ 50 /* SGSN Context Request */
73#define GTP_SGSN_CONTEXT_RSP 51 /* SGSN Context Response */
74#define GTP_SGSN_CONTEXT_ACK 52 /* SGSN Context Acknowledge */
75#define GTP_FWD_RELOC_REQ 53 /* Forward Relocation Request */
76#define GTP_FWD_RELOC_RSP 54 /* Forward Relocation Response */
77#define GTP_FWD_RELOC_COMPL 55 /* Forward Relocation Complete */
78#define GTP_RELOC_CANCEL_REQ 56 /* Relocation Cancel Request */
79#define GTP_RELOC_CANCEL_RSP 57 /* Relocation Cancel Response */
80#define GTP_FWD_SRNS 58 /* Forward SRNS Context */
81#define GTP_FWD_RELOC_ACK 59 /* Forward Relocation Complete Acknowledge */
82#define GTP_FWD_SRNS_ACK 60 /* Forward SRNS Context Acknowledge */
83/* 61-239 For future use. */
84#define GTP_DATA_TRAN_REQ 240 /* Data Record Transfer Request */
85#define GTP_DATA_TRAN_RSP 241 /* Data Record Transfer Response */
86/* 242-254 For future use. */
87#define GTP_GPDU 255 /* G-PDU */
88
89/* GTP 0 header.
90 * Explanation to some of the fields:
91 * SNDCP NPDU Number flag = 0 except for inter SGSN handover situations
92 * SNDCP N-PDU LCC Number 0 = 0xff except for inter SGSN handover situations
93 * Sequence number. Used for reliable delivery of signalling messages, and
94 * to discard "illegal" data messages.
95 * Flow label. Is used to point a particular PDP context. Is used in data
96 * messages as well as signalling messages related to a particular context.
97 * Tunnel ID is IMSI+NSAPI. Unique identifier of PDP context. Is somewhat
98 * redundant because the header also includes flow. */
99
100struct gtp0_header { /* Descriptions from 3GPP 09.60 */
101 u_int8_t flags; /* 01 bitfield, with typical values */
102 /* 000..... Version: 1 (0) */
103 /* ...1111. Spare (7) */
104 /* .......0 SNDCP N-PDU Number flag (0) */
105 u_int8_t type; /* 02 Message type. T-PDU = 0xff */
106 u_int16_t length; /* 03 Length (of G-PDU excluding header) */
107 u_int16_t seq; /* 05 Sequence Number */
108 u_int16_t flow; /* 07 Flow Label ( = 0 for signalling) */
109 u_int8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */
110 u_int8_t spare1; /* 10 Spare */
111 u_int8_t spare2; /* 11 Spare */
112 u_int8_t spare3; /* 12 Spare */
113 u_int64_t tid; /* 13 Tunnel ID */
114}; /* 20 */
115
116struct gtp1_header_short { /* Descriptions from 3GPP 29060 */
117 u_int8_t flags; /* 01 bitfield, with typical values */
118 /* 000..... Version: 1 */
119 /* ...1.... Protocol Type: GTP=1, GTP'=0 */
120 /* ....1... Spare = 1 */
121 /* .....1.. Extension header flag: 1 */
122 /* ......1. Sequence number flag: 1 */
123 /* .......0 PN: N-PDU Number flag */
124 u_int8_t type; /* 02 Message type. T-PDU = 0xff */
125 u_int16_t length; /* 03 Length (of IP packet or signalling) */
126 u_int64_t tid; /* 05 - 08 Tunnel ID */
127};
128
129struct gtp1_header_long { /* Descriptions from 3GPP 29060 */
130 u_int8_t flags; /* 01 bitfield, with typical values */
131 /* 000..... Version: 1 */
132 /* ...1.... Protocol Type: GTP=1, GTP'=0 */
133 /* ....1... Spare = 1 */
134 /* .....1.. Extension header flag: 1 */
135 /* ......1. Sequence number flag: 1 */
136 /* .......0 PN: N-PDU Number flag */
137 u_int8_t type; /* 02 Message type. T-PDU = 0xff */
138 u_int16_t length; /* 03 Length (of IP packet or signalling) */
139 u_int64_t tid; /* 05 Tunnel ID */
140 u_int16_t seq; /* 10 Sequence Number */
141 u_int8_t npdu; /* 11 N-PDU Number */
142 u_int8_t next; /* 12 Next extension header type. Empty = 0 */
143};
144
145struct gtp0_packet {
146 struct gtp0_header h;
147 u_int8_t p[GTP_MAX];
148} __attribute__((packed));
149
150struct gtp1_packet_short {
151 struct gtp1_header_short h;
152 u_int8_t p[GTP_MAX];
153} __attribute__((packed));
154
155struct gtp1_packet_long {
156 struct gtp1_header_long h;
157 u_int8_t p[GTP_MAX];
158} __attribute__((packed));
159
160union gtp_packet {
161 u_int8_t flags;
162 struct gtp0_packet gtp0;
163 struct gtp1_packet_short gtp1s;
164 struct gtp1_packet_long gtp1l;
165} __attribute__((packed)) h;
166
167
168
169
170/* ***********************************************************
171 * Information storage for each gsn instance
172 *
173 * Normally each instance of the application corresponds to
174 * one instance of a gsn.
175 *
176 * In order to avoid global variables in the application, and
177 * also in order to allow several instances of a gsn in the same
178 * application this struct is provided in order to store all
179 * relevant information related to the gsn.
180 *
181 * Note that this does not include information storage for '
182 * each pdp context. This is stored in another struct.
183 *************************************************************/
184
185struct gsn_t {
186 /* Parameters related to the network interface */
187
188 int fd; /* File descriptor to network interface */
189 struct in_addr gsnc; /* IP address of this gsn for signalling */
190 struct in_addr gsnu; /* IP address of this gsn for user traffic */
191
192 /* Parameters related to signalling messages */
193 uint16_t seq_next; /* Next sequence number to use */
194 int seq_first; /* First packet in queue (oldest timeout) */
195 int seq_last; /* Last packet in queue (youngest timeout) */
196
197 unsigned char restart_counter; /* Increment on restart. Stored on disk */
198 char *statedir; /* Disk location for permanent storage */
199
200 struct queue_t *queue_req; /* Request queue */
201 struct queue_t *queue_resp; /* Response queue */
202
203 /* Call back functions */
204 int (*cb_delete_context) (struct pdp_t*);
205 int (*cb_create_context) (struct pdp_t*);
206 int (*cb_conf) (int type, int cause, struct pdp_t *pdp, void* aid);
207 int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len);
208
209 /* Counters */
210
211 uint64_t err_socket; /* Number of socket errors */
212 uint64_t err_readfrom; /* Number of readfrom errors */
213 uint64_t err_sendto; /* Number of sendto errors */
214 uint64_t err_memcpy; /* Number of memcpy */
215 uint64_t err_queuefull; /* Number of times queue was full */
216 uint64_t err_seq; /* Number of seq out of range */
217 uint64_t err_address; /* GSN address conversion failed */
218 uint64_t err_unknownpdp; /* GSN address conversion failed */
219 uint64_t err_unknowntid; /* Application supplied unknown imsi+nsapi */
220 uint64_t err_cause; /* Unexpected cause value received */
221 uint64_t err_outofpdp; /* Out of storage for PDP contexts */
222
223 uint64_t empty; /* Number of empty packets */
224 uint64_t unsup; /* Number of unsupported version 29.60 11.1.1 */
225 uint64_t tooshort; /* Number of too short headers 29.60 11.1.2 */
226 uint64_t unknown; /* Number of unknown messages 29.60 11.1.3 */
227 uint64_t unexpect; /* Number of unexpected messages 29.60 11.1.4 */
228 uint64_t dublicate; /* Number of dublicate or unsolicited replies */
229 uint64_t missing; /* Number of missing mandatory field messages */
230 uint64_t invalid; /* Number of invalid message format messages */
231};
232
233
234/* External API functions */
235
236extern const char* gtp_version();
237extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen);
238extern int gtp_free(struct gsn_t *gsn);
239
240extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
241 uint64_t imsi, uint8_t nsapi);
242extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
243
244extern int gtp_create_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
245 struct in_addr* inetaddr);
246extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
247 struct in_addr* inetaddr);
248extern int gtp_delete_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid);
249
250extern int gtp_gpdu(struct gsn_t *gsn, struct pdp_t *pdp,
251 void *pack, unsigned len);
252
253extern int gtp_fd(struct gsn_t *gsn);
254extern int gtp_decaps(struct gsn_t *gsn);
255extern int gtp_retrans(struct gsn_t *gsn);
256extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout);
257
258/*
259extern int gtp_set_cb_newpdp(struct gsn_t *gsn,
260 int (*cb) (struct pdp_t*));
261extern int gtp_set_cb_freepdp(struct gsn_t *gsn,
262 int (*cb) (struct pdp_t*));
263extern int gtp_set_cb_create_pdp_ind(struct gsn_t *gsn,
264 int (*cb) (struct pdp_t*));
265extern int gtp_set_cb_create_pdp_conf(struct gsn_t *gsn,
266 int (*cb) (struct pdp_t*, int));
267extern int gtp_set_cb_update_pdp_conf(struct gsn_t *gsn,
268 int (*cb) (struct pdp_t*, int, int));
269extern int gtp_set_cb_delete_pdp_ind(struct gsn_t *gsn,
270 int (*cb) (struct pdp_t*));
271extern int gtp_set_cb_delete_pdp_conf(struct gsn_t *gsn,
272 int (*cb) (struct pdp_t*, int));
273*/
274
275extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
276 int (*cb_delete_context) (struct pdp_t* pdp));
277extern int gtp_set_cb_create_context(struct gsn_t *gsn,
278 int (*cb_create_context) (struct pdp_t* pdp));
279extern int gtp_set_cb_conf(struct gsn_t *gsn,
280 int (*cb) (int type, int cause, struct pdp_t* pdp, void *aid));
281extern int gtp_set_cb_gpdu(struct gsn_t *gsn,
282 int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len));
283
284
285/* Internal functions (not part of the API */
286
287extern int gtp_echo_req(struct gsn_t *gsn, struct in_addr *inetaddrs);
288extern int gtp_echo_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
289 void *pack, unsigned len);
290extern int gtp_echo_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
291 void *pack, unsigned len);
292extern int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
293 void *pack, unsigned len);
294
295extern int gtp_unsup_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
296 void *pack, unsigned len);
297extern int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
298 void *pack, unsigned len);
299
300extern int gtp_create_pdp_req(struct gsn_t *gsn, int version, void *aid,
301 struct in_addr* inetaddr, struct pdp_t *pdp);
302
303extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
304 struct sockaddr_in *peer,
305 void *pack, unsigned len,
306 struct pdp_t *pdp, uint8_t cause);
307
308extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
309 struct sockaddr_in *peer,
310 void *pack, unsigned len);
311
312extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
313 struct sockaddr_in *peer,
314 void *pack, unsigned len);
315
316extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *aid,
317 struct in_addr* inetaddr, struct pdp_t *pdp);
318
319extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *aid,
320 struct pdp_t *pdp);
321
322extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
323 struct sockaddr_in *peer,
324 void *pack, unsigned len,
325 struct pdp_t *pdp, uint8_t cause);
326
327extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
328 struct sockaddr_in *peer,
329 void *pack, unsigned len);
330
331extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
332 struct sockaddr_in *peer,
333 void *pack, unsigned len);
334
335
336extern int ipv42eua(struct ul66_t *eua, struct in_addr *src);
337extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua);
338extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna);
339extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src);
340
341#endif /* !_GTP_H */