[libss7-commits] mattf: branch mattf/bug13495 r240 - /team/mattf/bug13495/isup_masq.c
SVN commits to the libss7 project
libss7-commits at lists.digium.com
Thu Dec 11 11:59:26 CST 2008
Author: mattf
Date: Thu Dec 11 11:59:26 2008
New Revision: 240
URL: http://svn.digium.com/view/libss7?view=rev&rev=240
Log:
Forgot to add the new isup_masq.c file
Added:
team/mattf/bug13495/isup_masq.c
Added: team/mattf/bug13495/isup_masq.c
URL: http://svn.digium.com/view/libss7/team/mattf/bug13495/isup_masq.c?view=auto&rev=240
==============================================================================
--- team/mattf/bug13495/isup_masq.c (added)
+++ team/mattf/bug13495/isup_masq.c Thu Dec 11 11:59:26 2008
@@ -1,0 +1,252 @@
+/*
+libss7: An implementation of Signalling System 7
+
+Written by Matthew Fredrickson <creslin at digium.com>
+
+Copyright Digium, Inc. (C) 2006
+All Rights Reserved.
+
+This program is free software; you can redistribute it under the
+terms of the GNU General Public License as published by the Free
+Software Foundation
+
+Contains definitions and data structurs for the ISUP portion of SS7
+*/
+
+
+#include "libss7.h"
+//#include "isuptcp.h"
+#include "ss7_internal.h"
+#include "isup.h"
+#include "mtp3.h"
+#include "mtp2.h"
+
+#include <stdlib.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+
+static void isup_set_event(struct ss7 *ss7, int event)
+{
+ /* A little worker function to put events into the event q */
+
+ ss7_event *e = ss7_next_empty_event(ss7);
+ e->e = event;
+
+ return;
+}
+
+static int isup_ip_receive_buffer(struct mtp2 *mtp2, unsigned char *msg, int len)
+{
+ unsigned char *buf = (unsigned char *)msg;
+ int msgstate = (int) buf[0];
+ unsigned char *newmsg;
+
+ /*Finds second byte of msg and determines how to handle message. Used to let client know
+ if the ss7 link is down on server. SS7 socket server will send the
+ correct state byte for each message. It does not need to keep sending the UP or DOWN states. Only
+ needs to send them when it's own ss7 link is in alarm. So during normal UP state all messages will
+ be of CASE 5 */
+
+ switch (msgstate) {
+ case SS7_EVENT_UP:
+ isup_set_event(mtp2->master, SS7_EVENT_UP);
+ return 1;
+ case SS7_EVENT_DOWN:
+ isup_set_event(mtp2->master, SS7_EVENT_DOWN);
+ return 1;
+ case 3:
+ case 4:
+ return 0;
+ case 5: /*This is the case for all ISUP messages such as IAM's, RLC,ANMs,ACMs..etc */
+ newmsg = &buf[1]; /*Get the buf minus the event byte */
+ if (mtp2->master->debug > 0) { /* Send data to be decode for debug */
+ mtp3_dump(mtp2->master,NULL, (void *)newmsg, len-1);
+ }
+ mtp3_receive(mtp2->master, NULL, (void *)newmsg, len-1);
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int get_msg_length(struct mtp2 *mtp2)
+{
+ char lenbuf[10] = {0,};
+ int i = 0;
+
+ do {
+ if (read(mtp2->fd, &lenbuf[i++], 1) < 0) {
+ ss7_message(mtp2->master, "Read returned -1in get_msg_length\n");
+ return -1;
+ }
+ } while ((i < 10) && lenbuf[i - 1] != 0);
+
+ if (i == 10) {
+ ss7_message(mtp2->master, "Reached read limit length, huh?");
+ return -1;
+ }
+
+ sscanf(lenbuf, "%d", &i);
+
+ return i;
+}
+
+int isup_ip_receive(struct mtp2 *mtp2)
+{
+ unsigned char msg[1024];
+ int len;
+ int res = -1;
+
+ len = get_msg_length(mtp2);
+
+ if (len < 0)
+ return -1;
+
+ res = read(mtp2->fd, msg, len);
+
+ if (res < 0) {
+ ss7_message(mtp2->master, "Read problem from socket: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (res != len) {
+ ss7_message(mtp2->master, "Short read from socket\n");
+ return -1;
+ }
+
+ res = isup_ip_receive_buffer(mtp2, msg, len);
+
+ return res;
+}
+
+static unsigned char * itoa(int val, int base)
+{
+ static unsigned char buf[32] = {0};
+ int i = 30;
+
+ for(; val && i ; --i, val /= base)
+ buf[i] = "0123456789abcdef"[val % base];
+
+ return &buf[i+1];
+}
+
+static int isup_carefulwrite(int fd, unsigned char *s, int len, int timeoutms)
+{
+ /*This was copied from AST_CAREFULWRITE
+ Try to write string, but wait no more than ms milliseconds
+ before timing out*/
+ int res = 0;
+ struct pollfd fds[1];
+ while (len) {
+ res = write(fd, s, len);
+ if ((res < 0) && (errno != EAGAIN)) {
+ return -1;
+ }
+ if (res < 0)
+ res = 0;
+ len -= res;
+ s += res;
+ res = 0;
+ if (len) {
+ fds[0].fd = fd;
+ fds[0].events = POLLOUT;
+ /*Wait until writable again */
+ res = poll(fds, 1, timeoutms);
+ if (res < 1)
+ return -1;
+ }
+ }
+ return res;
+}
+
+static int isup_ip_send(struct mtp2 *mtp2, unsigned char *data, int len)
+{
+ int i;
+
+ if (mtp2->master->debug > 0) { /* Send data to be decode for debug */
+ mtp3_dump(mtp2->master, mtp2, data, len);}
+
+ /* Send the length of entire ISUP message first */
+ i = isup_carefulwrite(mtp2->fd, itoa(len,10), 4, 50);
+
+ return isup_carefulwrite(mtp2->fd, data, len, 50);
+}
+
+int isup_ip_msu(struct mtp2 *mtp2, struct ss7_msg *msg)
+{
+ int res;
+
+ res = isup_ip_send(mtp2, msg->buf + MTP2_SIZE, msg->size - MTP2_SIZE);
+
+ ss7_msg_free(msg);
+
+ return res;
+}
+
+int isup_masquerade_add_route(struct ss7 *ss7, int fd, int startcic, int endcic, unsigned int opc)
+{
+ struct isup_masq *masq_table = &ss7->isup_masq_table;
+ int i, j;
+
+ if (!ss7)
+ return -1;
+
+ if (masq_table->numentries >= ISUP_MASQ_MAX_ENTRIES)
+ return -1;
+
+ i = masq_table->numentries;
+
+ masq_table->routes[i].startcic = startcic;
+ masq_table->routes[i].endcic = endcic;
+ masq_table->routes[i].opc = opc;
+
+ ss7_add_slave_link(ss7, SS7_TRANSPORT_TCP, fd, 0, 0);
+
+ for (j = 0; j < ss7->numslavelinks; j++) {
+ if (ss7->slavelinks[j]->fd == fd)
+ break;
+ }
+
+ masq_table->routes[i].mtp2 = ss7->slavelinks[j];
+
+ return 0;
+}
+
+static int isup_masquerade_transmit(struct mtp2 *link, struct routing_label *rl, unsigned char *buf, int len)
+{
+ /* Rebuild our message here */
+ unsigned char txbuf[512];
+ int rlsize;
+
+ txbuf[0] = 5; /* ISUP MESSAGE */
+ txbuf[1] = (link->master->ni << 6) | SIG_ISUP;
+ rlsize = set_routinglabel(&txbuf[1], rl);
+
+ memcpy(&txbuf[rlsize], buf, len);
+
+ isup_ip_send(link, txbuf, len);
+
+ return 0;
+}
+
+int isup_needs_masquerade(struct ss7 *ss7, struct routing_label *rl, unsigned int cic, unsigned char *buf, int len)
+{
+ struct isup_masq * isup_masq_table = &ss7->isup_masq_table;
+ int i;
+
+ for (i = 0; i < isup_masq_table->numentries; i++) {
+ if ((isup_masq_table->routes[i].opc == rl->opc)
+ && (cic >= isup_masq_table->routes[i].startcic)
+ && (cic <= isup_masq_table->routes[i].endcic)) {
+ isup_masquerade_transmit(isup_masq_table->routes[i].mtp2, rl, buf, len);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
More information about the libss7-commits
mailing list